在Idris中替换等式证明中的子表达式

时间:2016-12-17 13:44:43

标签: dependent-type idris theorem-proving

作为伊德里斯的一项练习,我试图证明这个属性:

multCancel : (a:Nat) -> (b:Nat) -> (c:Nat) -> (S a) * b = (S a) * c -> b = c

我得出的结论是,作为一个非常规的步骤,我需要证明这样的事情:

lemma1 : {x:Nat} -> {y:Nat} -> {z:Nat} -> (x + x) + (x * z) = (y + y) + (y * z) -> (x * (S (S z))) = (y * (S (S z)))
lemma1 {x=x} {y=y} {z=z} prf = ?todo

当然,我已经证明了这一点:

plusDouble : (a:Nat) -> (a + a) = a*2
plusDouble a =
  rewrite multCommutative a 2 in
  rewrite plusZeroRightNeutral a in Refl

所以我相信我基本上只需要用(x + x)替换(x*2),然后调用分配来证明lemma1。我不知道怎么做这个替换。 我以为我可以简单地做一些像

这样的事情
rewrite plusDouble x in ...

但这显然不起作用,因为我要替换的子表达式位于prf并且位于目标中。

对此有一些通用的方法吗?或者在这种特殊情况下你会推荐什么?

2 个答案:

答案 0 :(得分:1)

重写功能使用引擎盖下的replace : (x = y) -> P x -> P y;它正在弄清P应该是什么(据我所知)。

要将x + x替换为x*2,您可以使用等同x + x = x*2。要将x*2替换为x + x,您可以使用等式x*2 = x + x;在你的情况下是sym prf。您需要两个替换才能实现这两个目标。

当重写工具(或推理)无法弄清楚时,您可以明确提供P,例如replace {P = \x' => x' + (x * z) = (y + y) + (y * z)} (plusDouble x) prf。当您需要重写某些x + x但不是全部的网站时,此功能特别有用。

答案 1 :(得分:0)

好的,所以我发现我不必总是使用重写规则来简化目标,但我可以扩展它以匹配我作为参数获得的证据。