blob: 5db848702afad5d176352bbc720e4a54976265e4 (
plain)
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
(* Title: HoTT/EqualProps.thy
Author: Josh Chen
Properties of equality
*)
theory EqualProps
imports
HoTT_Methods
Equal
Prod
begin
section \<open>Symmetry / Path inverse\<close>
definition inv :: "Term \<Rightarrow> Term" ("_\<inverse>" [1000] 1000) where "p\<inverse> \<equiv> ind\<^sub>= (\<lambda>x. (refl x)) p"
text "
In the proof below we begin by using path induction on \<open>p\<close> with the application of \<open>rule Equal_elim\<close>, telling Isabelle the specific substitutions to use.
The proof is finished with a standard application of the relevant type rules.
"
lemma inv_type:
assumes "A : U i" and "x : A" and "y : A" and "p: x =\<^sub>A y" shows "p\<inverse>: y =\<^sub>A x"
unfolding inv_def
by (rule Equal_elim[where ?x=x and ?y=y]) (routine lems: assms)
\<comment> \<open>The type doesn't depend on \<open>p\<close> so we don't need to specify \<open>?p\<close> in the \<open>where\<close> clause above.\<close>
text "
The next proof requires explicitly telling Isabelle what to substitute on the RHS of the typing judgment after the initial application of the type rules.
(If viewing this inside Isabelle, place the cursor after the \<open>proof\<close> statement and observe the second subgoal.)
"
lemma inv_comp:
assumes "A : U i " and "a : A" shows "(refl a)\<inverse> \<equiv> refl a"
unfolding inv_def
proof compute
show "\<And>x. x: A \<Longrightarrow> refl x: x =\<^sub>A x" ..
qed (routine lems: assms)
section \<open>Transitivity / Path composition\<close>
text "
Raw composition function, of type \<open>\<Prod>x:A. \<Prod>y:A. x =\<^sub>A y \<rightarrow> (\<Prod>z:A. y =\<^sub>A z \<rightarrow> x =\<^sub>A z)\<close> polymorphic over the type \<open>A\<close>.
"
definition rpathcomp :: Term where "rpathcomp \<equiv> \<^bold>\<lambda>_ _ p. ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>_ q. ind\<^sub>= (\<lambda>x. (refl x)) q) p"
text "
More complicated proofs---the nested path inductions require more explicit step-by-step rule applications:
"
lemma rpathcomp_type:
assumes "A: U i"
shows "rpathcomp: \<Prod>x:A. \<Prod>y:A. x =\<^sub>A y \<rightarrow> (\<Prod>z:A. y =\<^sub>A z \<rightarrow> x =\<^sub>A z)"
unfolding rpathcomp_def
proof
fix x assume 1: "x: A"
show "\<^bold>\<lambda>y p. ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>z q. ind\<^sub>= refl q) p: \<Prod>y:A. x =\<^sub>A y \<rightarrow> (\<Prod>z:A. y =\<^sub>A z \<rightarrow> x =\<^sub>A z)"
proof
fix y assume 2: "y: A"
show "\<^bold>\<lambda>p. ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>z q. ind\<^sub>= refl q) p: x =\<^sub>A y \<rightarrow> (\<Prod>z:A. y =\<^sub>A z \<rightarrow> x =\<^sub>A z)"
proof
fix p assume 3: "p: x =\<^sub>A y"
show "ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>z q. ind\<^sub>= refl q) p: \<Prod>z:A. y =\<^sub>A z \<rightarrow> x =\<^sub>A z"
proof (rule Equal_elim[where ?x=x and ?y=y])
show "\<And>u. u: A \<Longrightarrow> \<^bold>\<lambda>z q. ind\<^sub>= refl q: \<Prod>z:A. u =\<^sub>A z \<rightarrow> u =\<^sub>A z"
proof
show "\<And>u z. \<lbrakk>u: A; z: A\<rbrakk> \<Longrightarrow> \<^bold>\<lambda>q. ind\<^sub>= refl q: u =\<^sub>A z \<rightarrow> u =\<^sub>A z"
proof
fix u z q assume asm: "u: A" "z: A" "q: u =\<^sub>A z"
show "ind\<^sub>= refl q: u =\<^sub>A z"
by (rule Equal_elim[where ?x=u and ?y=z]) (routine lems: assms asm)
qed (routine lems: assms)
qed (rule assms)
qed (routine lems: assms 1 2 3)
qed (routine lems: assms 1 2)
qed (rule assms)
qed fact
corollary
assumes "A: U i" "x: A" "y: A" "z: A" "p: x =\<^sub>A y" "q: y =\<^sub>A z"
shows "rpathcomp`x`y`p`z`q: x =\<^sub>A z"
by (routine lems: assms rpathcomp_type)
text "
The following proof is very long, chiefly because for every application of \<open>`\<close> we have to show the wellformedness of the type family appearing in the equality computation rule.
"
lemma rpathcomp_comp:
assumes "A: U i" and "a: A"
shows "rpathcomp`a`a`(refl a)`a`(refl a) \<equiv> refl a"
unfolding rpathcomp_def
proof compute
fix x assume 1: "x: A"
show "\<^bold>\<lambda>y p. ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>z q. ind\<^sub>= refl q) p: \<Prod>y:A. x =\<^sub>A y \<rightarrow> (\<Prod>z:A. y =\<^sub>A z \<rightarrow> x =\<^sub>A z)"
proof
fix y assume 2: "y: A"
show "\<^bold>\<lambda>p. ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>z q. ind\<^sub>= refl q) p: x =\<^sub>A y \<rightarrow> (\<Prod>z:A. y =\<^sub>A z \<rightarrow> x =\<^sub>A z)"
proof
fix p assume 3: "p: x =\<^sub>A y"
show "ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>z q. ind\<^sub>= refl q) p: \<Prod>z:A. y =\<^sub>A z \<rightarrow> x =\<^sub>A z"
proof (rule Equal_elim[where ?x=x and ?y=y])
show "\<And>u. u: A \<Longrightarrow> \<^bold>\<lambda>z q. ind\<^sub>= refl q: \<Prod>z:A. u =\<^sub>A z \<rightarrow> u =\<^sub>A z"
proof
show "\<And>u z. \<lbrakk>u: A; z: A\<rbrakk> \<Longrightarrow> \<^bold>\<lambda>q. ind\<^sub>= refl q: u =\<^sub>A z \<rightarrow> u =\<^sub>A z"
proof
fix u z assume asm: "u: A" "z: A"
show "\<And>q. q: u =\<^sub>A z \<Longrightarrow> ind\<^sub>= refl q: u =\<^sub>A z"
by (rule Equal_elim[where ?x=u and ?y=z]) (routine lems: assms asm)
qed (routine lems: assms)
qed (rule assms)
qed (routine lems: assms 1 2 3)
qed (routine lems: assms 1 2)
qed (rule assms)
next show "(\<^bold>\<lambda>y p. ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>z q. ind\<^sub>= refl q) p)`a`(refl a)`a`(refl a) \<equiv> refl a"
proof compute
fix y assume 1: "y: A"
show "\<^bold>\<lambda>p. ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>z q. ind\<^sub>= refl q) p: a =\<^sub>A y \<rightarrow> (\<Prod>z:A. y =\<^sub>A z \<rightarrow> a =\<^sub>A z)"
proof
fix p assume 2: "p: a =\<^sub>A y"
show "ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>z q. ind\<^sub>= refl q) p: \<Prod>z:A. y =\<^sub>A z \<rightarrow> a =\<^sub>A z"
proof (rule Equal_elim[where ?x=a and ?y=y])
fix u assume 3: "u: A"
show "\<^bold>\<lambda>z q. ind\<^sub>= refl q: \<Prod>z:A. u =\<^sub>A z \<rightarrow> u =\<^sub>A z"
proof
fix z assume 4: "z: A"
show "\<^bold>\<lambda>q. ind\<^sub>= refl q: u =\<^sub>A z \<rightarrow> u =\<^sub>A z"
proof
show "\<And>q. q: u =\<^sub>A z \<Longrightarrow> ind\<^sub>= refl q: u =\<^sub>A z"
by (rule Equal_elim[where ?x=u and ?y=z]) (routine lems: assms 3 4)
qed (routine lems: assms 3 4)
qed fact
qed (routine lems: assms 1 2)
qed (routine lems: assms 1)
next show "(\<^bold>\<lambda>p. ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>z. \<^bold>\<lambda>q. ind\<^sub>= refl q) p)`(refl a)`a`(refl a) \<equiv> refl a"
proof compute
fix p assume 1: "p: a =\<^sub>A a"
show "ind\<^sub>= (\<lambda>_. \<^bold>\<lambda>z q. ind\<^sub>= refl q) p: \<Prod>z:A. a =\<^sub>A z \<rightarrow> a =\<^sub>A z"
proof (rule Equal_elim[where ?x=a and ?y=a])
fix u assume 2: "u: A"
show "\<^bold>\<lambda>z q. ind\<^sub>= refl q: \<Prod>z:A. u =\<^sub>A z \<rightarrow> u =\<^sub>A z"
proof
fix z assume 3: "z: A"
show "\<^bold>\<lambda>q. ind\<^sub>= refl q: u =\<^sub>A z \<rightarrow> u =\<^sub>A z"
proof
show "\<And>q. q: u =\<^sub>A z \<Longrightarrow> ind\<^sub>= refl q: u =\<^sub>A z"
by (rule Equal_elim[where ?x=u and ?y=z]) (routine lems: assms 2 3)
qed (routine lems: assms 2 3)
qed fact
qed (routine lems: assms 1)
next show "(ind\<^sub>=(\<lambda>_. \<^bold>\<lambda>z q. ind\<^sub>= refl q)(refl a))`a`(refl a) \<equiv> refl a"
proof compute
fix u assume 1: "u: A"
show "\<^bold>\<lambda>z q. ind\<^sub>= refl q: \<Prod>z:A. u =\<^sub>A z \<rightarrow> u =\<^sub>A z"
proof
fix z assume 2: "z: A"
show "\<^bold>\<lambda>q. ind\<^sub>= refl q: u =\<^sub>A z \<rightarrow> u =\<^sub>A z"
proof
show "\<And>q. q: u =\<^sub>A z \<Longrightarrow> ind\<^sub>= refl q: u =\<^sub>A z"
by (rule Equal_elim[where ?x=u and ?y=z]) (routine lems: assms 1 2)
qed (routine lems: assms 1 2)
qed fact
next show "(\<^bold>\<lambda>z q. ind\<^sub>= refl q)`a`(refl a) \<equiv> refl a"
proof compute
fix a assume 1: "a: A"
show "\<^bold>\<lambda>q. ind\<^sub>= refl q: a =\<^sub>A a \<rightarrow> a =\<^sub>A a"
proof
show "\<And>q. q: a =\<^sub>A a \<Longrightarrow> ind\<^sub>= refl q: a =\<^sub>A a"
by (rule Equal_elim[where ?x=a and ?y=a]) (routine lems: assms 1)
qed (routine lems: assms 1)
next show "(\<^bold>\<lambda>q. ind\<^sub>= refl q)`(refl a) \<equiv> refl a"
proof compute
show "\<And>p. p: a =\<^sub>A a \<Longrightarrow> ind\<^sub>= refl p: a =\<^sub>A a"
by (rule Equal_elim[where ?x=a and ?y=a]) (routine lems: assms)
show "ind\<^sub>= refl (refl a) \<equiv> refl a"
proof compute
show "\<And>x. x: A \<Longrightarrow> refl(x): x =\<^sub>A x" ..
qed (routine lems: assms)
qed (routine lems: assms)
qed fact
qed (routine lems: assms)
qed (routine lems: assms)
qed fact
qed fact
text "The raw object lambda term is cumbersome to use, so we define a simpler constant instead."
axiomatization pathcomp :: "[Term, Term] \<Rightarrow> Term" (infixl "\<bullet>" 120) where
pathcomp_def: "\<lbrakk>
A: U i;
x: A; y: A; z: A;
p: x =\<^sub>A y; q: y =\<^sub>A z
\<rbrakk> \<Longrightarrow> p \<bullet> q \<equiv> rpathcomp`x`y`p`z`q"
lemma pathcomp_type:
assumes "A: U i" "x: A" "y: A" "z: A" "p: x =\<^sub>A y" "q: y =\<^sub>A z"
shows "p \<bullet> q: x =\<^sub>A z"
proof (subst pathcomp_def)
show "A: U i" "x: A" "y: A" "z: A" "p: x =\<^sub>A y" "q: y =\<^sub>A z" by fact+
qed (routine lems: assms rpathcomp_type)
lemma pathcomp_comp:
assumes "A : U i" and "a : A" shows "(refl a) \<bullet> (refl a) \<equiv> refl a"
by (subst pathcomp_def) (routine lems: assms rpathcomp_comp)
lemmas EqualProps_type [intro] = inv_type pathcomp_type
lemmas EqualProps_comp [comp] = inv_comp pathcomp_comp
section \<open>Higher groupoid structure of types\<close>
lemma
assumes "A: U i" "x: A" "y: A" "p: x =\<^sub>A y"
shows
"ind\<^sub>= (\<lambda>u. refl (refl u)) p: p =[x =\<^sub>A y] p \<bullet> (refl y)" and
"ind\<^sub>= (\<lambda>u. refl (refl u)) p: p =[x =\<^sub>A y] (refl x) \<bullet> p"
proof -
show "ind\<^sub>= (\<lambda>u. refl (refl u)) p: p =[x =[A] y] p \<bullet> (refl y)"
by (rule Equal_elim[where ?p=p and ?x=x and ?y=y]) (derive lems: assms)+
show "ind\<^sub>= (\<lambda>u. refl (refl u)) p: p =[x =[A] y] (refl x) \<bullet> p"
by (rule Equal_elim[where ?p=p and ?x=x and ?y=y]) (derive lems: assms)+
qed
lemma
assumes "A: U i" "x: A" "y: A" "p: x =\<^sub>A y"
shows
"ind\<^sub>= (\<lambda>u. refl (refl u)) p: p\<inverse> \<bullet> p =[y =\<^sub>A y] (refl y)" and
"ind\<^sub>= (\<lambda>u. refl (refl u)) p: p \<bullet> p\<inverse> =[x =\<^sub>A x] (refl x)"
proof -
show "ind\<^sub>= (\<lambda>u. refl (refl u)) p: p\<inverse> \<bullet> p =[y =\<^sub>A y] (refl y)"
by (rule Equal_elim[where ?p=p and ?x=x and ?y=y]) (derive lems: assms)+
show "ind\<^sub>= (\<lambda>u. refl (refl u)) p: p \<bullet> p\<inverse> =[x =\<^sub>A x] (refl x)"
by (rule Equal_elim[where ?p=p and ?x=x and ?y=y]) (derive lems: assms)+
qed
lemma
assumes "A: U i" "x: A" "y: A" "p: x =\<^sub>A y"
shows "ind\<^sub>= (\<lambda>u. refl (refl u)) p: p\<inverse>\<inverse> =[x =\<^sub>A y] p"
by (rule Equal_elim[where ?p=p and ?x=x and ?y=y]) (derive lems: assms)
text "Next we construct a proof term of associativity of path composition."
schematic_goal
assumes
"A: U i"
"x: A" "y: A" "z: A" "w: A"
"p: x =\<^sub>A y" "q: y =\<^sub>A z" "r: z =\<^sub>A w"
shows
"?a: p \<bullet> (q \<bullet> r) =[x =\<^sub>A z] (p \<bullet> q) \<bullet> r"
apply (rule Equal_elim[where ?p=p and ?x=x and ?y=y])
apply (rule assms)+
\<comment> \<open>Continue by substituting \<open>refl x \<bullet> q = q\<close> etc.\<close>
sorry
section \<open>Transport\<close>
definition transport :: "Term \<Rightarrow> Term" where
"transport p \<equiv> ind\<^sub>= (\<lambda>x. (\<^bold>\<lambda>x. x)) p"
text "Note that \<open>transport\<close> is a polymorphic function in our formulation."
lemma transport_type:
assumes
"A: U i" "P: A \<longrightarrow> U i"
"x: A" "y: A"
"p: x =\<^sub>A y"
shows "transport p: P x \<rightarrow> P y"
unfolding transport_def
by (rule Equal_elim[where ?p=p and ?x=x and ?y=y]) (routine lems: assms)
lemma transport_comp:
assumes "A: U i" and "x: A"
shows "transport (refl x) \<equiv> id"
unfolding transport_def by (derive lems: assms)
end
|