在 Idris 中,如何从 So 类型中提取证明?

In Idris, how do I extract a proof from a So type?

如果我有一个 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)

您似乎无法从布尔值中提取证据。 So 是弱类型。它应该仅用于保证运行时某些检查的性能。另请参阅此问题:

我不确定这不可能。但是我试图证明 ltNeNat 并且惨败。虽然,也许我只是愚蠢。考虑使用一些证据而不是 So,例如 ReflSo 上的模式匹配不会为您提供更多帮助证明事物的能力。您可以在 this tutorial 下找到 So 的有效用例。即使你能够从 So 中提取证据,它也需要你编写大量代码并且处理 So 不太方便。

你可以在 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 中编码的信息。