1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
From Stdlib Require Import Program.
From Stdlib Require Import String.
From Stdlib Require Import Ascii.
From Stdlib Require Import BinNums.
Set Implicit Arguments.
Set Strict Implicit.
Set Universe Polymorphism.
Set Printing Universes.
Local Open Scope positive.
Definition field : Type := positive.
Section poly.
Universe U.
Inductive fields : Type :=
| pm_Leaf : fields
| pm_Branch : fields -> option Type@{U} -> fields -> fields.
Definition fields_left (f : fields) : fields :=
match f with
| pm_Leaf => pm_Leaf
| pm_Branch l _ _ => l
end.
Definition fields_right (f : fields) : fields :=
match f with
| pm_Leaf => pm_Leaf
| pm_Branch _ _ r => r
end.
Definition fields_here (f : fields) : option Type@{U} :=
match f with
| pm_Leaf => None
| pm_Branch _ s _ => s
end.
Fixpoint fields_get (p : field) (m : fields) {struct p} : option Type@{U} :=
match p with
| xH => match m with
| pm_Leaf => None
| pm_Branch _ x _ => x
end
| xO p' => fields_get p' match m with
| pm_Leaf => pm_Leaf
| pm_Branch L _ _ => L
end
| xI p' => fields_get p' match m with
| pm_Leaf => pm_Leaf
| pm_Branch _ _ R => R
end
end.
Definition fields_leaf : fields := pm_Leaf.
Inductive member (val : Type@{U}) : fields -> Type :=
| pmm_H : forall L R, member val (pm_Branch L (Some val) R)
| pmm_L : forall (V : option Type@{U}) L R, member val L -> member val (pm_Branch L V R)
| pmm_R : forall (V : option Type@{U}) L R, member val R -> member val (pm_Branch L V R).
Arguments pmm_H {_ _ _}.
Arguments pmm_L {_ _ _ _} _.
Arguments pmm_R {_ _ _ _} _.
Fixpoint get_member (val : Type@{U}) p {struct p}
: forall m, fields_get p m = @Some Type@{U} val -> member val m :=
match p as p return forall m, fields_get p m = @Some Type@{U} val -> member@{U} val m with
| xH => fun m =>
match m as m return fields_get xH m = @Some Type@{U} val -> member@{U} val m with
| pm_Leaf => fun pf : None = @Some Type@{U} _ =>
match pf in _ = Z return match Z with
| Some _ => _
| None => unit
end
with
| eq_refl => tt
end
| pm_Branch _ None _ => fun pf : None = @Some Type@{U} _ =>
match pf in _ = Z return match Z with
| Some _ => _
| None => unit
end
with
| eq_refl => tt
end
| pm_Branch _ (Some x) _ => fun pf : @Some Type@{U} x = @Some Type@{U} val =>
match eq_sym pf in _ = Z return member@{U} val (pm_Branch _ Z _) with
| eq_refl => pmm_H
end
end
| xO p' => fun m =>
match m as m return fields_get (xO p') m = @Some Type@{U} val -> member@{U} val m with
| pm_Leaf => fun pf : fields_get p' pm_Leaf = @Some Type@{U} val =>
@get_member _ p' pm_Leaf pf
| pm_Branch l _ _ => fun pf : fields_get p' l = @Some Type@{U} val =>
@pmm_L _ _ _ _ (@get_member _ p' l pf)
end
| xI p' => fun m =>
match m as m return fields_get (xI p') m = @Some Type@{U} val -> member@{U} val m with
| pm_Leaf => fun pf : fields_get p' pm_Leaf = @Some Type@{U} val =>
@get_member _ p' pm_Leaf pf
| pm_Branch l _ r => fun pf : fields_get p' r = @Some Type@{U} val =>
@pmm_R _ _ _ _ (@get_member _ p' r pf)
end
end.
Inductive record : fields -> Type :=
| pr_Leaf : record pm_Leaf
| pr_Branch : forall L R (V : option Type@{U}),
record L ->
match V return Type@{U} with
| None => unit
| Some t => t
end ->
record R ->
record (pm_Branch L V R).
Definition record_left {L} {V : option Type@{U}} {R}
(r : record (pm_Branch L V R)) : record L :=
match r in record z
return match z with
| pm_Branch L _ _ => record L
| _ => unit
end
with
| pr_Branch _ l _ _ => l
| pr_Leaf => tt
end.
Set Printing All.
Definition record_at {L} {V : option Type@{U}} {R} (r : record (pm_Branch L V R))
: match V return Type@{U} with
| None => unit
| Some t => t
end :=
match r in record z
return match z (* return ?X *) with
| pm_Branch _ V _ => match V return Type@{U} with
| None => unit
| Some t => t
end
| _ => unit
end
with
| pr_Branch _ _ v _ => v
| pr_Leaf => tt
end.
Definition record_here {L : fields} (v : Type@{U}) {R : fields}
(r : record (pm_Branch L (@Some Type@{U} v) R)) : v :=
match r in record z
return match z return Type@{U} with
| pm_Branch _ (Some v) _ => v
| _ => unit
end
with
| pr_Branch _ _ v _ => v
| pr_Leaf => tt
end.
Definition record_right {L V R} (r : record (pm_Branch L V R)) : record R :=
match r in record z return match z with
| pm_Branch _ _ R => record R
| _ => unit
end
with
| pr_Branch _ _ _ r => r
| pr_Leaf => tt
end.
Fixpoint record_get {val : Type@{U}} {pm : fields} (m : member val pm) : record pm -> val :=
match m in member _ pm return record pm -> val with
| pmm_H => fun r => record_here r
| pmm_L m' => fun r => record_get m' (record_left r)
| pmm_R m' => fun r => record_get m' (record_right r)
end.
Fixpoint record_set {val : Type@{U}} {pm : fields} (m : member val pm) (x : val) {struct m}
: record pm -> record pm :=
match m in member _ pm return record pm -> record pm with
| pmm_H => fun r =>
pr_Branch (Some _)
(record_left r)
x
(record_right r)
| pmm_L m' => fun r =>
pr_Branch _
(record_set m' x (record_left r))
(record_at r)
(record_right r)
| pmm_R m' => fun r =>
pr_Branch _ (record_left r)
(record_at r)
(record_set m' x (record_right r))
end.
End poly.
Axiom cheat : forall {A}, A.
Lemma record_get_record_set_different:
forall (T: Type) (vars: fields)
(pmr pmw: member T vars)
(diff: pmr <> pmw)
(r: record vars) (val: T),
record_get pmr (record_set pmw val r) = record_get pmr r.
Proof.
intros.
revert pmr diff r val.
induction pmw; simpl; intros.
- dependent destruction pmr.
+ congruence.
+ auto.
+ auto.
- dependent destruction pmr.
+ auto.
+ simpl. apply IHpmw. congruence.
+ auto.
- dependent destruction pmr.
+ auto.
+ auto.
+ simpl. apply IHpmw. congruence.
Qed.
|