我想证明,我的想法是一个合理的定理:
theorem1 : (n : Nat) -> (m : Nat) -> (n + (m - n)) = m
通过归纳证明到了我需要证明这一点:
lemma1 : (n : Nat) -> (n - 0) = n
当我尝试使用交互式证明器证明它(引理,为简单起见)时会发生这种情况:
---------- Goal: ----------
{hole0} : (n : Nat) -> minus n 0 = n
> intros
---------- Other goals: ----------
{hole0}
---------- Assumptions: ----------
n : Nat
---------- Goal: ----------
{hole1} : minus n 0 = n
> trivial
Can't unify
n = n
with
minus n 0 = n
Specifically:
Can't unify
n
with
minus n 0
我觉得我必须遗漏一些关于减号的定义,所以我在源头查了一下:
||| Subtract natural numbers. If the second number is larger than the first, return 0.
total minus : Nat -> Nat -> Nat
minus Z right = Z
minus left Z = left
minus (S left) (S right) = minus left right
我需要的定义就在那里! minus left Z = left
。我的理解是,伊德里斯应该在这里用minus m 0
代替m
,然后这反过来就是真的。我错过了什么?
答案 0 :(得分:23)
不幸的是,你想在这里证明的定理实际上并不正确,因为Idris自然会将减法截断为0. theorem1
的反例是n=3, m=0
。让我们逐步完成评估:
首先,我们替换:
3 + (0 - 3) = 0
接下来,我们将语法设计为底层的Num实例,并放入被调用的实际函数:
plus (S (S (S Z))) (minus Z (S (S (S Z))))) = Z
Idris是一种严格的,按值调用的语言,因此我们首先评估函数的参数。因此,我们减少了表达式minus Z (S (S (S Z))))
。查看the definition of minus
,第一个模式适用,因为第一个参数是Z
。所以我们有:
plus (S (S (S Z))) Z = Z
plus
对其第一个参数是递归的,因此评估的下一步产生:
S (plus (S (S Z)) Z) = Z
我们继续这种方式,直到plus
获得Z
为第一个参数,此时它返回第二个参数Z
,产生类型:
S (S (S Z)) = Z
我们无法建造居民。
很抱歉,如果上面看起来有点迂腐和低级别,但在使用依赖类型时考虑特定的减少步骤非常重要。那就是你得到的计算"免费"在类型内部,所以安排它以产生方便的结果是很好的。
pdxleif的上述解决方案适用于您的引理。第一个参数的案例拆分对于使minus
中的模式匹配起作用是必要的。请记住,它在模式匹配中从上到下进行,第一个模式在第一个参数上有一个具体的构造函数,这意味着在知道该构造函数是否匹配之前,还原不能继续进行。
答案 1 :(得分:10)
只是玩弄交互式编辑,进行案例分割和证明搜索,产生:
lemma1 : (n : Nat) -> (n - 0) = n
lemma1 Z = refl
lemma1 (S k) = refl
从减号的定义可以看出这一点,这就是为什么它只是简单的反映。当输入变量只是n时,它可能会徘徊,因为它可能有不同的行为,如果它是Z或其他什么?还是递归?
答案 2 :(得分:1)
以防万一,Idris Prelude已经定义了很多算术引理,就像你的一样:
total minusZeroRight : (left : Nat) -> left - 0 = left
minusZeroRight Z = refl
minusZeroRight (S left) = refl
答案 3 :(得分:1)
为了完整性'为了清楚起见(战术语言已被弃用,有利于阐述者的反思),我将补充说,用战术语言证明你的引理的方法是调用induction n
。然后,您可以使用trivial
来显示每个案例(在归纳案例中intros
之后)。
---------- Goal: ----------
{hole0} : (n : Nat) -> minus n 0 = n
-lemma1> intros
---------- Other goals: ----------
{hole0}
---------- Assumptions: ----------
n : Nat
---------- Goal: ----------
{hole1} : minus n 0 = n
-lemma1> induction n
---------- Other goals: ----------
elim_S0,{hole1},{hole0}
---------- Assumptions: ----------
n : Nat
---------- Goal: ----------
elim_Z0 : minus 0 0 = 0
-lemma1> trivial
---------- Other goals: ----------
{hole1},{hole0}
---------- Assumptions: ----------
n : Nat
---------- Goal: ----------
elim_S0 : (n__0 : Nat) ->
(minus n__0 0 = n__0) -> minus (S n__0) 0 = S n__0
-lemma1> intros
---------- Other goals: ----------
{hole8},elim_S0,{hole1},{hole0}
---------- Assumptions: ----------
n : Nat
n__0 : Nat
ihn__0 : minus n__0 0 = n__0
---------- Goal: ----------
{hole9} : minus (S n__0) 0 = S n__0
-lemma1> trivial
lemma1: No more goals.
-lemma1> qed
Proof completed!
lemma1 = proof
intros
induction n
trivial
intros
trivial