You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{` To prove that general W-types are fibrant, we need function extensionality, since W-types involve functions as inputs. `}
265
+
266
+
axiom funext (A : Type) (B : A → Type) (f0 f1 : (x : A) → B x)
267
+
(f2 : (x : A) → eq (B x) (f0 x) (f1 x))
268
+
: eq ((x : A) → B x) f0 f1
269
+
270
+
{` We also need a version of funext for bridges in function types. We could probably derive this from the ordinary one, using the definitional isomorphism behavior of Id-Π. `}
271
+
272
+
axiom funext_refl (A0 A1 : Type) (A2 : Id Type A0 A1) (B0 : A0 → Type)
273
+
(B1 : A1 → Type) (B2 : refl ((X ↦ X → Type) : Type → Type) A2 B0 B1)
{` Now, there are two ways to characterize the Id types of a W-type. The firts is that the Id-types of an (indexed) W-type are an indexed W-type, which is properly indexed even if the original W-type was not. This is not helpful for us, since indexed inductive types in general are *not* fibrant until we fibrantly replace them. However, we include the encode-decode argument here anyway. `}
280
+
281
+
section Indexed_𝕎 ≔
282
+
283
+
def 𝕎spec : Type ≔ sig (
284
+
I : Type,
285
+
A : Type,
286
+
B : A → Type,
287
+
j : (a : A) → B a → I,
288
+
k : A → I )
289
+
290
+
def 𝕎 (s : 𝕎spec) : s .I → Type ≔ data [
291
+
| sup. (a : s .A) (f : (b : s .B a) → 𝕎 s (s .j a b)) : 𝕎 s (s .k a) ]
292
+
293
+
def code_spec (s : 𝕎spec) : 𝕎spec ≔ (
294
+
I ≔ sig (
295
+
i0 : s .I,
296
+
i1 : s .I,
297
+
i2 : Id (s .I) i0 i1,
298
+
x0 : 𝕎 s i0,
299
+
x1 : 𝕎 s i1 ),
300
+
A ≔ sig (
301
+
a0 : s .A,
302
+
a1 : s .A,
303
+
a2 : Id (s .A) a0 a1,
304
+
f0 : (b0 : s .B a0) → 𝕎 s (s .j a0 b0),
305
+
f1 : (b1 : s .B a1) → 𝕎 s (s .j a1 b1) ),
306
+
B ≔ x ↦ sig (
307
+
b0 : s .B (x .a0),
308
+
b1 : s .B (x .a1),
309
+
b2 : refl (s .B) (x .a2) b0 b1 ),
310
+
j ≔ a b ↦ (
311
+
s .j (a .a0) (b .b0),
312
+
s .j (a .a1) (b .b1),
313
+
refl (s .j) (a .a2) (b .b2),
314
+
a .f0 (b .b0),
315
+
a .f1 (b .b1)),
316
+
k ≔ a ↦ (
317
+
s .k (a .a0),
318
+
s .k (a .a1),
319
+
refl (s .k) (a .a2),
320
+
sup. (a .a0) (a .f0),
321
+
sup. (a .a1) (a .f1)))
322
+
323
+
def 𝕎_encode (s : 𝕎spec) (i0 i1 : s .I) (i2 : Id (s .I) i0 i1)
324
+
(x0 : 𝕎 s i0) (x1 : 𝕎 s i1) (x2 : refl (𝕎 s) i2 x0 x1)
(𝕎_encode s i0 i1 i2 x0 x1) (𝕎_decode s (i0, i1, i2, x0, x1))
414
+
(x2 ↦ 𝕎_decode_encode s i0 i1 i2 x0 x1 x2)
415
+
(y2 ↦ 𝕎_encode_decode s (i0, i1, i2, x0, x1) y2)
416
+
417
+
end
418
+
419
+
{` The characterization of Id-types of W-types that is useful to us is recursive, analogous to that for the Id-types of ℕ above. `}
420
+
421
+
def 𝕎 (A : Type) (B : A → Type) : Type ≔ data [
422
+
| sup. (a : A) (f : B a → 𝕎 A B) ]
423
+
424
+
{` We need to characterize the *dependent* Id-types over bridges of A and B. `}
425
+
426
+
def 𝕎_code (A0 A1 : Type) (A2 : Id Type A0 A1) (B0 : A0 → Type)
427
+
(B1 : A1 → Type) (B2 : refl ((X ↦ X → Type) : Type → Type) A2 B0 B1)
428
+
(x0 : 𝕎 A0 B0) (x1 : 𝕎 A1 B1)
429
+
: Type
430
+
≔ match x0, x1 [
431
+
| sup. a0 f0, sup. a1 f1 ↦
432
+
Σ (A2 a0 a1)
433
+
(a2 ↦
434
+
(b0 : B0 a0) (b1 : B1 a1) (b2 : B2 a2 b0 b1)
435
+
→ 𝕎_code A0 A1 A2 B0 B1 B2 (f0 b0) (f1 b1))]
436
+
437
+
{` The encode-decode argument is straightforward, and only long because of the multiple applications of funext and because we lack implicit arguments. `}
438
+
439
+
def 𝕎_encode (A0 A1 : Type) (A2 : Id Type A0 A1) (B0 : A0 → Type)
440
+
(B1 : A1 → Type) (B2 : refl ((X ↦ X → Type) : Type → Type) A2 B0 B1)
{` Finally, we can prove that W-types are fibrant. Note that there are "recursive calls" to 𝕗𝕎 in *all* the clauses. I'm not exactly sure how they are justified in the cases of tr and lift, but note that they are inside matches as well. `}
575
+
576
+
def 𝕗𝕎 (A : Type) (B : A → Type) (𝕗A : isFibrant A)
0 commit comments