diff options
Diffstat (limited to 'theories/res.v')
-rw-r--r-- | theories/res.v | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/theories/res.v b/theories/res.v new file mode 100644 index 0000000..d13bfee --- /dev/null +++ b/theories/res.v | |||
@@ -0,0 +1,75 @@ | |||
1 | From mininix Require Export utils. | ||
2 | From stdpp Require Import options. | ||
3 | |||
4 | Variant res A := | ||
5 | | Res (x : option A) | ||
6 | | NoFuel. | ||
7 | Arguments Res {_} _. | ||
8 | Arguments NoFuel {_}. | ||
9 | |||
10 | Instance res_fail : MFail res := λ {A} _, Res None. | ||
11 | |||
12 | Instance res_mret : MRet res := λ {A} x, Res (Some x). | ||
13 | |||
14 | Instance res_mbind : MBind res := λ {A B} f rx, | ||
15 | match rx with | ||
16 | | Res mx => default mfail (f <$> mx) | ||
17 | | NoFuel => NoFuel | ||
18 | end. | ||
19 | |||
20 | Instance res_fmap : FMap res := λ {A B} f rx, | ||
21 | match rx with | ||
22 | | Res mx => Res (f <$> mx) | ||
23 | | NoFuel => NoFuel | ||
24 | end. | ||
25 | |||
26 | Instance Res_inj A : Inj (=) (=) (@Res A). | ||
27 | Proof. by injection 1. Qed. | ||
28 | |||
29 | Ltac simplify_res := | ||
30 | repeat match goal with | ||
31 | | H : Res _ = mfail |- _ => apply (inj Res) in H | ||
32 | | H : mfail = Res _ |- _ => apply (inj Res) in H | ||
33 | | H : Res _ = mret _ |- _ => apply (inj Res) in H | ||
34 | | H : mret _ = Res _ |- _ => apply (inj Res) in H | ||
35 | | _ => progress simplify_eq/= | ||
36 | end. | ||
37 | |||
38 | Lemma mapM_Res_impl {A B} (f g : A → res B) (xs : list A) ys : | ||
39 | mapM f xs = Res ys → | ||
40 | (∀ x y, f x = Res y → g x = Res y) → | ||
41 | mapM g xs = Res ys. | ||
42 | Proof. | ||
43 | intros Hxs Hf. revert ys Hxs. | ||
44 | induction xs as [|x xs IH]; intros ys ?; simplify_res; [done|]. | ||
45 | destruct (f x) as [my|] eqn:?; simplify_res. rewrite (Hf x my) //=. | ||
46 | destruct my as [y|]; simplify_res; [|done]. | ||
47 | destruct (mapM f _) as [mys|]; simplify_res; [|done..]. | ||
48 | by rewrite (IH _ eq_refl). | ||
49 | Qed. | ||
50 | |||
51 | Lemma map_mapM_sorted_Res_impl `{FinMap K M} | ||
52 | (R : relation K) `{!RelDecision R, !PartialOrder R, !Total R} | ||
53 | {A B} (f g : A → res B) (m1 : M A) m2 : | ||
54 | map_mapM_sorted R f m1 = Res m2 → | ||
55 | (∀ x y, f x = Res y → g x = Res y) → | ||
56 | map_mapM_sorted R g m1 = Res m2. | ||
57 | Proof. | ||
58 | intros Hm Hf. revert m2 Hm. | ||
59 | induction m1 as [|i x m1 ?? IH] using (map_sorted_ind R); intros m2. | ||
60 | { by rewrite !map_mapM_sorted_empty. } | ||
61 | rewrite !map_mapM_sorted_insert //. intros. | ||
62 | destruct (f x) as [my|] eqn:?; simplify_res. rewrite (Hf x my) //=. | ||
63 | destruct my as [y|]; simplify_res; [|done]. | ||
64 | destruct (map_mapM_sorted _ f _) as [mm2'|]; simplify_res; [|done..]. | ||
65 | by rewrite (IH _ eq_refl). | ||
66 | Qed. | ||
67 | |||
68 | Lemma mapM_res_app {A B} (f : A → res B) xs1 xs2 : | ||
69 | mapM f (xs1 ++ xs2) = ys1 ← mapM f xs1; ys2 ← mapM f xs2; mret (ys1 ++ ys2). | ||
70 | Proof. | ||
71 | induction xs1 as [|x1 xs1 IH]; simpl. | ||
72 | { by destruct (mapM f xs2) as [[]|]. } | ||
73 | destruct (f x1) as [[y1|]|]; simpl; [|done..]. | ||
74 | rewrite IH. by destruct (mapM f xs1) as [[]|], (mapM f xs2) as [[]|]. | ||
75 | Qed. | ||