Mercurial > meta
comparison variant.ur @ 6:799f43bce62b
Import some code from iwl
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Tue, 14 Dec 2010 10:33:24 -0500 |
parents | |
children | 744bf911dcc6 |
comparison
equal
deleted
inserted
replaced
5:943410267fad | 6:799f43bce62b |
---|---|
1 fun read [r ::: {Unit}] [t ::: Type] (fl : folder r) (r : $(mapU t r)) (v : variant (mapU {} r)) : t = | |
2 match v | |
3 (@fold [fn r => r' :: {Unit} -> [r ~ r'] => $(mapU t (r ++ r')) -> $(mapU ({} -> t) r)] | |
4 (fn [nm :: Name] [u::_] [us::_] [[nm] ~ us] (cs : r' :: {Unit} -> [us ~ r'] => $(mapU t (us ++ r')) -> _) [r'::_] [[nm = u] ++ us ~ r'] r => | |
5 {nm = fn () => r.nm} ++ cs [[nm = u] ++ r'] ! r) | |
6 (fn [r'::_] [[] ~ r'] _ => {}) fl [[]] ! r) | |
7 | |
8 fun write [r ::: {Unit}] [t ::: Type] (fl : folder r) (r : $(mapU t r)) (v : variant (mapU {} r)) (x : t) : $(mapU t r) = | |
9 match v | |
10 (@fold [fn r => r' :: {Unit} -> [r ~ r'] => $(mapU t (r ++ r')) -> $(mapU ({} -> $(mapU t (r ++ r'))) r)] | |
11 (fn [nm :: Name] [u::_] [us::_] [[nm] ~ us] | |
12 (cs : r' :: {Unit} -> [us ~ r'] => $(mapU t (us ++ r')) -> $(mapU ({} -> $(mapU t (us ++ r'))) us)) | |
13 [r'::_] [[nm = u] ++ us ~ r'] r => | |
14 {nm = fn () => r -- nm ++ {nm = x}} ++ cs [[nm = u] ++ r'] ! r) | |
15 (fn [r'::_] [[] ~ r'] _ => {}) fl [[]] ! r) | |
16 | |
17 fun search [r] [t] (f : variant (mapU {} r) -> option t) (fl : folder r) : option t = | |
18 @fold [fn r => r' :: {Unit} -> [r ~ r'] => (variant (mapU {} (r ++ r')) -> option t) -> option t] | |
19 (fn [nm :: Name] [u ::_] [r ::_] [[nm] ~ r] | |
20 (acc : r' :: {Unit} -> [r ~ r'] => (variant (mapU {} (r ++ r')) -> option t) -> option t) | |
21 [r' ::_] [[nm] ++ r ~ r'] f' => | |
22 case f' (make [nm] {}) of | |
23 None => acc [[nm] ++ r'] ! f' | |
24 | v => v) | |
25 (fn [r' ::_] [[] ~ r'] _ => None) fl [[]] ! f | |
26 | |
27 fun find [r] (f : variant (mapU {} r) -> bool) (fl : folder r) : option (variant (mapU {} r)) = | |
28 @search (fn v => if f v then Some v else None) fl | |
29 | |
30 fun test [nm :: Name] [t ::: Type] [ts ::: {Type}] [[nm] ~ ts] (fl : folder ([nm = t] ++ ts)) | |
31 (v : variant ([nm = t] ++ ts)) : option t = | |
32 match v ({nm = Some} | |
33 ++ (@map0 [fn t' => t' -> option t] (fn [t' :: Type] _ => None) fl -- nm)) | |
34 | |
35 fun testLess [nm :: Name] [t ::: Type] [ts ::: {Type}] [[nm] ~ ts] (fl : folder ts) (v : variant ([nm = t] ++ ts)) : option t = | |
36 match v ({nm = Some} | |
37 ++ @map0 [fn t' => t' -> option t] (fn [t' :: Type] _ => None) fl) | |
38 | |
39 fun eq [r] (fl : folder r) (v1 : variant (mapU {} r)) (v2 : variant (mapU {} r)) : bool = | |
40 match v1 | |
41 (@fold [fn r => r' :: {Unit} -> [r ~ r'] => folder (r ++ r') -> variant (mapU {} (r ++ r')) -> $(mapU ({} -> bool) r)] | |
42 (fn [nm ::_] [u ::_] [r ::_] [[nm] ~ r] | |
43 (acc : r' :: {Unit} -> [r ~ r'] => folder (r ++ r') -> variant (mapU {} (r ++ r')) -> $(mapU ({} -> bool) r)) | |
44 [r' ::_] [[nm] ++ r ~ r'] (fl' : folder ([nm] ++ r ++ r')) v => | |
45 {nm = fn () => Option.isSome (@test [nm] ! (@Folder.mp fl') v)} | |
46 ++ acc [[nm] ++ r'] ! fl' v) | |
47 (fn [r' ::_] [[] ~ r'] _ _ => {}) fl [[]] ! fl v2) | |
48 | |
49 fun fold [r] [t] (fl : folder r) (f : variant (mapU {} r) -> t -> t) : t -> t = | |
50 @Top.fold [fn r => r' :: {Unit} -> [r ~ r'] => (variant (mapU {} (r ++ r')) -> t -> t) -> t -> t] | |
51 (fn [nm :: Name] [u ::_] [r ::_] [[nm] ~ r] | |
52 (acc : r' :: {Unit} -> [r ~ r'] => (variant (mapU {} (r ++ r')) -> t -> t) -> t -> t) | |
53 [r' ::_] [[nm] ++ r ~ r'] f' acc' => | |
54 f' (make [nm] {}) (acc [[nm] ++ r'] ! f' acc')) | |
55 (fn [r' ::_] [[] ~ r'] _ x => x) fl [[]] ! f | |
56 | |
57 fun destrR [K] [f :: K -> Type] [fr :: K -> Type] [t ::: Type] | |
58 (f : p :: K -> f p -> fr p -> t) | |
59 [r ::: {K}] (fl : folder r) (v : variant (map f r)) (r : $(map fr r)) : t = | |
60 match v | |
61 (@Top.mp [fr] [fn p => f p -> t] | |
62 (fn [p] (m : fr p) (v : f p) => f [p] v m) | |
63 fl r) | |
64 | |
65 fun destr2R [K] [f1 :: K -> Type] [f2 :: K -> Type] [fr :: K -> Type] [t ::: Type] | |
66 (f : p :: K -> f1 p -> f2 p -> fr p -> t) | |
67 [r ::: {K}] (fl : folder r) (v1 : variant (map f1 r)) (v2 : variant (map f2 r)) (r : $(map fr r)) : option t = | |
68 match v1 | |
69 (@foldR [fr] [fn r => others :: {K} -> [others ~ r] => | |
70 folder (r ++ others) | |
71 -> variant (map f2 (r ++ others)) | |
72 -> $(map (fn p => f1 p -> option t) r)] | |
73 (fn [nm ::_] [p ::_] [r ::_] [[nm] ~ r] (meta : fr p) | |
74 (acc : others :: {K} -> [others ~ r] => | |
75 folder (r ++ others) | |
76 -> variant (map f2 (r ++ others)) | |
77 -> $(map (fn p => f1 p -> option t) r)) | |
78 [others :: {K}] [others ~ [nm = p] ++ r] | |
79 (fl : folder ([nm = p] ++ r ++ others)) | |
80 (v2 : variant (map f2 ([nm = p] ++ r ++ others))) => | |
81 {nm = fn x1 => match v2 | |
82 ({nm = fn x2 => Some (f [p] x1 x2 meta)} | |
83 ++ (@map0 [fn p => f2 p -> option t] (fn [p' ::_] _ => None) fl -- nm))} | |
84 ++ acc [[nm = p] ++ others] ! fl v2) | |
85 (fn [others ::_] [others ~ []] _ _ => {}) | |
86 fl r [[]] ! fl v2) | |
87 | |
88 fun testEq [K] [f :: K -> Type] [nm :: Name] [t ::: K] [ts ::: {K}] [r ::: {K}] [[nm] ~ ts] | |
89 (pf : Eq.eq r ([nm = t] ++ ts)) (fl : folder r) (v : variant (map f r)) : option (f t) = | |
90 @test [nm] ! (@Folder.mp (@Eq.cast pf [folder] fl)) | |
91 (Eq.cast pf [fn r => variant (map f r)] v) | |
92 | |
93 fun makeEq [K] [f :: K -> Type] [nm :: Name] [t ::: K] [ts ::: {K}] [r ::: {K}] [[nm] ~ ts] | |
94 (pf : Eq.eq r ([nm = t] ++ ts)) (x : f t) : variant (map f r) = | |
95 Eq.cast (Eq.sym pf) [fn r => variant (map f r)] (make [nm] x) |