-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsorts.v
133 lines (113 loc) · 2.74 KB
/
sorts.v
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
#[global]
Set Primitive Projections.
#[global]
Unset Printing Primitive Projection Parameters.
#[global]
Set Universe Polymorphism.
#[global]
Set Default Goal Selector "!".
Require Import Coq.Unicode.Utf8.
Import IfNotations.
Inductive Tag := Const | Sum | Prod.
Definition eq_Tag (x y: Tag): {x = y} + {x ≠ y}.
Proof.
decide equality.
Defined.
Definition eqb x y := if eq_Tag x y then True else False.
#[universes(cumulative)]
CoInductive U := u {
tag: Tag ;
const_u: eqb tag Const → Type ;
sum_left: eqb tag Sum → U ;
sum_right: eqb tag Sum → U ;
prod_left: eqb tag Prod → U ;
prod_right: eqb tag Prod → U ;
}.
Notation "'const' A" := {|
tag := Const ;
const_u _ := A ;
prod_left x := match x: False with end ;
prod_right x := match x: False with end ;
sum_left x := match x: False with end ;
sum_right x := match x: False with end ;
|} (at level 1).
Notation "A * B" := {|
tag := Prod ;
prod_left _ := A ;
prod_right _ := B ;
const_u x := match x: False with end ;
sum_left x := match x: False with end ;
sum_right x := match x: False with end ;
|}.
Notation "A + B" := {|
tag := Sum ;
sum_left _ := A ;
sum_right _ := B ;
const_u x := match x: False with end ;
prod_left x := match x: False with end ;
prod_right x := match x: False with end ;
|}.
Definition is_const: U → option Type.
Proof.
intro u.
destruct u.
destruct (eq_Tag tag0 Const).
2: apply None.
subst.
apply Some.
apply const_u0.
apply I.
Defined.
Definition is_sum: U → option (U * U).
Proof.
intro u.
destruct u.
destruct (eq_Tag tag0 Sum).
2: apply None.
subst.
apply Some.
split.
- apply sum_left0.
cbn.
apply I.
- apply sum_right0.
cbn.
apply I.
Defined.
Definition is_prod: U → option (U * U).
Proof.
intro u.
destruct u.
destruct (eq_Tag tag0 Prod).
2: apply None.
subst.
apply Some.
split.
- apply prod_left0.
cbn.
apply I.
- apply prod_right0.
cbn.
apply I.
Defined.
#[universes(cumulative)]
Inductive El (u: U) :=
| El_const:
(if is_const u is Some T then T else False) → El u
| El_pair:
El (if is_prod u is Some (A, _) then A else const Empty_set) →
El (if is_prod u is Some (_, B) then B else const Empty_set) →
El u
| El_inl:
El (if is_sum u is Some (A, _) then A else const Empty_set) →
El u
| El_inr:
El (if is_sum u is Some (_, B) then B else const Empty_set) →
El u
.
Coercion El: U >-> Sortclass.
Definition pt: El (const unit) := El_const (const unit) tt.
CoFixpoint list A := const unit + (const A * list A).
Definition nil {A}: list A := El_inl (list A) (El_const (const unit) tt).
Definition cons {A} (h: A) (t: list A): list A :=
El_inr (list A) (El_pair (const A * list A) (El_const (const A) h) t).