Agda:使用 `with` 证明 `Vec` `last`
Agda: proof about `Vec` `last` using `with`
我试图证明以下说法
vecNat : ∀ {n} (xs : Vec ℕ n) → last (xs ∷ʳ 1) ≡ 1
但我对 (x ∷ xs)
的情况感到困惑。
vecNat5 : ∀ {n} (xs : Vec ℕ n) → last (xs ∷ʳ 1) ≡ 1
vecNat5 [] = refl
vecNat5 (x ∷ xs) = {! 0!}
目标是
?0 : last ((x ∷ xs) ∷ʳ 1) ≡ 1
我首先尝试使用 begin
vecNat5 : ∀ {n} (xs : Vec ℕ n) → last (xs ∷ʳ 1) ≡ 1
vecNat5 [] = refl
vecNat5 (x ∷ xs) =
begin
last ((x ∷ xs) ∷ʳ 1)
≡⟨⟩
1
∎
但随后出现此错误:
1 !=
(last (x ∷ (xs ∷ʳ 1))
| (initLast (x ∷ (xs ∷ʳ 1)) | initLast (xs ∷ʳ 1)))
of type ℕ
when checking that the expression 1 ∎ has type
last ((x ∷ xs) ∷ʳ 1) ≡ 1
所以我查看了agda-stdlib/src/Data/Vec/Base.agda
中last
的定义
last : ∀ {n} → Vec A (1 + n) → A
last xs with initLast xs
last .(ys ∷ʳ y) | (ys , y , refl) = y
并注意到 with
子句,所以我想我会尝试使用 with
进行证明。
我还在 https://agda.readthedocs.io/en/v2.6.1.1/language/with-abstraction.html?highlight=with#generalisation 中看到了一个使用 with
.
的证明示例(涉及 filter
)
所以我想试试这个
vecNat : ∀ {n} (xs : Vec ℕ n) → last (xs ∷ʳ 1) ≡ 1
vecNat [] = refl
vecNat (x ∷ xs) with last (xs ∷ʳ 1)
... | r = {! 0!}
我的目标是:
?0 : (last (x ∷ (xs ∷ʳ 1))
| (initLast (x ∷ (xs ∷ʳ 1)) | initLast (xs ∷ʳ 1)))
≡ 1
我对如何继续前进感到困惑。还是我一开始走错了方向?
谢谢!
编辑
当我尝试时
vecNat : ∀ {n} (xs : Vec ℕ n) → last (xs ∷ʳ 1) ≡ 1
vecNat [] = refl
vecNat (x ∷ xs) with initLast (xs ∷ʳ 1)
... | (xs , x , refl) = ?
我得到:
I'm not sure if there should be a case for the constructor refl,
because I get stuck when trying to solve the following unification
problems (inferred index ≟ expected index):
xs ∷ʳ 1 ≟ xs₁ ∷ʳ 1
when checking that the pattern refl has type xs ∷ʳ 1 ≡ xs₁ ∷ʳ 1
不太清楚为什么现在有 xs₁
以及为什么不只是 xs
这是一个可能的解决方案,我将您的 1 更改为任何 a
,并使向量类型通用:
首先,一些导入:
module Vecnat where
open import Data.Nat
open import Data.Vec
open import Relation.Binary.PropositionalEquality
open import Data.Product
然后一个简单但非常重要的 属性 指出在列表的头部添加一个元素不会改变它的最后一个元素:
prop : ∀ {a} {A : Set a} {n x} (xs : Vec A (suc n)) → last (x ∷ xs) ≡ last xs
prop xs with initLast xs
... | _ , _ , refl = refl
您要找的证明终于来了:
vecNat5 : ∀ {a} {A : Set a} {l n} (xs : Vec A n) → last (xs ∷ʳ l) ≡ l
vecNat5 [] = refl
vecNat5 (_ ∷ xs) = trans (prop (xs ∷ʳ _)) (vecNat5 xs)
我试图证明以下说法
vecNat : ∀ {n} (xs : Vec ℕ n) → last (xs ∷ʳ 1) ≡ 1
但我对 (x ∷ xs)
的情况感到困惑。
vecNat5 : ∀ {n} (xs : Vec ℕ n) → last (xs ∷ʳ 1) ≡ 1
vecNat5 [] = refl
vecNat5 (x ∷ xs) = {! 0!}
目标是
?0 : last ((x ∷ xs) ∷ʳ 1) ≡ 1
我首先尝试使用 begin
vecNat5 : ∀ {n} (xs : Vec ℕ n) → last (xs ∷ʳ 1) ≡ 1
vecNat5 [] = refl
vecNat5 (x ∷ xs) =
begin
last ((x ∷ xs) ∷ʳ 1)
≡⟨⟩
1
∎
但随后出现此错误:
1 !=
(last (x ∷ (xs ∷ʳ 1))
| (initLast (x ∷ (xs ∷ʳ 1)) | initLast (xs ∷ʳ 1)))
of type ℕ
when checking that the expression 1 ∎ has type
last ((x ∷ xs) ∷ʳ 1) ≡ 1
所以我查看了agda-stdlib/src/Data/Vec/Base.agda
last
的定义
last : ∀ {n} → Vec A (1 + n) → A
last xs with initLast xs
last .(ys ∷ʳ y) | (ys , y , refl) = y
并注意到 with
子句,所以我想我会尝试使用 with
进行证明。
我还在 https://agda.readthedocs.io/en/v2.6.1.1/language/with-abstraction.html?highlight=with#generalisation 中看到了一个使用 with
.
filter
)
所以我想试试这个
vecNat : ∀ {n} (xs : Vec ℕ n) → last (xs ∷ʳ 1) ≡ 1
vecNat [] = refl
vecNat (x ∷ xs) with last (xs ∷ʳ 1)
... | r = {! 0!}
我的目标是:
?0 : (last (x ∷ (xs ∷ʳ 1))
| (initLast (x ∷ (xs ∷ʳ 1)) | initLast (xs ∷ʳ 1)))
≡ 1
我对如何继续前进感到困惑。还是我一开始走错了方向?
谢谢!
编辑
当我尝试时
vecNat : ∀ {n} (xs : Vec ℕ n) → last (xs ∷ʳ 1) ≡ 1
vecNat [] = refl
vecNat (x ∷ xs) with initLast (xs ∷ʳ 1)
... | (xs , x , refl) = ?
我得到:
I'm not sure if there should be a case for the constructor refl,
because I get stuck when trying to solve the following unification
problems (inferred index ≟ expected index):
xs ∷ʳ 1 ≟ xs₁ ∷ʳ 1
when checking that the pattern refl has type xs ∷ʳ 1 ≡ xs₁ ∷ʳ 1
不太清楚为什么现在有 xs₁
以及为什么不只是 xs
这是一个可能的解决方案,我将您的 1 更改为任何 a
,并使向量类型通用:
首先,一些导入:
module Vecnat where
open import Data.Nat
open import Data.Vec
open import Relation.Binary.PropositionalEquality
open import Data.Product
然后一个简单但非常重要的 属性 指出在列表的头部添加一个元素不会改变它的最后一个元素:
prop : ∀ {a} {A : Set a} {n x} (xs : Vec A (suc n)) → last (x ∷ xs) ≡ last xs
prop xs with initLast xs
... | _ , _ , refl = refl
您要找的证明终于来了:
vecNat5 : ∀ {a} {A : Set a} {l n} (xs : Vec A n) → last (xs ∷ʳ l) ≡ l
vecNat5 [] = refl
vecNat5 (_ ∷ xs) = trans (prop (xs ∷ʳ _)) (vecNat5 xs)