我试图在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))
作为回应。
我不完全了解如何阅读{{1}}组件。我想我的问题是;是否可能,该术语的含义和含义是什么。
非常感谢。
答案 0 :(得分:8)
我不完全明白怎么做 阅读
(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
,因为引理不依赖于向量的内容。
答案 1 :(得分:3)
确定。我通过作弊得到了这个,我希望有人有更好的解决方案。我放弃了从init
定义的initLast
获得的所有额外信息,并创建了我自己的天真版本。
initLazy : ∀{A l} → Vec A (suc l) → Vec A l
initLazy (x ∷ []) = []
initLazy (x ∷ (y ∷ ys)) = x ∷ (initLazy (y ∷ ys))
现在这个引理很简单。
还有其他优惠吗?