根据(进一步)证明证明类型相等
Proving equality of types depending on (further) proofs
假设我们想在 Nat
上有一个 "proper" minus
,需要 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
也可以),但看起来不可能同时重写和更改证明对象以便它匹配重写。
我该如何解决这个问题?或者,更一般地说,我如何证明这个引理?
好的,我想我已经解决了。底线:如果您不知道该怎么做,请做一个引理!
所以我们有两个被减数 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
假设我们想在 Nat
上有一个 "proper" minus
,需要 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
也可以),但看起来不可能同时重写和更改证明对象以便它匹配重写。
我该如何解决这个问题?或者,更一般地说,我如何证明这个引理?
好的,我想我已经解决了。底线:如果您不知道该怎么做,请做一个引理!
所以我们有两个被减数 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