Functional programming 如何在Agda中用N的归纳原理证明N的递归器的定义方程命题成立?

Functional programming 如何在Agda中用N的归纳原理证明N的递归器的定义方程命题成立?,functional-programming,agda,dependent-type,type-theory,homotopy-type-theory,Functional Programming,Agda,Dependent Type,Type Theory,Homotopy Type Theory,这是本书中的练习。以下是我所拥有的: data ℕ : Set where zero : ℕ succ : ℕ → ℕ iter : {C : Set} → C → (C → C) → ℕ → C iter z f zero = z iter z f (succ n) = f (iter z f n) succℕ : {C : Set} → (ℕ → C → C) → ℕ × C → ℕ × C succℕ f (n , x) = (succ n , f n x)

这是本书中的练习。以下是我所拥有的:

data ℕ : Set where
    zero : ℕ
    succ : ℕ → ℕ

iter : {C : Set} → C → (C → C) → ℕ → C
iter z f  zero    = z
iter z f (succ n) = f (iter z f n)

succℕ : {C : Set} → (ℕ → C → C) → ℕ × C → ℕ × C
succℕ f (n , x) = (succ n , f n x)

iterℕ : {C : Set} → C → (ℕ → C → C) → ℕ → ℕ × C
iterℕ z f = iter (zero , z) (succℕ f)

recℕ : {C : Set} → C → (ℕ → C → C) → ℕ → C
recℕ z f = _×_.proj₂ ∘ iterℕ z f

indℕ : {C : ℕ → Set} → C zero → ((n : ℕ) → C n → C (succ n)) → (n : ℕ) → C n
indℕ z f  zero    = z
indℕ z f (succ n) = f n (indℕ z f n)

recℕzfzero≡z : {C : Set} {z : C} {f : ℕ → C → C} → recℕ z f zero ≡ z
recℕzfzero≡z = refl

recℕzfsuccn≡fnrecℕzfn : {C : Set} {z : C} {f : ℕ → C → C} (n : ℕ) →
                        recℕ z f (succ n) ≡ f n (recℕ z f n)
recℕzfsuccn≡fnrecℕzfn = indℕ refl ?
我不知道如何证明这一点ℕ z f(成功)≡ f n(记录ℕ z f n)。我需要证明:

(n : ℕ) → recℕ z f (succ n) ≡ f n (recℕ z f n)
        → recℕ z f (succ (succ n)) ≡ f (succ n) (recℕ z f (succ n))
在英语中,给定一个自然数
n
,归纳假设证明了结果

中缀运算符
_∘_是正常的函数组合。
_≡_
\uxx0
数据类型定义为:

data _≡_ {A : Set} : A → A → Set where
    refl : {x : A} → x ≡ x

record _×_ (A B : Set) : Set where
    constructor _,_
    field
        _×_.proj₁ : A
        _×_.proj₂ : B

我一直在考虑一个解决方案,但我不知道如何解决这个问题。

让我们从Agda mode for emacs获得一些帮助:

recℕzfsuccn≡fnrecℕzfn : {C : Set} {z : C} {f : ℕ → C → C} (n : ℕ) →
                        recℕ z f (succ n) ≡ f n (recℕ z f n)
recℕzfsuccn≡fnrecℕzfn {f = f} n = {!!}
如果我们通过键入
C-u C-u C-C-,
(每次我都觉得我在尝试调用《致命快击》中的死亡),来规范化洞中的上下文,我们会看到(我稍微整理了一下你的定义)

f
的第二个参数两边相等,因此我们可以编写

recℕzfsuccn≡fnrecℕzfn {f = f} n = cong (λ m -> f m (recℕ _ f n)) {!!}
在哪里

现在的目标是

Goal: proj₁ (iter (zero , .z) (succℕ f) n) ≡ n
这是一个简单的引理

lem : {C : Set} {z : C} {f : ℕ → C → C} (n : ℕ)
    → proj₁ (iter (zero , z) (succℕ f) n) ≡ n
lem = indℕ refl (λ _ -> cong succ)
所以


.

让我们从Agda模式中获得一些有关emacs的帮助:

recℕzfsuccn≡fnrecℕzfn : {C : Set} {z : C} {f : ℕ → C → C} (n : ℕ) →
                        recℕ z f (succ n) ≡ f n (recℕ z f n)
recℕzfsuccn≡fnrecℕzfn {f = f} n = {!!}
如果我们通过键入
C-u C-u C-C-,
(每次我都觉得我在尝试调用《致命快击》中的死亡),来规范化洞中的上下文,我们会看到(我稍微整理了一下你的定义)

f
的第二个参数两边相等,因此我们可以编写

recℕzfsuccn≡fnrecℕzfn {f = f} n = cong (λ m -> f m (recℕ _ f n)) {!!}
在哪里

现在的目标是

Goal: proj₁ (iter (zero , .z) (succℕ f) n) ≡ n
这是一个简单的引理

lem : {C : Set} {z : C} {f : ℕ → C → C} (n : ℕ)
    → proj₁ (iter (zero , z) (succℕ f) n) ≡ n
lem = indℕ refl (λ _ -> cong succ)
所以


.

为什么您需要iter的复杂设置ℕ
成功ℕ?如果您定义
recℕ直接以
ind表示ℕ,这些方程立即可以引用。@AndrásKovács这实际上是本书中的一个练习。是的,我可以定义
recℕ直接以
ind表示ℕrecℕ
仅使用
iter
,然后使用
ind证明其定义方程符合命题ℕ。为什么需要使用
iter进行复杂的设置ℕ
成功ℕ?如果您定义
recℕ直接以
ind表示ℕ,这些方程立即可以引用。@AndrásKovács这实际上是本书中的一个练习。是的,我可以定义
recℕ直接以
ind表示ℕrecℕ
仅使用
iter
,然后使用
ind证明其定义方程符合命题ℕ
。为什么我以前没有想到使用
cong
?这太明显了。谢谢。我以前为什么没想到用
cong
?这太明显了。非常感谢。