gpt4 book ai didi

agda - 为什么下面的 Agda 代码不会进行类型检查?

转载 作者:行者123 更新时间:2023-12-04 07:21:07 26 4
gpt4 key购买 nike

我是 Agda 的新手,对此感到困惑。

open import Data.Vec
open import Data.Nat
open import Data.Nat.DivMod
open import Data.Fin hiding (_+_ ; splitAt)
open import Data.Product
open import Relation.Binary.PropositionalEquality

difference : ∀ m (n : Fin m) → ∃ λ o → m ≡ toℕ n + o
difference zero ()
difference (suc m) zero = suc m , refl
difference (suc m) (suc n) with difference m n
difference (suc m) (suc n) | o , p1 = o , cong suc p1

takeFin : ∀ {A : Set} {m : ℕ} (n : Fin m) → Vec A m → Vec A (toℕ n)
takeFin {A} {m = m} n vec with difference m n
... | o , p rewrite p with splitAt (toℕ n) vec
... | xs , _ , _ = xs
takeFin 函数给出了错误信息:
m != lhs 类型 ℕ
检查类型时
{m : ℕ} (n : Fin m) (o : ℕ) (p : m ≡ to ℕ n + o) (lhs : ℕ) →
lhs ≡ toℕ n + o → {A : Set} (vec : Vec A lhs) → Vec A (toℕ n)
生成的 with 函数是良构的
但以下函数确实可以编译
takeFin' : ∀ {A : Set} {m : ℕ} (n : Fin m) → Vec A m → Vec A m
takeFin' {A} {m = m} n a vec with difference m n
... | o , p rewrite p with splitAt (toℕ n) vec
... | xs , ys , _ = xs ++ ys

takeFin'' : ∀ {A : Set} {m : ℕ} (n : Fin m) → A → Vec A m → Vec A (toℕ n)
takeFin'' {A} {m = m} n a vec = replicate a
谁能帮我吗?

最佳答案

正如 Agda 新用户倾向于做的那样,您确实使事情变得比您需要的要复杂得多。您打算证明的实际上可以以更简单的方式完成,如下所示:

open import Data.Vec
open import Data.Fin

takeFin : ∀ {a} {A : Set a} {m} {n : Fin m} → Vec A m → Vec A (toℕ n)
takeFin {n = zero} (x ∷ v) = []
takeFin {n = suc _} (x ∷ v) = x ∷ takeFin v
您应该始终尝试编写简单的归纳证明,而不是使用不必要的中间引理。
至于为什么您的版本不进行类型检查(不是编译,而是类型检查),原因在于您的重写调用是在 m ≡ toℕ n + o 的元素上进行的。而您的目标类型是 Vec A (toℕ n)并且不包含任何出现的 m .你想要做的是转换 vec 的类型在您的上下文中,而 rewrite只对目标采取行动。这是我将如何使其工作:
takeFin : ∀ {A : Set} {m} {n : Fin m} → Vec A m → Vec A (toℕ n)
takeFin {m = m} {n} vec with difference m n
... | _ , p = proj₁ (splitAt (toℕ n) (subst (Vec _) p vec))
它可以工作,但正如您所见,它远没有那么优雅(并且它还需要您定义的 difference 函数),更重要的是,它使用了 subst这通常是不鼓励的。
作为旁注,主要是为了好玩,可以使函数更加简洁和优雅(但不太容易理解),如下所示:
open import Function

takeFin : ∀ {A : Set} {m} {n : Fin m} → Vec A m → Vec A (toℕ n)
takeFin {n = n} = proj₁ ∘ (splitAt (toℕ n)) ∘ (subst (Vec _) (proj₂ (difference _ n)))
这个版本虽然读起来复杂得多,但展示了 Agda 在推断参数值方面的强大功能,只有 n是明确给出的。

关于agda - 为什么下面的 Agda 代码不会进行类型检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68492964/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com