如何在Agda中为`Vec`写一个安全的`length`函数?

时间:2017-11-12 18:58:08

标签: agda dependent-type

由于我们有 <form id='first'class="" method="post"> <input type="text" placeholder="what have you eaten" name="item" id="inputID" value="" class="toEat"> <button id="eat" class=consumeFood>Add food</button> </form> <ol id="eaten"> </ol> <form id="second" class="" method="post"> <input type="text" placeholder="any foods you would like to eat" name="item2"id="wantToEat" class="toEat"> <button id="possibeEat"class="consumeFood">include</button> </form> ,因此我们知道Data.Vec是什么。

我想证明Nat和Vec是同构的。

我已经成功创建了一个证明Nat可以转换为Vec的函数:

Vec

当我尝试写相应的ℕ→vec : (n : ℕ) → Vec ⊤ n ℕ→vec zero = [] ℕ→vec (suc a) = tt ∷ ℕ→vec a 时,我失败了。

我想写这样的东西(它不能编译,但它可读):

vec→ℕ

在第一个代码中,确保参数正好是返回值的长度。 但是,如何确保第一个参数的长度恰好是返回值?

3 个答案:

答案 0 :(得分:5)

我不知道,如果这是最好的解决方案,那就是我想到的。

open import Data.Vec
open import Data.Unit
open import Data.Nat
open import Data.Product

open import Relation.Binary.PropositionalEquality

vec→ℕ : ∀ {n} → Vec ⊤ n → ∃ (λ m → n ≡ m)
vec→ℕ  []      = zero , refl
vec→ℕ (tt ∷ a) with vec→ℕ a
vec→ℕ (tt ∷ a) | m , refl = suc m , refl

我没有说结果正好是n,而是引入了一个相等的顺序来指定这样的函数返回m,这样n ≡ m。希望它能帮到你。使用你的类型签名,我有一个解析错误并开发了这个。

答案 1 :(得分:5)

您可以使vec→ℕ在定义上等于长度:

vec→ℕ : ∀ {n} → Vec ⊤ n → ℕ
vec→ℕ {n} _ = n

然后我认为这对Agda来说是足够透明的,无论你需要的属性是你得到的属性是正确的,它都会自动为你提供(即通过缩减)。

编辑添加:您可能认为这是未指定的,因为vec→ℕ的类型没有规定它返回的确切 atural。但是,Agda看到了这个定义,例如,如果需要,你可以证明以下外部正确性证据(但我认为它不会增加任何价值):

open import Relation.Binary.PropositionalEquality

vec→ℕ-correct : ∀ {n} {xs : Vec ⊤ n} → vec→ℕ xs ≡ n
vec→ℕ-correct = refl

请注意,由于vec→ℕ xs在定义上等于n,因此我们无需在校样中查看nxs

答案 2 :(得分:-1)

这没有多大意义。确实,List⊤与Nat同构,但在Vec的情况下,你已经把自然数作为一个指数???