tree_sum.v 2.03 KB
Newer Older
1
2
From iris.program_logic Require Export weakestpre.
From iris.heap_lang Require Export lang.
3
4
From iris.proofmode Require Export tactics.
From iris.heap_lang Require Import proofmode notation.
5
Set Default Proof Using "Type".
6
7
8
9
10

Inductive tree :=
  | leaf : Z  tree
  | node : tree  tree  tree.

11
Fixpoint is_tree `{!heapG Σ} (v : val) (t : tree) : iProp Σ :=
12
  match t with
Ralf Jung's avatar
Ralf Jung committed
13
  | leaf n => v = InjLV #n
14
15
  | node tl tr =>
      (ll lr : loc) (vl vr : val),
Ralf Jung's avatar
Ralf Jung committed
16
       v = InjRV (#ll,#lr)  ll  vl  is_tree vl tl  lr  vr  is_tree vr tr
17
18
19
20
21
22
23
24
25
26
  end%I.

Fixpoint sum (t : tree) : Z :=
  match t with
  | leaf n => n
  | node tl tr => sum tl + sum tr
  end.

Definition sum_loop : val :=
  rec: "sum_loop" "t" "l" :=
27
28
29
    match: "t" with
      InjL "n" => "l" <- "n" + !"l"
    | InjR "tt" => "sum_loop" !(Fst "tt") "l" ;; "sum_loop" !(Snd "tt") "l"
30
31
32
33
    end.

Definition sum' : val := λ: "t",
  let: "l" := ref #0 in
34
35
  sum_loop "t" "l";;
  !"l".
36

37
38
39
40
Lemma sum_loop_wp `{!heapG Σ} v t l (n : Z) :
  {{{ l  #n  is_tree v t }}}
    sum_loop v #l
  {{{ RET #(); l  #(sum t + n)  is_tree v t }}}.
41
Proof.
42
  iIntros (Φ) "[Hl Ht] HΦ".
43
  iLöb as "IH" forall (v t l n Φ). wp_rec. wp_let.
44
45
  destruct t as [n'|tl tr]; simpl in *.
  - iDestruct "Ht" as "%"; subst.
46
    wp_match. wp_load. wp_op. wp_store.
47
    by iApply ("HΦ" with "[$Hl]").
48
  - iDestruct "Ht" as (ll lr vl vr) "(% & Hll & Htl & Hlr & Htr)"; subst.
49
    wp_match. wp_proj. wp_load.
50
    wp_apply ("IH" with "Hl Htl"). iIntros "[Hl Htl]".
51
    wp_seq. wp_proj. wp_load.
52
53
    wp_apply ("IH" with "Hl Htr"). iIntros "[Hl Htr]".
    iApply "HΦ". iSplitL "Hl".
54
55
56
57
    { by replace (sum tl + sum tr + n) with (sum tr + (sum tl + n)) by omega. }
    iExists ll, lr, vl, vr. by iFrame.
Qed.

58
59
Lemma sum_wp `{!heapG Σ} v t :
  {{{ is_tree v t }}} sum' v {{{ RET #(sum t); is_tree v t }}}.
60
Proof.
61
  iIntros (Φ) "Ht HΦ". rewrite /sum' /=.
62
  wp_let. wp_alloc l as "Hl". wp_let.
63
  wp_apply (sum_loop_wp with "[$Hl $Ht]").
64
  rewrite Z.add_0_r.
65
  iIntros "[Hl Ht]". wp_seq. wp_load. by iApply "HΦ".
66
Qed.