9

我试图在 Agda 中证明一个简单的引理,我认为这是正确的。

如果一个向量有两个以上的元素,则取其head后取与立即init取其相同head

我将其制定如下:

lem-headInit : ∀{l} (xs : Vec ℕ (suc (suc l)))
                    -> head (init xs) ≡ head xs
lem-headInit (x ∷ xs) = ?

这给了我;

.l : ℕ
x  : ℕ
xs : Vec ℕ (suc .l)
------------------------------
Goal: head (init (x ∷ xs) | (initLast (x ∷ xs) | initLast xs)) ≡ x

作为回应。

我不完全了解如何阅读该(init (x ∷ xs) | (initLast (x ∷ xs) | initLast xs))组件。我想我的问题是;是否可能,该术语的含义和含义。

非常感谢。

4

2 回答 2

9

我不完全了解如何阅读该(init (x ∷ xs) | (initLast (x ∷ xs) | initLast xs))组件。我想我的问题是;是否可能,该术语的含义和含义。

这告诉您该值init (x ∷ xs)取决于 . 右侧所有内容的值|。当您在 Agda 中的函数中证明某些内容时,您的证明必须具有原始定义的结构。

在这种情况下,您必须对结果进行判断,initLast因为 的定义initLast在产生任何结果之前会执行此操作。

init : ∀ {a n} {A : Set a} → Vec A (1 + n) → Vec A n
init xs         with initLast xs
                --  ⇧  The first thing this definition does is case on this value
init .(ys ∷ʳ y) | (ys , y , refl) = ys

所以这就是我们如何写引理。

module inithead where

open import Data.Nat
open import Data.Product
open import Data.Vec
open import Relation.Binary.PropositionalEquality

lem-headInit : {A : Set} {n : ℕ} (xs : Vec A (2 + n))
             → head (init xs) ≡ head xs

lem-headInit (x ∷ xs) with initLast xs
lem-headInit (x ∷ .(ys ∷ʳ y)) | ys , y , refl = refl

我冒昧地将您的引理概括为,Vec A因为引理不依赖于向量的内容。

于 2010-11-07T22:26:29.673 回答
3

行。我通过作弊得到了这个,我希望有人有更好的解决方案。我抛弃了你从init定义中获得的所有额外信息,initLast并创建了我自己的幼稚版本。

initLazy : ∀{A l} → Vec A (suc l) → Vec A l
initLazy (x ∷ []) = []
initLazy (x ∷ (y ∷ ys)) = x ∷ (initLazy (y ∷ ys))

现在引理是微不足道的。

还有其他优惠吗?

于 2010-08-11T16:20:42.353 回答