[2514] | 1 | include "infrastructure.ma". |
---|
[2411] | 2 | |
---|
| 3 | inductive tag : Type[0] := a : tag | b : tag | c : tag. |
---|
| 4 | |
---|
| 5 | definition tags : list tag ≝ [a;b;c]. |
---|
| 6 | |
---|
| 7 | definition type_of_tag : ∀T:Type[0]. tag → Type[0] ≝ |
---|
| 8 | λT,t. match t with [ a ⇒ T | b ⇒ nat | c ⇒ bool ]. |
---|
| 9 | |
---|
| 10 | record test (T:Type[0]) : Type[0] ≝ |
---|
| 11 | { A_:option (type_of_tag T a); B_: option (type_of_tag T b); C_: option (type_of_tag T c) }. |
---|
| 12 | |
---|
| 13 | definition mk_test ≝ mk_test. |
---|
| 14 | |
---|
| 15 | definition proj_of_tag: ∀t:tag. ∀T:Type[0]. test T → option (type_of_tag T t) ≝ |
---|
| 16 | λt. match t with [ a ⇒ A_ | b ⇒ B_ | c ⇒ C_ ]. |
---|
| 17 | |
---|
| 18 | definition eq_tag : tag → tag → bool ≝ |
---|
| 19 | λt1,t2. |
---|
| 20 | match t1 with |
---|
| 21 | [ a ⇒ match t2 with [a => true | _ => false] |
---|
| 22 | | b ⇒ match t2 with [b => true | _ => false] |
---|
| 23 | | c ⇒ match t2 with [c => true | _ => false]]. |
---|
| 24 | |
---|
| 25 | definition Tag : DeqSet ≝ mk_DeqSet tag eq_tag ?. |
---|
| 26 | ** normalize /2/ % #abs destruct |
---|
| 27 | qed. |
---|
| 28 | |
---|
| 29 | record sub_test (l: list tag) (T: Type[0]) : Type[0] ≝ |
---|
| 30 | { |
---|
| 31 | st_el :> test T; |
---|
| 32 | st_el_in: for_each ? (λt. defined … (proj_of_tag t … st_el)) l |
---|
| 33 | }. |
---|
| 34 | |
---|
| 35 | coercion sub_test : ∀l:list tag. Type[0] → Type[0] |
---|
| 36 | ≝ sub_test on _l: list tag to Type[0] → Type[0]. |
---|
| 37 | |
---|
| 38 | (* |
---|
| 39 | coercion mk_sub_expr : |
---|
| 40 | ∀l:list tag.∀E.∀e:expr E. |
---|
| 41 | ∀p:is_in ? l e.sub_expr l E |
---|
| 42 | ≝ mk_sub_expr on e:expr ? to sub_expr ? ?. |
---|
| 43 | *) |
---|
| 44 | |
---|
| 45 | definition proj: |
---|
| 46 | ∀t:tag. ∀l:list tag. memb Tag t l → ∀T:Type[0]. l T → type_of_tag T t |
---|
| 47 | ≝ |
---|
| 48 | λt,l,H,T,r. |
---|
| 49 | match proj_of_tag t … r return λr. defined ? r → type_of_tag T t with |
---|
| 50 | [ None ⇒ λH:False.? |
---|
| 51 | | Some v ⇒ λH:True.v] ?. |
---|
| 52 | [2: cases H |
---|
| 53 | | lapply (st_el_in …r) inversion (for_each ???) [2: #_ #abs cases abs] |
---|
| 54 | #K #_ lapply (for_each_to_memb_to_true ???? H K) #X >X %] |
---|
| 55 | qed. |
---|
| 56 | |
---|
| 57 | definition A: ∀l:list tag. memb Tag a l → ∀T:Type[0]. l T → T ≝ proj a. |
---|
| 58 | definition B: ∀l:list tag. memb Tag b l → ∀T:Type[0]. l T → nat ≝ proj b. |
---|
| 59 | definition C: ∀l:list tag. memb Tag c l → ∀T:Type[0]. l T → bool ≝ proj c. |
---|
| 60 | |
---|
| 61 | let rec type_of_build_test0 (tags: list tag) (l:list tag) (T:Type[0]) on tags: Type[0] ≝ |
---|
| 62 | match tags with |
---|
| 63 | [ nil ⇒ l T |
---|
| 64 | | cons hd tl ⇒ |
---|
| 65 | if memb Tag hd l then |
---|
| 66 | (type_of_tag T hd → type_of_build_test0 tl l T) |
---|
| 67 | else |
---|
| 68 | type_of_build_test0 tl l T ]. |
---|
| 69 | |
---|
| 70 | definition type_of_build_test: list tag → Type[0] → Type[0] ≝ |
---|
| 71 | type_of_build_test0 tags. |
---|
| 72 | |
---|
| 73 | let rec type_of_mk_test0 (tags: list tag) (T:Type[0]) on tags: Type[0] ≝ |
---|
| 74 | match tags with |
---|
| 75 | [ nil ⇒ test T |
---|
| 76 | | cons hd tl ⇒ option (type_of_tag T hd) → type_of_mk_test0 tl T]. |
---|
| 77 | |
---|
| 78 | let rec mk_test0_ok (tags: list tag) (l:list tag) (T:Type[0]) on tags : |
---|
| 79 | type_of_mk_test0 tags T → Prop ≝ |
---|
| 80 | match tags return λtags.type_of_mk_test0 tags T → Prop with |
---|
| 81 | [ nil ⇒ λr:test T. bool_to_Prop (for_each ? (λt. defined … (proj_of_tag t … r)) l) |
---|
| 82 | | cons hd tl ⇒ λr:option (type_of_tag T hd) → type_of_mk_test0 tl T. |
---|
| 83 | if memb Tag hd l then |
---|
| 84 | ∀x:type_of_tag T hd. mk_test0_ok tl l T (r (Some … x)) |
---|
| 85 | else |
---|
| 86 | mk_test0_ok tl l T (r (None …)) |
---|
| 87 | ]. |
---|
| 88 | |
---|
| 89 | let rec build_test0 (tags: list tag) (l:list tag) (T:Type[0]) on tags : |
---|
| 90 | ∀mk_record:type_of_mk_test0 tags T. |
---|
| 91 | mk_test0_ok tags l T mk_record → type_of_build_test0 tags l T |
---|
| 92 | ≝ |
---|
| 93 | match tags |
---|
| 94 | return λtags. |
---|
| 95 | ∀mk_record:type_of_mk_test0 tags T. |
---|
| 96 | mk_test0_ok tags l T mk_record → type_of_build_test0 tags l T |
---|
| 97 | with |
---|
| 98 | [ nil ⇒ λr,r_ok.? |
---|
| 99 | | cons hd tl ⇒ λmk_record,mk_record_ok. |
---|
| 100 | match memb Tag hd l return λb. b=memb Tag hd l → if b then ? else ? with |
---|
| 101 | [ true ⇒ λH.λv. build_test0 tl l T (mk_record (Some ? v)) ? |
---|
| 102 | | false ⇒ λH.build_test0 tl l T (mk_record (None …)) ?] (refl … (memb Tag hd l))]. |
---|
| 103 | [ %{r} @r_ok |
---|
| 104 | |2,3: whd in mk_record_ok; <H in mk_record_ok; // ] |
---|
| 105 | qed. |
---|
| 106 | |
---|
| 107 | (*CSC: This needs to be proved every time :-( *) |
---|
| 108 | axiom mk_test_ok: ∀l: list tag. ∀T:Type[0]. mk_test0_ok tags l T (mk_test T). |
---|
| 109 | |
---|
| 110 | definition build_test: ∀l:list tag. ∀T:Type[0]. type_of_build_test l T ≝ |
---|
| 111 | λl,T. build_test0 tags l T (mk_test …) ?. |
---|
| 112 | // qed. |
---|
| 113 | |
---|
| 114 | example xxx: [a; c] True ≝ build_test [a;c] … I true. |
---|
| 115 | example xxx_c: C … xxx = true. // qed. |
---|
| 116 | (*CSC: here we need a lemma! *) |
---|
| 117 | example xxx_sub: [a;b] True → [a] True. |
---|
| 118 | #x %{x} cases x #y whd in ⊢ (% → %); whd in match (for_each ???); |
---|
| 119 | cases (for_each ???) [#X @X | #X cases X] |
---|
[2514] | 120 | qed. |
---|