diff options
Diffstat (limited to 'theories/nix/wp_examples.v')
-rw-r--r-- | theories/nix/wp_examples.v | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/theories/nix/wp_examples.v b/theories/nix/wp_examples.v new file mode 100644 index 0000000..7bc2109 --- /dev/null +++ b/theories/nix/wp_examples.v | |||
@@ -0,0 +1,164 @@ | |||
1 | From mininix Require Import nix.wp nix.notations. | ||
2 | From stdpp Require Import options. | ||
3 | Local Open Scope Z_scope. | ||
4 | |||
5 | Definition test αs := | ||
6 | let: "x" := 1 in | ||
7 | with: EAttr αs in | ||
8 | with: EAttr {[ "y" := AttrN 2 ]} in | ||
9 | "x" =: "y". | ||
10 | |||
11 | Example test_wp μ αs : | ||
12 | no_recs αs → | ||
13 | wp μ (test αs) (.= false). | ||
14 | Proof. | ||
15 | intros Hαs. rewrite /test. apply LetAttr_no_recs_wp. | ||
16 | { by apply no_recs_insert. } | ||
17 | rewrite /= !map_fmap_singleton /= right_id_L lookup_singleton lookup_singleton_ne //=. | ||
18 | apply LetAttr_no_recs_wp. | ||
19 | { by apply no_recs_attr_subst. } | ||
20 | rewrite /= !map_fmap_singleton /= right_id_L. | ||
21 | rewrite (map_fmap_compose attr_expr) lookup_fmap union_kinded_abs. | ||
22 | rewrite !lookup_fmap. | ||
23 | apply LetAttr_no_recs_wp. | ||
24 | { by apply no_recs_insert. } | ||
25 | rewrite /= map_fmap_singleton lookup_singleton lookup_singleton_ne //=. | ||
26 | rewrite union_kinded_with. | ||
27 | apply BinOp_wp. | ||
28 | apply Id_wp, Lit_wp; first done. eexists; split; [constructor|]. | ||
29 | apply Id_wp, Lit_wp; first done. | ||
30 | eexists; split; [done|]. by apply Lit_wp. | ||
31 | Qed. | ||
32 | |||
33 | Definition neg := λ: "b", if: "b" then false else true. | ||
34 | |||
35 | Lemma neg_wp μ (Φ : expr → Prop) e : | ||
36 | wp SHALLOW e (λ e', ∃ b : bool, e' = b ∧ Φ (negb b)) → | ||
37 | wp μ (neg e) Φ. | ||
38 | Proof. | ||
39 | intros Hwp. apply β_wp. rewrite /= lookup_singleton /=. | ||
40 | apply If_wp, Id_wp. eapply wp_mono; [done|]. | ||
41 | intros ? (b & -> & ?). exists b; split; [done|]. | ||
42 | destruct b; by apply Lit_wp. | ||
43 | Qed. | ||
44 | |||
45 | (* rec { f = x: if x = 0 then true else !(f (x - 1)); }.f n *) | ||
46 | Definition even_rec_attr := | ||
47 | EAttr {[ "f" := AttrR (λ: "x", if: "x" =: 0 then true else neg ("f" ("x" -: 1))) ]} .: "f". | ||
48 | |||
49 | Lemma even_rec_attr_wp e n : | ||
50 | 0 ≤ n ≤ int_max → | ||
51 | wp SHALLOW e (.= n) → | ||
52 | wp SHALLOW (even_rec_attr e) (.= Z.even n). | ||
53 | Proof. | ||
54 | intros Hn Hwp. apply App_wp. | ||
55 | revert e Hwp. induction (Z.lt_wf 0 n) as [n _ IH]; intros e Hwp. | ||
56 | apply BinOp_wp. apply Attr_wp_shallow. | ||
57 | eexists; split; [by constructor|]. | ||
58 | apply Lit_wp; [done|]. eexists; split; [by eexists|]. | ||
59 | rewrite /=. apply Abs_wp, β_wp. | ||
60 | rewrite /= !lookup_singleton /= !lookup_singleton_ne //=. | ||
61 | rewrite !union_with_None_l !union_with_None_r. | ||
62 | rewrite /indirects map_imap_insert map_imap_empty lookup_insert. | ||
63 | rewrite -/even_rec_attr -/neg. | ||
64 | apply If_wp, BinOp_wp, Id_wp. | ||
65 | eapply wp_mono; [apply Hwp|]; intros ? ->. | ||
66 | eexists; split; [by constructor|]. | ||
67 | apply Lit_wp; [done|]. eexists; split; [by eexists|]. simpl. | ||
68 | destruct (n =? 0) eqn:Hn0; (apply Lit_wp; [done|]; eexists; split; [done|]; simpl). | ||
69 | { apply Lit_wp; [done|]. by apply Z.eqb_eq in Hn0 as ->. } | ||
70 | apply neg_wp, App_wp, Id_wp. | ||
71 | eapply wp_mono; [apply (IH (n-1))|]; [lia..| |]. | ||
72 | 2:{ intros e' He'. eapply wp_mono; [apply He'|]. | ||
73 | intros ? ->. eexists; split; [done|]. | ||
74 | by rewrite Z.negb_even Z.sub_1_r Z.odd_pred. } | ||
75 | eapply BinOp_wp, Id_wp. eapply wp_mono; [apply Hwp|]. intros ? ->. | ||
76 | eexists; split; [by constructor|]. apply Lit_wp; [done|]. | ||
77 | eexists; split; [eexists _, _; split_and!; [done| |done]|]. | ||
78 | - rewrite /= option_guard_True //. apply bool_decide_pack. | ||
79 | rewrite /int_min Z.shiftl_mul_pow2 //. lia. | ||
80 | - apply Lit_wp; [|done]. apply bool_decide_pack. | ||
81 | rewrite /int_min Z.shiftl_mul_pow2 //. lia. | ||
82 | Qed. | ||
83 | |||
84 | Lemma even_rec_attr_wp' n : | ||
85 | 0 ≤ n ≤ int_max → | ||
86 | wp SHALLOW (even_rec_attr n) (.= Z.even n). | ||
87 | Proof. | ||
88 | intros ?. apply even_rec_attr_wp; [done|]. apply Lit_wp; [|done]. | ||
89 | rewrite /= /int_ok. apply bool_decide_pack. | ||
90 | rewrite /int_min Z.shiftl_mul_pow2 //. lia. | ||
91 | Qed. | ||
92 | |||
93 | (* { "__functor " = r: x: if x == 0 then true else !(r (x - 1)); } n *) | ||
94 | Definition even_rec_functor := | ||
95 | EAttr {[ "__functor" := | ||
96 | AttrN (λ: "r" "x", if: "x" =: 0 then true else neg ("r" ("x" -: 1))) ]}. | ||
97 | |||
98 | Lemma even_rec_functor_wp e n : | ||
99 | 0 ≤ n ≤ int_max → | ||
100 | wp SHALLOW e (.= n) → | ||
101 | wp SHALLOW (even_rec_functor e) (.= Z.even n). | ||
102 | Proof. | ||
103 | intros Hn Hwp. apply App_wp. | ||
104 | revert e Hwp. induction (Z.lt_wf 0 n) as [n _ IH]; intros e Hwp. | ||
105 | apply Attr_wp_shallow. rewrite map_fmap_singleton /=. eapply Functor_wp. | ||
106 | { by apply no_recs_insert. } | ||
107 | { done. } | ||
108 | apply App_wp. apply β_wp. | ||
109 | rewrite /= !lookup_singleton !lookup_singleton_ne //=. apply Abs_wp, β_wp. | ||
110 | rewrite /= !lookup_singleton /= !lookup_singleton_ne //=. | ||
111 | rewrite -/even_rec_functor -/neg. | ||
112 | apply If_wp, BinOp_wp, Id_wp. | ||
113 | eapply wp_mono; [apply Hwp|]; intros ? ->. | ||
114 | eexists; split; [by constructor|]. | ||
115 | apply Lit_wp; [done|]. eexists; split; [by eexists|]. simpl. | ||
116 | destruct (n =? 0) eqn:Hn0; (apply Lit_wp; [done|]; eexists; split; [done|]; simpl). | ||
117 | { apply Lit_wp; [done|]. by apply Z.eqb_eq in Hn0 as ->. } | ||
118 | apply neg_wp, App_wp, Id_wp. | ||
119 | eapply wp_mono; [apply (IH (n-1))|]; [lia..| |]. | ||
120 | 2:{ intros e' He'. eapply wp_mono; [apply He'|]. | ||
121 | intros ? ->. eexists; split; [done|]. | ||
122 | by rewrite Z.negb_even Z.sub_1_r Z.odd_pred. } | ||
123 | eapply BinOp_wp, Id_wp. eapply wp_mono; [apply Hwp|]. intros ? ->. | ||
124 | eexists; split; [by constructor|]. apply Lit_wp; [done|]. | ||
125 | eexists; split; [eexists _, _; split_and!; [done| |done]|]. | ||
126 | - rewrite /= option_guard_True //. apply bool_decide_pack. | ||
127 | rewrite /int_min Z.shiftl_mul_pow2 //. lia. | ||
128 | - apply Lit_wp; [|done]. apply bool_decide_pack. | ||
129 | rewrite /int_min Z.shiftl_mul_pow2 //. lia. | ||
130 | Qed. | ||
131 | |||
132 | Lemma even_rec_functor_wp' n : | ||
133 | 0 ≤ n ≤ int_max → | ||
134 | wp SHALLOW (even_rec_functor n) (.= Z.even n). | ||
135 | Proof. | ||
136 | intros ?. apply even_rec_functor_wp; [done|]. apply Lit_wp; [|done]. | ||
137 | rewrite /= /int_ok. apply bool_decide_pack. | ||
138 | rewrite /int_min Z.shiftl_mul_pow2 //. lia. | ||
139 | Qed. | ||
140 | |||
141 | (* ({ f ? (x: if x == 0 then true else !(f (x - 1))) }: f) {} n *) | ||
142 | Definition even_rec_default := | ||
143 | (λattr: | ||
144 | {[ "f" := Some (λ: "x", if: "x" =: 0 then true else neg ("f" ("x" -: 1))) ]}, "f") | ||
145 | (EAttr ∅). | ||
146 | |||
147 | Lemma even_rec_default_wp e n : | ||
148 | 0 ≤ n ≤ int_max → | ||
149 | wp SHALLOW e (.= n) → | ||
150 | wp SHALLOW (even_rec_default e) (.= Z.even n). | ||
151 | Proof. | ||
152 | intros Hn Hwp. apply App_wp. | ||
153 | eapply βMatch_wp; [done|repeat econstructor|]. simplify_map_eq. | ||
154 | rewrite -/even_rec_attr. by apply Id_wp, App_wp, even_rec_attr_wp. | ||
155 | Qed. | ||
156 | |||
157 | Lemma even_rec_default_wp' n : | ||
158 | 0 ≤ n ≤ int_max → | ||
159 | wp SHALLOW (even_rec_default n) (.= Z.even n). | ||
160 | Proof. | ||
161 | intros ?. apply even_rec_default_wp; [done|]. apply Lit_wp; [|done]. | ||
162 | rewrite /= /int_ok. apply bool_decide_pack. | ||
163 | rewrite /int_min Z.shiftl_mul_pow2 //. lia. | ||
164 | Qed. | ||