|
|
@ -37,54 +37,84 @@ Lemma ent_weakening P Q R :
|
|
|
|
(P ⊢ R) →
|
|
|
|
(P ⊢ R) →
|
|
|
|
P ∧ Q ⊢ R.
|
|
|
|
P ∧ Q ⊢ R.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
intro P_ent_R.
|
|
|
|
Admitted.
|
|
|
|
eapply ent_trans; [ eapply ent_and_elim_l | assumption ].
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma ent_true P :
|
|
|
|
Lemma ent_true P :
|
|
|
|
P ⊢ True.
|
|
|
|
P ⊢ True.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
eapply ent_trans.
|
|
|
|
Admitted.
|
|
|
|
- apply (ent_prove_pure P True).
|
|
|
|
|
|
|
|
tauto.
|
|
|
|
|
|
|
|
- exact (ent_refl True).
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma ent_false P :
|
|
|
|
Lemma ent_false P :
|
|
|
|
False ⊢ P.
|
|
|
|
False ⊢ P.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
apply (ent_assume_pure _ _ _ (ent_refl False)).
|
|
|
|
Admitted.
|
|
|
|
tauto.
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma ent_and_comm P Q :
|
|
|
|
Lemma ent_and_comm P Q :
|
|
|
|
P ∧ Q ⊢ Q ∧ P.
|
|
|
|
P ∧ Q ⊢ Q ∧ P.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
apply ent_and_intro; [ apply ent_and_elim_r | apply ent_and_elim_l ].
|
|
|
|
Admitted.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition ent_or_intro_l := ent_or_introl.
|
|
|
|
|
|
|
|
Definition ent_or_intro_r := ent_or_intror.
|
|
|
|
|
|
|
|
|
|
|
|
Lemma ent_or_comm P Q :
|
|
|
|
Lemma ent_or_comm P Q :
|
|
|
|
P ∨ Q ⊢ Q ∨ P.
|
|
|
|
P ∨ Q ⊢ Q ∨ P.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
apply ent_or_elim; [ apply ent_or_intro_r | apply ent_or_intro_l ].
|
|
|
|
Admitted.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma ent_all_comm {X} (Φ : X → X → iProp) :
|
|
|
|
Lemma ent_all_comm {X} (Φ : X → X → iProp) :
|
|
|
|
(∀ x y, Φ x y) ⊢ (∀ y x, Φ x y).
|
|
|
|
(∀ x y, Φ x y) ⊢ (∀ y x, Φ x y).
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
apply ent_all_intro.
|
|
|
|
Admitted.
|
|
|
|
intro x.
|
|
|
|
|
|
|
|
apply ent_all_intro.
|
|
|
|
|
|
|
|
intro y.
|
|
|
|
|
|
|
|
eapply ent_trans.
|
|
|
|
|
|
|
|
- eapply ent_all_elim.
|
|
|
|
|
|
|
|
- eapply ent_all_elim.
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma ent_exist_comm {X} (Φ : X → X → iProp) :
|
|
|
|
Lemma ent_exist_comm {X} (Φ : X → X → iProp) :
|
|
|
|
(∃ x y, Φ x y) ⊢ (∃ y x, Φ x y).
|
|
|
|
(∃ x y, Φ x y) ⊢ (∃ y x, Φ x y).
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
apply ent_exist_elim.
|
|
|
|
Admitted.
|
|
|
|
intro x.
|
|
|
|
|
|
|
|
apply ent_exist_elim.
|
|
|
|
|
|
|
|
intro y.
|
|
|
|
|
|
|
|
eapply ent_exist_intro.
|
|
|
|
|
|
|
|
eapply ent_exist_intro.
|
|
|
|
|
|
|
|
exact (ent_refl _).
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma ent_pure_pure {φ ψ : Prop} :
|
|
|
|
|
|
|
|
(φ → ψ) →
|
|
|
|
|
|
|
|
bi_entails (PROP := iProp) ⌜φ⌝ ⌜ψ⌝.
|
|
|
|
|
|
|
|
Proof.
|
|
|
|
|
|
|
|
intro H.
|
|
|
|
|
|
|
|
apply (ent_assume_pure _ _ _ (ent_refl ⌜φ⌝)); intro Hφ.
|
|
|
|
|
|
|
|
eapply ent_prove_pure.
|
|
|
|
|
|
|
|
exact (H Hφ).
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
(** Derived Hoare rules *)
|
|
|
|
(** Derived Hoare rules *)
|
|
|
|
Lemma hoare_con_pre P Q Φ e:
|
|
|
|
Lemma hoare_con_pre {P Q Φ e}:
|
|
|
|
(P ⊢ Q) →
|
|
|
|
(P ⊢ Q) →
|
|
|
|
{{ Q }} e {{ Φ }} →
|
|
|
|
{{ Q }} e {{ Φ }} →
|
|
|
|
{{ P }} e {{ Φ }}.
|
|
|
|
{{ P }} e {{ Φ }}.
|
|
|
@ -92,7 +122,7 @@ Proof.
|
|
|
|
intros ??. eapply hoare_con; eauto.
|
|
|
|
intros ??. eapply hoare_con; eauto.
|
|
|
|
Qed.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_con_post P Φ Ψ e:
|
|
|
|
Lemma hoare_con_post {P Φ Ψ e}:
|
|
|
|
(∀ v, Ψ v ⊢ Φ v) →
|
|
|
|
(∀ v, Ψ v ⊢ Φ v) →
|
|
|
|
{{ P }} e {{ Ψ }} →
|
|
|
|
{{ P }} e {{ Ψ }} →
|
|
|
|
{{ P }} e {{ Φ }}.
|
|
|
|
{{ P }} e {{ Φ }}.
|
|
|
@ -100,7 +130,7 @@ Proof.
|
|
|
|
intros ??. eapply hoare_con; last done; eauto.
|
|
|
|
intros ??. eapply hoare_con; last done; eauto.
|
|
|
|
Qed.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_value_con P Φ v :
|
|
|
|
Lemma hoare_value_con {P Φ v} :
|
|
|
|
(P ⊢ Φ v) →
|
|
|
|
(P ⊢ Φ v) →
|
|
|
|
{{ P }} v {{ Φ }}.
|
|
|
|
{{ P }} v {{ Φ }}.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
@ -122,8 +152,9 @@ Lemma hoare_rec P Φ f x e v:
|
|
|
|
({{ P }} subst' x v (subst' f (rec: f x := e) e) {{Φ}}) →
|
|
|
|
({{ P }} subst' x v (subst' f (rec: f x := e) e) {{Φ}}) →
|
|
|
|
{{ P }} (rec: f x := e)%V v {{Φ}}.
|
|
|
|
{{ P }} (rec: f x := e)%V v {{Φ}}.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
intro H_subst.
|
|
|
|
Admitted.
|
|
|
|
eapply hoare_pure_step; [ apply pure_step_beta | assumption ].
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_let P Φ x e v:
|
|
|
|
Lemma hoare_let P Φ x e v:
|
|
|
@ -138,58 +169,95 @@ Proof.
|
|
|
|
apply pure_step_beta.
|
|
|
|
apply pure_step_beta.
|
|
|
|
Qed.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_eq_num (n m: Z):
|
|
|
|
Lemma hoare_value_exact P v :
|
|
|
|
{{ ⌜n = m⌝ }} #n = #m {{ u, ⌜u = #true⌝ }}.
|
|
|
|
{{ P }} v {{ w, ⌜w = v⌝ }}.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
eapply hoare_pure; first reflexivity.
|
|
|
|
|
|
|
|
intros ->. eapply hoare_pure_step.
|
|
|
|
|
|
|
|
{ apply pure_step_eq. done. }
|
|
|
|
|
|
|
|
apply hoare_value_con.
|
|
|
|
apply hoare_value_con.
|
|
|
|
by apply ent_prove_pure.
|
|
|
|
by apply ent_prove_pure.
|
|
|
|
Qed.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ltac by_hoare_pred H := eapply hoare_pure; first reflexivity; intro H.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_eq_num (n m: Z):
|
|
|
|
|
|
|
|
{{ ⌜n = m⌝ }} #n = #m {{ u, ⌜u = #true⌝ }}.
|
|
|
|
|
|
|
|
Proof.
|
|
|
|
|
|
|
|
by_hoare_pred Heq; subst.
|
|
|
|
|
|
|
|
eapply hoare_pure_step; [ apply pure_step_eq; done | apply hoare_value_exact ].
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_neq_num (n m: Z):
|
|
|
|
Lemma hoare_neq_num (n m: Z):
|
|
|
|
{{ ⌜n ≠ m⌝ }} #n = #m {{ u, ⌜u = #false⌝ }}.
|
|
|
|
{{ ⌜n ≠ m⌝ }} #n = #m {{ u, ⌜u = #false⌝ }}.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
by_hoare_pred n_ne_m.
|
|
|
|
Admitted.
|
|
|
|
eapply hoare_pure_step; [ apply (pure_step_neq _ _ n_ne_m) | apply hoare_value_exact ].
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_sub (z1 z2: Z):
|
|
|
|
Lemma hoare_sub (z1 z2: Z):
|
|
|
|
{{ True }} #z1 - #z2 {{ v, ⌜v = #(z1 - z2)⌝ }}.
|
|
|
|
{{ True }} #z1 - #z2 {{ v, ⌜v = #(z1 - z2)⌝ }}.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
eapply hoare_pure_step; [ apply pure_step_sub | apply hoare_value_exact ].
|
|
|
|
Admitted.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_add (z1 z2: Z):
|
|
|
|
Lemma hoare_add (z1 z2: Z):
|
|
|
|
{{ True }} #z1 + #z2 {{ v, ⌜v = #(z1 + z2)⌝ }}.
|
|
|
|
{{ True }} #z1 + #z2 {{ v, ⌜v = #(z1 + z2)⌝ }}.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
eapply hoare_pure_step; [ apply pure_step_add | apply hoare_value_exact ].
|
|
|
|
Admitted.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_mul (z1 z2: Z):
|
|
|
|
|
|
|
|
{{ True }} #z1 * #z2 {{ v, ⌜v = #(z1 * z2)⌝ }}.
|
|
|
|
|
|
|
|
Proof.
|
|
|
|
|
|
|
|
eapply hoare_pure_step; [ apply pure_step_mul | apply hoare_value_exact ].
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_mul_nat (n1 n2: nat):
|
|
|
|
|
|
|
|
{{ True }} #n1 * #n2 {{ v, ⌜v = #((n1 * n2)%nat)⌝ }}.
|
|
|
|
|
|
|
|
Proof.
|
|
|
|
|
|
|
|
eapply hoare_con_post; [ | apply hoare_mul ].
|
|
|
|
|
|
|
|
intro v.
|
|
|
|
|
|
|
|
apply ent_pure_pure.
|
|
|
|
|
|
|
|
intros ->.
|
|
|
|
|
|
|
|
have n_eq : (n1 * n2)%Z = (n1 * n2)%nat.
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lia.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
rewrite n_eq.
|
|
|
|
|
|
|
|
reflexivity.
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_if_false P e1 e2 Φ:
|
|
|
|
Lemma hoare_if_false P e1 e2 Φ:
|
|
|
|
{{ P }} e2 {{ Φ }} →
|
|
|
|
{{ P }} e2 {{ Φ }} →
|
|
|
|
({{ P }} if: #false then e1 else e2 {{ Φ }}).
|
|
|
|
({{ P }} if: #false then e1 else e2 {{ Φ }}).
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
eapply hoare_pure_step. apply pure_step_if_false.
|
|
|
|
Admitted.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_if_true P e1 e2 Φ:
|
|
|
|
Lemma hoare_if_true P e1 e2 Φ:
|
|
|
|
{{ P }} e1 {{ Φ }} →
|
|
|
|
{{ P }} e1 {{ Φ }} →
|
|
|
|
({{ P }} if: #true then e1 else e2 {{ Φ }}).
|
|
|
|
({{ P }} if: #true then e1 else e2 {{ Φ }}).
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
eapply hoare_pure_step. apply pure_step_if_true.
|
|
|
|
Admitted.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma hoare_pure_pre φ Φ e:
|
|
|
|
Lemma hoare_pure_pre φ (ψ : val → iProp) e:
|
|
|
|
{{ ⌜φ⌝ }} e {{ Φ }} ↔ (φ → {{ True }} e {{ Φ }}).
|
|
|
|
{{ ⌜φ⌝ }} e {{ ψ }} ↔ (φ → {{ True }} e {{ ψ }}).
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
constructor.
|
|
|
|
Admitted.
|
|
|
|
- intros He Hφ.
|
|
|
|
|
|
|
|
(* For yet another ungodly reason,
|
|
|
|
|
|
|
|
now coq has been messed up and requires multiple goals to be proven inside of focus groups,
|
|
|
|
|
|
|
|
and if you fail to prove something in an apply, it just gets shelved away.
|
|
|
|
|
|
|
|
*)
|
|
|
|
|
|
|
|
eapply (hoare_con_pre (ent_prove_pure _ _ Hφ) He).
|
|
|
|
|
|
|
|
- intro He.
|
|
|
|
|
|
|
|
by_hoare_pred Hφ.
|
|
|
|
|
|
|
|
specialize (He Hφ).
|
|
|
|
|
|
|
|
by eapply (hoare_con_pre (ent_true _) He).
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** Example: Fibonacci *)
|
|
|
|
(** Example: Fibonacci *)
|
|
|
@ -199,18 +267,50 @@ Definition fib: val :=
|
|
|
|
else if: "n" = #1 then #1
|
|
|
|
else if: "n" = #1 then #1
|
|
|
|
else "fib" ("n" - #1) + "fib" ("n" - #2).
|
|
|
|
else "fib" ("n" - #1) + "fib" ("n" - #2).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ltac by_pure_step H := eapply hoare_pure_step; first apply H; simpl.
|
|
|
|
|
|
|
|
|
|
|
|
Lemma fib_zero:
|
|
|
|
Lemma fib_zero:
|
|
|
|
{{ True }} fib #0 {{ v, ⌜v = #0⌝ }}.
|
|
|
|
{{ True }} fib #0 {{ v, ⌜v = #0⌝ }}.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
unfold fib.
|
|
|
|
Admitted.
|
|
|
|
by_pure_step pure_step_beta.
|
|
|
|
|
|
|
|
eapply hoare_pure_step.
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
eapply (pure_step_fill [IfCtx _ _]).
|
|
|
|
|
|
|
|
apply pure_step_eq; reflexivity.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
simpl.
|
|
|
|
|
|
|
|
by_pure_step pure_step_if_true.
|
|
|
|
|
|
|
|
apply hoare_value_exact.
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma fib_one:
|
|
|
|
Lemma fib_one:
|
|
|
|
{{ True }} fib #1 {{ v, ⌜v = #1⌝ }}.
|
|
|
|
{{ True }} fib #1 {{ v, ⌜v = #1⌝ }}.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
unfold fib.
|
|
|
|
Admitted.
|
|
|
|
by_pure_step pure_step_beta.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
eapply hoare_pure_step.
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
eapply (pure_step_fill [IfCtx _ _]).
|
|
|
|
|
|
|
|
apply pure_step_neq. auto.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
simpl.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
by_pure_step pure_step_if_false.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
eapply hoare_pure_step.
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
eapply (pure_step_fill [IfCtx _ _]).
|
|
|
|
|
|
|
|
apply pure_step_eq; reflexivity.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
simpl.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
by_pure_step pure_step_if_true.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
apply hoare_value_exact.
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma fib_succ (z n m: Z):
|
|
|
|
Lemma fib_succ (z n m: Z):
|
|
|
@ -243,13 +343,58 @@ Proof.
|
|
|
|
eapply hoare_value_con. by apply ent_prove_pure.
|
|
|
|
eapply hoare_value_con. by apply ent_prove_pure.
|
|
|
|
Qed.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ltac hoare_erase_pre := eapply (hoare_con_pre (Q := True)); [ apply ent_prove_pure; tauto | ].
|
|
|
|
|
|
|
|
Ltac hoare_bind_cleanup :=
|
|
|
|
|
|
|
|
let v := fresh "v" in
|
|
|
|
|
|
|
|
let H := fresh "H" in
|
|
|
|
|
|
|
|
intro v; simpl; by_hoare_pred H; subst v; hoare_erase_pre.
|
|
|
|
|
|
|
|
|
|
|
|
Lemma fib_succ_oldschool (z n m: Z):
|
|
|
|
Lemma fib_succ_oldschool (z n m: Z):
|
|
|
|
{{ True }} fib #(z - 1)%Z {{ v, ⌜v = #n⌝ }} →
|
|
|
|
{{ True }} fib #(z - 1)%Z {{ v, ⌜v = #n⌝ }} →
|
|
|
|
{{ True }} fib #(z - 2)%Z {{ v, ⌜v = #m⌝ }} →
|
|
|
|
{{ True }} fib #(z - 2)%Z {{ v, ⌜v = #m⌝ }} →
|
|
|
|
{{ ⌜z > 1⌝%Z }} fib #z {{ v, ⌜v = #(n + m)⌝ }}.
|
|
|
|
{{ ⌜z > 1⌝%Z }} fib #z {{ v, ⌜v = #(n + m)⌝ }}.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
intros Hf1 Hf2.
|
|
|
|
Admitted.
|
|
|
|
by_hoare_pred z_gt_one.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unfold fib.
|
|
|
|
|
|
|
|
eapply hoare_rec.
|
|
|
|
|
|
|
|
simpl.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
eapply (hoare_bind [IfCtx _ _]).
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
eapply hoare_con_pre; [ eapply ent_prove_pure | eapply hoare_neq_num ].
|
|
|
|
|
|
|
|
lia.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
hoare_bind_cleanup.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
eapply hoare_if_false.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
eapply (hoare_bind [IfCtx _ _]).
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
eapply hoare_con_pre; [ eapply ent_prove_pure | eapply hoare_neq_num ].
|
|
|
|
|
|
|
|
lia.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
hoare_bind_cleanup.
|
|
|
|
|
|
|
|
eapply hoare_if_false.
|
|
|
|
|
|
|
|
fold fib.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
eapply (hoare_bind [BinOpRCtx PlusOp _]).
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
eapply (hoare_bind [AppRCtx _]); [ apply hoare_sub | hoare_bind_cleanup ].
|
|
|
|
|
|
|
|
exact Hf2.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
hoare_bind_cleanup.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
eapply (hoare_bind [BinOpLCtx PlusOp _]).
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
eapply (hoare_bind [AppRCtx _]); [ apply hoare_sub | hoare_bind_cleanup ].
|
|
|
|
|
|
|
|
exact Hf1.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
hoare_bind_cleanup.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
apply hoare_add.
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fixpoint Fib (n: nat) :=
|
|
|
|
Fixpoint Fib (n: nat) :=
|
|
|
@ -415,7 +560,19 @@ Definition fac : val :=
|
|
|
|
if: "n" = #0 then #1
|
|
|
|
if: "n" = #0 then #1
|
|
|
|
else "n" * "fac" ("n" - #1).
|
|
|
|
else "n" * "fac" ("n" - #1).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ltac hoare_simpl_if_neq :=
|
|
|
|
|
|
|
|
eapply (hoare_bind [IfCtx _ _]); [(
|
|
|
|
|
|
|
|
eapply hoare_con_pre; [ eapply ent_prove_pure | eapply hoare_neq_num ];
|
|
|
|
|
|
|
|
try lia
|
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
hoare_bind_cleanup; eapply hoare_if_false].
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ltac hoare_simpl_if_eq :=
|
|
|
|
|
|
|
|
eapply (hoare_bind [IfCtx _ _]); [(
|
|
|
|
|
|
|
|
eapply hoare_con_pre; [ eapply ent_prove_pure | eapply hoare_eq_num ];
|
|
|
|
|
|
|
|
try lia
|
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
hoare_bind_cleanup; eapply hoare_if_true].
|
|
|
|
|
|
|
|
|
|
|
|
Fixpoint Fac (n : nat) :=
|
|
|
|
Fixpoint Fac (n : nat) :=
|
|
|
|
match n with
|
|
|
|
match n with
|
|
|
@ -425,18 +582,46 @@ Fixpoint Fac (n : nat) :=
|
|
|
|
Lemma fac_computes_Fac (n : nat) :
|
|
|
|
Lemma fac_computes_Fac (n : nat) :
|
|
|
|
{{ True }} fac #n {{ v, ⌜v = #(Fac n)⌝ }}.
|
|
|
|
{{ True }} fac #n {{ v, ⌜v = #(Fac n)⌝ }}.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
induction n.
|
|
|
|
Admitted.
|
|
|
|
- unfold fac.
|
|
|
|
|
|
|
|
eapply hoare_rec; simpl.
|
|
|
|
|
|
|
|
hoare_simpl_if_eq.
|
|
|
|
|
|
|
|
apply hoare_value_exact.
|
|
|
|
|
|
|
|
- unfold fac.
|
|
|
|
|
|
|
|
eapply hoare_rec; simpl.
|
|
|
|
|
|
|
|
hoare_simpl_if_neq.
|
|
|
|
|
|
|
|
fold fac.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
eapply (hoare_bind [BinOpRCtx _ _]).
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
eapply (hoare_bind [AppRCtx _]); [ apply hoare_sub | hoare_bind_cleanup ].
|
|
|
|
|
|
|
|
have h₁ : (S n - 1)%Z = n.
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lia.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
rewrite h₁.
|
|
|
|
|
|
|
|
exact IHn.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
hoare_bind_cleanup.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
have h₂ : (Fac n) + n * (Fac n) = (S n) * (Fac n).
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lia.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rewrite h₂.
|
|
|
|
|
|
|
|
apply (hoare_mul_nat (S n) (Fac n)).
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** * Separation Logic *)
|
|
|
|
(** * Separation Logic *)
|
|
|
|
(*Check ent_sep_weaken.*)
|
|
|
|
Check ent_sep_weaken.
|
|
|
|
(*Check ent_sep_true.*)
|
|
|
|
Check ent_sep_true.
|
|
|
|
(*Check ent_sep_comm.*)
|
|
|
|
Check ent_sep_comm.
|
|
|
|
(*Check ent_sep_split.*)
|
|
|
|
Check ent_sep_split.
|
|
|
|
(*Check ent_sep_assoc.*)
|
|
|
|
Check ent_sep_assoc.
|
|
|
|
(*Check ent_pointsto_sep.*)
|
|
|
|
Check ent_pointsto_sep.
|
|
|
|
(*Check ent_exists_sep.*)
|
|
|
|
Check ent_exists_sep.
|
|
|
|
|
|
|
|
|
|
|
|
(* Note: The separating conjunction can usually be typed with \ast or \sep *)
|
|
|
|
(* Note: The separating conjunction can usually be typed with \ast or \sep *)
|
|
|
|
|
|
|
|
|
|
|
@ -444,15 +629,23 @@ Admitted.
|
|
|
|
Lemma ent_pointsto_disj l l' v w :
|
|
|
|
Lemma ent_pointsto_disj l l' v w :
|
|
|
|
l ↦ v ∗ l' ↦ w ⊢ ⌜l ≠ l'⌝.
|
|
|
|
l ↦ v ∗ l' ↦ w ⊢ ⌜l ≠ l'⌝.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
destruct (decide (l = l')) as [l_eq | l_neq].
|
|
|
|
Admitted.
|
|
|
|
- rewrite l_eq.
|
|
|
|
|
|
|
|
eapply ent_trans; [ apply ent_pointsto_sep | apply ent_false ].
|
|
|
|
|
|
|
|
- apply ent_prove_pure.
|
|
|
|
|
|
|
|
assumption.
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
Lemma ent_sep_exists {X} (Φ : X → iProp) P :
|
|
|
|
Lemma ent_sep_exists {X} (Φ : X → iProp) P :
|
|
|
|
(∃ x : X, Φ x ∗ P) ⊣⊢ (∃ x : X, Φ x) ∗ P.
|
|
|
|
(∃ x : X, Φ x ∗ P) ⊣⊢ (∃ x : X, Φ x) ∗ P.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
rewrite ent_equiv.
|
|
|
|
Admitted.
|
|
|
|
constructor.
|
|
|
|
|
|
|
|
- eapply ent_trans; [ apply ent_exist_elim; intro x | reflexivity ].
|
|
|
|
|
|
|
|
eapply ent_sep_split; [ | reflexivity ].
|
|
|
|
|
|
|
|
eapply ent_exist_intro; reflexivity.
|
|
|
|
|
|
|
|
- eapply ent_exists_sep.
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -467,15 +660,36 @@ Definition chain l r : iProp := ∃ n, ⌜n > 0⌝ ∗ chain_pre n l r.
|
|
|
|
Lemma chain_single (l r : loc) :
|
|
|
|
Lemma chain_single (l r : loc) :
|
|
|
|
l ↦ #r ⊢ chain l r.
|
|
|
|
l ↦ #r ⊢ chain l r.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
eapply (ent_trans _ (∃ t : loc, l ↦ #t ∗ ⌜t = r⌝) _); [ | eapply (ent_exist_intro 1); unfold chain_pre].
|
|
|
|
Admitted.
|
|
|
|
- eapply (ent_exist_intro r).
|
|
|
|
|
|
|
|
etransitivity; first apply ent_sep_true.
|
|
|
|
|
|
|
|
rewrite ent_sep_comm.
|
|
|
|
|
|
|
|
apply ent_sep_split; first reflexivity.
|
|
|
|
|
|
|
|
apply ent_prove_pure.
|
|
|
|
|
|
|
|
reflexivity.
|
|
|
|
|
|
|
|
- etrans; first apply ent_sep_true.
|
|
|
|
|
|
|
|
apply ent_sep_split; last reflexivity.
|
|
|
|
|
|
|
|
apply ent_prove_pure.
|
|
|
|
|
|
|
|
lia.
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma chain_cons (l r t : loc) :
|
|
|
|
Lemma chain_cons (l r t : loc) :
|
|
|
|
l ↦ #r ∗ chain r t ⊢ chain l t.
|
|
|
|
l ↦ #r ∗ chain r t ⊢ chain l t.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
unfold chain.
|
|
|
|
Admitted.
|
|
|
|
rewrite ent_sep_comm.
|
|
|
|
|
|
|
|
rewrite <-ent_sep_exists.
|
|
|
|
|
|
|
|
apply ent_exist_elim; intro x.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rewrite <-ent_sep_assoc.
|
|
|
|
|
|
|
|
rewrite (ent_sep_comm _ (l ↦ #r)).
|
|
|
|
|
|
|
|
eapply (ent_exist_intro (S x)).
|
|
|
|
|
|
|
|
unfold chain_pre; fold chain_pre.
|
|
|
|
|
|
|
|
apply ent_sep_split; [ apply ent_pure_pure; intro; lia | ].
|
|
|
|
|
|
|
|
eapply (ent_exist_intro r).
|
|
|
|
|
|
|
|
reflexivity.
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma chain_trans (l r t : loc) :
|
|
|
|
Lemma chain_trans (l r t : loc) :
|
|
|
@ -535,8 +749,12 @@ Lemma hoare_assert P e :
|
|
|
|
{{ P }} e {{ v, ⌜v = #true⌝ }} →
|
|
|
|
{{ P }} e {{ v, ⌜v = #true⌝ }} →
|
|
|
|
{{ P }} assert e {{ v, ⌜v = #()⌝ }}.
|
|
|
|
{{ P }} assert e {{ v, ⌜v = #()⌝ }}.
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* TODO: exercise *)
|
|
|
|
intro He.
|
|
|
|
Admitted.
|
|
|
|
unfold assert.
|
|
|
|
|
|
|
|
eapply (hoare_bind [IfCtx _ _]); [ exact He | hoare_bind_cleanup ].
|
|
|
|
|
|
|
|
apply hoare_if_true.
|
|
|
|
|
|
|
|
apply hoare_value_exact.
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma frame_example (f : val) :
|
|
|
|
Lemma frame_example (f : val) :
|
|
|
@ -748,4 +966,3 @@ Lemma tail_ll_strengthened v x xs :
|
|
|
|
Proof.
|
|
|
|
Proof.
|
|
|
|
(* FIXME: exercise *)
|
|
|
|
(* FIXME: exercise *)
|
|
|
|
Abort.
|
|
|
|
Abort.
|
|
|
|
|
|
|
|
|
|
|
|