我正试图从chapter 7 of "theorem proving in lean"了解归纳类型。
我为自己设定了一个任务,证明自然数的继承者有平等的替代属性:
inductive natural : Type
| zero : natural
| succ : natural -> natural
lemma succ_over_equality (a b : natural) (H : a = b) :
(natural.succ a) = (natural.succ b) := sorry
经过一些猜测和相当详尽的搜索后,我能够满足编译器的几种可能性:
lemma succ_over_equality (a b : natural) (H : a = b) :
(natural.succ a) = (natural.succ b) :=
eq.rec_on H (eq.refl (natural.succ a))
--eq.rec_on H rfl
--eq.subst H rfl
--eq.subst H (eq.refl (natural.succ a))
--congr_arg (λ (n : natural), (natural.succ n)) H
我不明白我刚给出的任何证据是如何实际工作的。
eq
(归纳型)的完整定义是什么?在VSCode中,我可以看到eq
的类型签名为eq Π {α : Type} α → α → Prop
,但我看不到单个(归纳)构造函数(来自{{1}的zero
和succ
的类似物}})。我在源代码doesn't look quite right中找到的最好的。natural
乐意接受eq.subst
提供(natural.succ a) = (natural.succ a)
证明的证明?(natural.succ a) = (natural.succ b)
时遇到的错误是什么意思,#check (eq.rec_on H (eq.refl (natural.succ a)))
答案 0 :(得分:5)
eq
defined为
inductive eq {α : Sort u} (a : α) : α → Prop
| refl : eq a
这个想法是任何一个术语都等于它自己,两个术语相等的唯一方法就是它们是同一个术语。这可能感觉像是一点ITT魔术。美丽来自于此定义的自动生成的recursor:
eq.rec : Π {α : Sort u_2} {a : α} {C : α → Sort u_1}, C a → Π {a_1 : α}, a = a_1 → C a_1
这是平等的替代原则。 “如果C持有a,a = a_1,则C持有a_1。” (如果C是类型值而不是支持值,则有类似的解释。)
eq.subst
正在提供a = b
的证明以及succ a = succ a
的证明。请注意,eq.subst
基本上是上述eq.rec
的重新制定。假设在变量x上参数化的属性C
是succ a = succ x
。 C
通过反身性保留a
,自a = b
以来,我们C
持有b
。
当你写eq.subst H rfl
时,精益需要弄清楚属性(或“动机”)C
应该是什么。这是高阶统一的一个例子:未知变量需要与lambda表达式统一。我在https://leanprover.github.io/theorem_proving_in_lean/theorem_proving_in_lean.pdf的第6.10节和https://en.wikipedia.org/wiki/Unification_(computer_science)#Higher-order_unification的一些一般信息中对此进行了讨论。
您要求精益将a = b
替换为succ a = succ a
,而不告诉它您要证明的内容。你可能试图证明succ b = succ b
,succ b = succ a
,甚至succ a = succ a
(通过替换无处)。精益无法推断出动机C
,除非它有这方面的信息。
一般而言,“手动”(使用eq.rec
,subst
等)进行替换很困难,因为高阶统一是挑剔且昂贵的。您经常会发现使用rw
(重写)等策略更好:
lemma succ_over_equality (a b : natural) (H : a = b) :
(natural.succ a) = (natural.succ b) := by rw H
如果你想要聪明,你可以使用精益方程式编译器,以及a=b
的“唯一”证明是rfl
的事实:
lemma succ_over_equality : Π (a b : natural),
a = b → (natural.succ a) = (natural.succ b)
| ._ _ rfl := rfl