根据(更多)证明证明类型相等

时间:2019-02-27 19:51:38

标签: idris dependent-type

假设我们想在minus上使用一个“适当的” Nat,要求m <= n使n `minus` m有意义:

%hide minus

minus : (n, m : Nat) -> { auto prf : m `LTE` n } -> Nat
minus { prf = LTEZero } n Z = n
minus { prf = LTESucc prevPrf } (S n) (S m) = minus n m

现在让我们尝试证明以下引理,假设(n + (1 + m)) - k = ((1 + n) + m) - k,假设双方都是有效的:

minusPlusTossS : (n, m, k : Nat) ->
                 { auto prf1 : k `LTE` n + S m } ->
                 { auto prf2 : k `LTE` S n + m } ->
                 minus (n + S m) k = minus (S n + m) k

目标表明以下困境可能会有所帮助:

plusTossS : (n, m : Nat) -> n + S m = S n + m
plusTossS Z m = Refl
plusTossS (S n) m = cong $ plusTossS n m

所以我们尝试使用它:

minusPlusTossS n m k =
  let tossPrf = plusTossS n m
  in rewrite tossPrf in ?rhs

在这里我们失败了:

When checking right hand side of minusPlusTossS with expected type
        minus (n + S m) k = minus (S n + m) k

When checking argument prf to function Main.minus:
        Type mismatch between
                LTE k (S n + m) (Type of prf2)
        and
                LTE k replaced (Expected type)

        Specifically:
                Type mismatch between
                        S (plus n m)
                and
                        replaced

如果我正确理解此错误,则仅表示它试图将目标等式(即minus { prf = prf2 } (S n + m) k)的RHS重写为minus { prf = prf2 } (n + S m) k并失败。当然,由于prf是另一种不平等现象的证明!尽管可以使用replace来生成(S n + m) k的证明(或者prf1也可以这样做),但看起来似乎不可能同时重写和更改证明对象,因此它与重写匹配。

我该如何解决?或者,更笼统地说,我如何证明这个引理?

1 个答案:

答案 0 :(得分:2)

好的,我想我解决了。底线:如果您不知道该怎么办,请做引理!

因此,我们有两个相等的证明n1, n2是相等的,并且我们需要产生n1 `minus` m = n2 `minus` m的证明。让我们写下来吧!

minusReflLeft : { n1, n2, m : Nat } -> (prf : n1 = n2) -> (prf_n1 : m `LTE` n1) -> (prf_n2 : m `LTE` n2) -> n1 `minus` m = n2 `minus` m
minusReflLeft Refl LTEZero LTEZero = Refl
minusReflLeft Refl (LTESucc prev1) (LTESucc prev2) = minusReflLeft Refl prev1 prev2

我什至不再需要plusTossS,可以用更直接适用的引理代替它:

plusRightS : (n, m : Nat) -> n + S m = S (n + m)
plusRightS Z m = Refl
plusRightS (S n) m = cong $ plusRightS n m

在那之后,原始的变得微不足道:

minusPlusTossS : (n, m, k : Nat) ->
                 { auto prf1 : k `LTE` n + S m } ->
                 { auto prf2 : k `LTE` S n + m } ->
                 minus (n + S m) k = minus (S n + m) k
minusPlusTossS {prf1} {prf2} n m k = minusReflLeft (plusRightS n m) prf1 prf2