如果您已经有b : Bool
,你可以把它变成命题:So b
,比b ≡ true
。有时(我不记得任何实际情况)不需要考虑正确的数据类型,这种快速解决方案就足够了。
So
与“适当的”相比似乎有严重的缺点
证明术语:模式匹配oh
没有给你任何信息
您可以用它进行另一个术语类型检查。作为推论,So
价值观不能有效地参与交互式证明。
将此与计算有用性进行对比Disjoint
, 哪个
表示为证明列表,其中的每一列s'
不
出现在s
.
So
确实为您提供了相同的信息Disjoint
- 你只需要提取它。基本上,如果两者之间没有不一致的话disjoint
and Disjoint
,那么你应该能够编写一个函数So (disjoint s) -> Disjoint s
使用模式匹配、递归和不可能情况消除。
然而,如果你稍微调整一下定义:
So : Bool -> Set
So true = ⊤
So false = ⊥
So
成为一种非常有用的数据类型,因为x : So true
立即减少到tt
由于 eta 规则⊤
。这允许使用So
就像一个约束:在伪 Haskell 中我们可以写
forall n. (n <=? 3) => Vec A n
and if n
是规范形式(即suc (suc (suc ... zero))
), then n <=? 3
可以由编译器检查,不需要证明。实际上 Agda 是
∀ {n} {_ : n <=? 3} -> Vec A n
我用了这个技巧this https://stackoverflow.com/a/28589398/3237465答案(这是{_ : False (m ≟ 0)}
那里)。我想编写所描述的机器的可用版本是不可能的here https://stackoverflow.com/a/31105948/3237465没有这个简单的定义:
Is-just : ∀ {α} {A : Set α} -> Maybe A -> Set
Is-just = T ∘ isJust
where T
is So
在 Agda 的标准库中。
此外,在存在实例参数的情况下So
-as-a-data-type 可以用作So
作为约束:
open import Data.Bool.Base
open import Data.Nat.Base
open import Data.Vec
data So : Bool -> Set where
oh : So true
instance
oh-instance : So true
oh-instance = oh
_<=_ : ℕ -> ℕ -> Bool
0 <= m = true
suc n <= 0 = false
suc n <= suc m = n <= m
vec : ∀ {n} {{_ : So (n <= 3)}} -> Vec ℕ n
vec = replicate 0
ok : Vec ℕ 2
ok = vec
fail : Vec ℕ 4
fail = vec