【发布时间】:2019-04-25 15:13:43
【问题描述】:
我试图确保在将 Coq 提取到 Haskell 时丢弃无用的Prop。但是,当我使用以下示例时,我看到 divides 和 prime 都被提取为 Haskell 空类型。这是为什么呢?
(***********)
(* isPrime *)
(***********)
Fixpoint isPrime (p : nat) : bool :=
match p with
| 0 => false
| 1 => false
| S p' => (negb (helper p p'))
end.
(***********)
(* divides *)
(***********)
Definition divides (n p : nat) : Prop :=
exists (m : nat), ((mult m n) = p).
(*********)
(* prime *)
(*********)
Definition prime (p : nat) : Prop :=
(p > 1) /\ (forall (n : nat), ((divides n p) -> ((n = 1) \/ (n = p)))).
(***************************)
(* Extract to Haskell file *)
(***************************)
Extraction "/home/oren/some_file.hs" isPrime divides prime.
这就是divides 和prime 发生的事情:
type Divides = ()
type Prime = ()
提取它们有什么用?
【问题讨论】:
-
如果将
Prop更改为Type会怎样?我认为Prop的部分观点是相同Prop的两个证明可以被视为相同(在标准库中有一个称为proof_irrelevance的公理)。这将对应于每个Prop只有一个居民(Haskell 中的()就是这种情况)。我不确定是否总是这样。我知道在像 HoTT 这样的系统中,你不一定想要证明无关紧要,但也许这是通过使用Type而不是Prop来捕获的(或者你可能只是不使用proof_irrelevance公理?)。 -
另外,我怀疑还是会有一些限制。毕竟,Coq 有一个依赖类型的类型系统,而 Haskell 没有(尽管我相信 GHC 最终会朝着这个方向发展)。
-
那些不是空类型,而是单元类型。空类型没有像
Void这样的(非底部)居民,而单元类型()作为居民,即()。 -
@chi 很棒的观察。提取器似乎可以使用
newtype Void = Void Void和type Divides = Void之类的东西。然后将undefined放在每个地方都需要Divides类型的术语。 -
@AntonTrunov 实际上,我更喜欢当前的翻译。滥用底部感觉不对。最多,我会使用
Void来翻译无人居住的类型(但这样做很难,因为我们无法决定)。