簡體   English   中英

Agda類型檢查和+的交換/相關性

[英]Agda Type-Checking and Commutativity / Associativity of +

由於Nat_+_ -Operation通常是在第一個參數中遞歸定義的,因此對於類型檢查器而言,知道i + 0 == i顯然是非常重要的。 但是,當我在固定大小的向量上編寫函數時,我經常遇到這個問題。

一個例子:我如何定義Agda函數

swap : {A : Set}{m n : Nat} -> Vec A (n + m) -> Vec A (m + n)

它將前n值放在向量的末尾?

因為Haskell中的簡單解決方案是

swap 0 xs     = xs
swap n (x:xs) = swap (n-1) (xs ++ [x])

我在Agda中類似地嘗試過這樣的:

swap : {A : Set}{m n : Nat} -> Vec A (n + m) -> Vec A (m + n)    
swap {_} {_} {zero} xs          = xs 
swap {_} {_} {suc i} (x :: xs)  = swap {_} {_} {i} (xs ++ (x :: []))

但是類型檢查器失敗並顯示消息(與上面的swap -Definition中的{zero} -case相關):

.m != .m + zero of type Nat
when checking that the expression xs has type Vec .A (.m + zero)

所以,我的問題:如何教Agda, m == m + zero 以及如何在Agda中編寫這樣的swap函數?

教授m == m + zero Agda並不太難。 例如,使用標准類型進行相等證明,我們可以編寫此證明:

rightIdentity : (n : Nat) -> n + 0 == n
rightIdentity zero = refl
rightIdentity (suc n) = cong suc (rightIdentity n)

然后,我們可以使用rewrite關鍵字告訴Agda使用此證明:

swap : {A : Set} {m n : Nat} -> Vec A (n + m) -> Vec A (m + n)    
swap {_} {m} {zero} xs rewrite rightIdentity m = xs 
swap {_} {_} {suc i} (x :: xs) = ?

但是,為第二個等式提供必要的證明要困難得多。 一般來說,嘗試使計算結構與類型結構相匹配是一個更好的主意。 這樣,你可以通過很少的定理證明(或在這種情況下沒有)。

例如,假設我們有

drop : {A : Set} {m : Nat} -> (n : Nat) -> Vec A (n + m) -> Vec A m
take : {A : Set} {m : Nat} -> (n : Nat) -> Vec A (n + m) -> Vec A n

(兩者都可以在沒有任何定理證明的情況下定義),Agda很樂意接受這個定義而不用大驚小怪:

swap : {A : Set} {m n : Nat} -> Vec A (n + m) -> Vec A (m + n)
swap {_} {_} {n} xs = drop n xs ++ take n xs

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM