« Home

Dependent equality in dependent type theory [ag-000C]

這是從 https://mathstodon.xyz/@MartinEscardo/114751426538568913 學到的技巧。

{-# OPTIONS --safe --without-K #-}
module ag-000C where

open import Agda.Primitive
  renaming (Set to Type; Setω to Typeω)
open import Agda.Builtin.Equality
open import Agda.Builtin.Nat

假設我們有

  1. a type X : Type
  2. a family of types A : X → Type indexed by X

那我們常常會遇到有

  1. x y : X
  2. a : A x
  3. b : A y
  4. p : x = y

是 MLTT 的 identity type,p 是一個 x = y 的證明,這時候如果我們問 a = b 是沒有答案的,因為根據 MLTT,ab 的類型壓根兒就不一樣,這導致問題連寫都寫不下來,那怎麼辦?

方法是定義高階等式(又稱為 dependent equality 或是 PathOver 或是 path transport),在該依賴項等價的情況下把問題變成新的等式來讓 dependent type 語言表達等式

用案例來說就是如果有個 equality 是「類型不同」的(出於依賴項的不透明性,比如這裡 vector length 輸入的 associative 不同)

先定義一些下面案例會用到的輔助程式:

cong : {X Y : Type} (f : X  Y) {x₀ x₁ : X}  x₀  x₁  f x₀  f x₁
cong {X} {Y} f refl = refl

+-assoc :  l m n  (l + m) + n  l + (m + n)
+-assoc zero     m n = refl
+-assoc (suc l) m n = cong suc (+-assoc l m n)

具體案例 vector ++ 的 associativity

data Vec (A : Type) : Nat  Type where
  [] : Vec A 0
  _::_ : ∀{n}  A  Vec A n  Vec A (suc n)
infixl 40 _::_

_++_ : {Y : Type} {l m : Nat}  (xs : Vec Y l)  (ys : Vec Y m)  Vec Y (l + m)
[]        ++ ys = ys
(x :: xs) ++ ys = x :: (xs ++ ys)
infixl 30 _++_

基於 x₀ ≡ x₁ 定義一個更高階的 equality

higher-equality : {X : Type} (A : X  Type) {x₀ x₁ : X}  A x₀  x₀  x₁  A x₁  Type
higher-equality A a₀ refl a₁ = a₀  a₁

但可以根據案例定義比較簡單的版本

_≡[_]_ : {X : Type} {x₀ x₁ : Nat}  Vec X x₀  x₀  x₁  Vec X x₁  Type
a₀ ≡[ refl ] a₁ = a₀  a₁

命題 (xs ++ ys) ++ zs ≡ xs ++ (ys ++ zs) 無法寫下,因為(meta-level 的)型別不同。 所以需要用高階等式描述

cong-cons : {X : Type} {m n : Nat} {xs : Vec X m} {ys : Vec X n}
  (x : X) (p : m  n)
   xs ≡[ p ] ys  x :: xs ≡[ cong suc p ] x :: ys
cong-cons {X}{A} x refl refl = refl

++-assoc : {X : Type} (l m n : Nat)
  (xs : Vec X l) (ys : Vec X m) (zs : Vec X n)
   (xs ++ ys) ++ zs ≡[ +-assoc l m n ] xs ++ (ys ++ zs)
++-assoc {X} zero     m n []       ys zs = refl
++-assoc {X} (suc l) m n (x :: xs) ys zs = I
  where
  I : x :: (xs ++ ys) ++ zs ≡[ cong suc (+-assoc l m n) ] x :: (xs ++ (ys ++ zs))
  I = cong-cons x (+-assoc l m n) (++-assoc l m n xs ys zs)