如果我有So
类型,例如So (x < y)
,则由
IsLt : Ord a => (x: a) -> (y: a) -> Type
IsLt x y = So (x < y)
如何从中提取出(x < y)
的证明?我无法在标准库中找到一个函数。
So
在标准库中定义为:
data So : Bool -> Type where
Oh : So True
而且我不确定如何从中提取证据,用于证明以下内容:
ltNeNat : {x: Nat} -> {y: Nat} -> So (x < y) -> Not (x = y)
答案 0 :(得分:3)
好像你无法从布尔值中提取证据。 So
是弱类型。它应该仅用于保证运行时某些检查的性能。另见这个问题:
我不确定这是不可能的。但是我试图证明ltNeNat
并且悲惨地失败了。虽然,也许我只是愚蠢。考虑使用一些证据而不是So
,例如Refl
。 So
上的模式匹配并没有给你更多的力量来帮助证明事情。您可以在this tutorial下找到So
的有效用例。即使您能够从So
中提取证据,也需要您提供大量代码并处理So
不太方便。
答案 1 :(得分:3)
您可以通过x
上的归纳来证明这个引理:
ltNeNat : {x: Nat} -> {y: Nat} -> So (lt x y) -> Not (x = y)
ltNeNat {x = Z} {y = Z} Oh _ impossible
ltNeNat {x = Z} {y = S _} _ Refl impossible
ltNeNat {x = S x} {y = Z} so Refl impossible
ltNeNat {x = S x} {y = S y} so eq =
let IH = ltNeNat {x} {y} so in
IH $ succInjective _ _ eq
我必须将<
替换为lt
,否则Idris无法看到So (S x < S y)
和So (x < y)
在定义上相等。
注意我在第一个和最后一个条款中使用了So
中编码的信息。