[英]`take n (take n xs) ≡ take n xs` for `Vec` in Agda
我想證明在 Agda 中為Vec
take
function 的一個幾乎微不足道的屬性。
open import Data.Vec
open import Data.Nat
open import Relation.Binary.PropositionalEquality
take-idempotent : ∀ n (xs : Vec ℕ n) → take n (take n xs) ≡ take n xs
take-idempotent n xs = ?
我的問題源於這樣一個事實,即take
的類型索引由自然數的加法組成。 Agda 將以下消息輸出到上述代碼。
n != n + _n_9 of type ℕ
when checking that the inferred type of an application
Vec _A_8 n
matches the expected type
Vec _A_8 (n + _n_9)
我可以使xs
具有類似Vec ℕ (n + 0)
的類型並應用一次,但結果的類型take
是Vec ℕ n
。 要應用take
兩次,我需要將xs
的類型設置為Vec ℕ (n + 0 + 0)
並在第一個應用程序中使用take (n + 0)
。 此外,我需要+ 0
調整才能將 lhs 和 rhs 傳遞給_≡_
,因為它們有不同數量的take
應用。
有沒有簡單的方法來 state 並證明這個命題?
這可能是一個比看起來更難的問題。 另一個欺騙性的例子:將向量反轉兩次會產生原始向量。 證明有多難? 證明列表很容易,對吧? 事實證明這很難。 查看最近對 Agda 標准庫的貢獻: https://github.com/agda/agda-stdlib/issues/942
在我(非常有限的)經驗中,很容易用鉛筆和紙證明的東西在 Agda 中證明可能更具挑戰性,因為像手頭的技術一樣。 重要的是要對在 Agda 中難以證明的內容和難以證明的內容有一個直覺,並圍繞它構建你的命題。 我認為這一點強調得不夠。
也就是說,這里有一些過去幫助我解決具有不同索引的類型的問題:
subst
- 這似乎是一個有爭議的選擇。 您很容易陷入subst
地獄,在那里您看不到所有subst
的證明。n
的向量和大小為n + 0
的向量之間陳述逐點相等(與命題相等不同)。更具體地說:
open import Data.Nat
open import Data.Nat.Properties
open import Data.Product
open import Data.Vec
open import Data.Vec.Relation.Binary.Pointwise.Inductive as PI
open import Relation.Binary.PropositionalEquality as PE
take-all₁ : ∀ n → (xs : Vec ℕ n) → (xs′ : Vec ℕ (n + 0)) → Pointwise _≡_ xs xs′ →
take n xs′ ≡ xs
take-all₁ n xs xs′ p = {!!}
take-all₂ : ∀ n (xs : Vec ℕ n) → take n (subst (Vec ℕ) (PE.sym (+-identityʳ n)) xs) ≡ xs
take-all₂ n xs = {!!}
use₁ : (xs : Vec ℕ 3) → take 3 xs ≡ xs
use₁ xs = take-all₁ 3 xs xs (PI.refl PE.refl)
use₂ : (xs : Vec ℕ 3) → take 3 xs ≡ xs
use₂ = take-all₂ 3
請注意,在use₁
和use₂
中,所有subst
和逐點的討厭都會消失,因為3
和3 + 0
都減少到3
。 (與n
和n + 0
不同。)
過去對我有用的是將兩個索引(例如i
和k
)與p: i ≡ k
一起傳遞給證明。 然后假設i
和k
對於大多數證明是不相關的,並且只在需要的地方使用p
。 但這似乎不適用於這里。
還有異質相等的概念似乎可以替代命題相等,但它允許不同的索引。 我還沒有探索過。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.