精益:hq上的eq.subst chokes :( n = 0)

时间:2017-07-29 03:40:24

标签: theorem-proving lean

使用Lean,计算机证明检查系统。

第一个证明成功,第二个证明不成功。

variables n m : nat

theorem works (h1 : n = m) (h2 : 0 < n) : (0 < m) :=
eq.subst h1 h2

theorem nowrk (h3 : n = 0) (h4 : 0 < n) : (0 < 0) :=
eq.subst h3 h4

错误发生在eq.subst中,如下所示:

"eliminator" elaborator type mismatch, term
  h4
has type
  0 < n
but is expected to have type
  n < n

[然后是一些额外的信息]

我不理解错误消息。我在假设中尝试了各种明显的排列,例如0 = n或n&gt; 0,但我无法让它工作,或者产生一个我能理解的错误信息。

任何人都可以澄清吗?我阅读了关于congr_arg等关于定理的定理的部分,但这些其他命令并没有帮助我。

2 个答案:

答案 0 :(得分:3)

eq.subst依赖于更高阶的统一来计算替换的动机,这本身就是一种启发式和一种挑剔的过程。在你的第二个案例中,精益的启发式失败了。 (您可以在错误消息中看到错误的动机。)还有其他方法可以更智能地执行此操作。

使用自动化:

theorem nowrk (h3 : n = 0) (h4 : 0 < n) : (0 < 0) :=
by simp * at * -- this may not work on 3.2.0

theorem nowrk2 (h3 : n = 0) (h4 : 0 < n) : (0 < 0) :=
by cc

使用重写:

theorem nowrk3 (h3 : n = 0) (h4 : 0 < n) : (0 < 0) :=
by rw h3 at h4; assumption

使用eq.subst并明确给出动机:

theorem nowrk4 (h3 : n = 0) (h4 : 0 < n) : (0 < 0) :=
@eq.subst _ (λ h, 0 < h) _ _ h3 h4

theorem nowrk4' (h3 : n = 0) (h4 : 0 < n) : (0 < 0) :=
@eq.subst _ ((<) 0) _ _ h3 h4 -- more concise notation for the above

使用计算模式:

theorem nowrk5 (h3 : n = 0) (h4 : 0 < n) : (0 < 0) :=
calc 0 < n : h4
   ... = 0 : h3

使用模式匹配:

theorem nowork6 : Π n, n = 0 → 0 < n → 0 < 0
| ._ rfl prf := prf

答案 1 :(得分:2)

首先,为您的函数提供有意义的名称是一种很好的编程习惯。

第一个引理可以被称为subst_ineq_rightsubst_ineq,如果从上下文中可以清楚地看到你总是在右边替换。

现在,在你的第一个引理的情况下,阐明者将合成哪个术语是明确的。如果h1类型为n = mh2类型为0 < n,则详细信息器会some complicated recursor magic代替n代替m 0 < n并根据需要生成0 < m类型的术语:

lemma subst_ineq (h1 : n = m) (h2 : 0 < n) : (0 < m) :=
    eq.subst h1 h2

不幸的是,你的第二个引理失败了,比如subst_zero_ineq

lemma subst_zero_ineq (h3 : n = 0) (h4 : 0 < n) : (0 < 0) :=
    eq.subst h3 h4

这是因为现在对于阐述者将合成的术语存在歧义。它可以替换n中的0,或0中的n替换0 < n。由于不可思议的原因,阐述者选择做后者,产生n < n类型的术语。结果不是0 < 0类型的术语,并且证明不会键入check。

消除不明确性的一种方法是在subst_ineq的证明中使用subst_zero_ineq,例如:

lemma subst_zero_ineq (h3 : n = 0) (h4 : 0 < n) : (0 < 0) :=
    subst_ineq n 0 h3 h4

typechecs正确。