【发布时间】:2019-02-27 19:51:37
【问题描述】:
假设我们想在Nats 上有一个“正确的”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 也可以),但看起来不可能同时重写和更改证明对象以使其与重写匹配。
我该如何解决这个问题?或者,更一般地说,我如何证明这个引理?
【问题讨论】:
-
也许您可以将您的证明包含在
plusTossS中,以便人们可以更好地重现您的代码。 -
你可能需要对证明做一些智能的事情:``` minusPlusTossS n m Z {prf1 = LTEZero} {prf2 = LTEZero} = let tossPrf = plusTossS n m in rewrite tossPrf in Refl ``` typechecks ,但不是全部。
-
@Markus 我猜这是因为类型检查器无法将
k `LTE` n + S m与LTESucc的可用表单相匹配。当然,我们可以将该证明重写为k `LTE` S (n + m),但这对我来说并不是特别有成果。
标签: idris dependent-type