我正在试验Coq对Haskell的提取机制。我在Coq中为素数写了一个幼稚的谓词,它是:
(***********)
(* IMPORTS *)
(***********)
Require Import Coq.Arith.PeanoNat.
(************)
(* helper'' *)
(************)
Fixpoint helper' (p m n : nat) : bool :=
match m,n with
| 0,_ => false
| 1,_ => false
| _,0 => false
| _,1 => false
| S m',S n' => (orb ((mult m n) =? p) (helper' p m' n))
end.
(**********)
(* helper *)
(**********)
Fixpoint helper (p m : nat) : bool :=
match m with
| 0 => false
| S m' => (orb ((mult m m) =? p) (orb (helper' p m' m) (helper p m')))
end.
(***********)
(* isPrime *)
(***********)
Fixpoint isPrime (p : nat) : bool :=
match p with
| 0 => false
| 1 => false
| S p' => (negb (helper p p'))
end.
Compute (isPrime 220).
(*****************)
(* isPrimeHelper *)
(*****************)
Extraction Language Haskell.
(*****************)
(* isPrimeHelper *)
(*****************)
Extraction "/home/oren/GIT/CoqIt/Primes.hs" isPrime helper helper'.
在提取Haskell代码之后,我编写了一个简单的驱动程序对其进行测试。我遇到了两个问题:
Bool
,而不是使用Haskell的内置布尔类型。nat
,所以我不能问isPrime 6
,而不得不使用S (S (...))
。module Main( main ) where
import Primes
main = do
if ((isPrime (
Primes.S (
Primes.S (
Primes.S (
Primes.S (
Primes.S (
Primes.S ( O ))))))))
==
Primes.True)
then
print "Prime"
else
print "Non Prime"
答案 0 :(得分:7)
关于您的第一点-尝试添加
Require Import ExtrHaskellBasic.
到您的Coq来源。它指定提取应针对某些基本类型使用Haskell的前奏定义。可以找到文档here。 strings也有一个类似的模块。
答案 1 :(得分:0)
我要在此处发布完整的解决方案,以使该帖子完全独立。希望其他人可以利用它。
(***********)
(* IMPORTS *)
(***********)
Require Import Coq.Arith.PeanoNat.
(************)
(* helper'' *)
(************)
Fixpoint helper' (p m n : nat) : bool :=
match m,n with
| 0,_ => false
| 1,_ => false
| _,0 => false
| _,1 => false
| S m',S n' => (orb ((mult m n) =? p) (helper' p m' n))
end.
(**********)
(* helper *)
(**********)
Fixpoint helper (p m : nat) : bool :=
match m with
| 0 => false
| S m' => (orb ((mult m m) =? p) (orb (helper' p m' m) (helper p m')))
end.
(***********)
(* isPrime *)
(***********)
Fixpoint isPrime (p : nat) : bool :=
match p with
| 0 => false
| 1 => false
| S p' => (negb (helper p p'))
end.
Compute (isPrime 220).
(********************************)
(* Extraction Language: Haskell *)
(********************************)
Extraction Language Haskell.
(***************************)
(* Use Haskell basic types *)
(***************************)
Require Import ExtrHaskellBasic.
(****************************************)
(* Use Haskell support for Nat handling *)
(****************************************)
Require Import ExtrHaskellNatNum.
Extract Inductive Datatypes.nat => "Prelude.Integer" ["0" "succ"]
"(\fO fS n -> if n Prelude.== 0 then fO () else fS (n Prelude.- 1))".
(***************************)
(* Extract to Haskell file *)
(***************************)
Extraction "/home/oren/GIT/CoqIt/Primes.hs" isPrime helper helper'.
这是驱动程序:
module Main( main ) where
import Primes
import Prelude
main = do
if ((isPrime 220) == True)
then
print "Prime"
else
print "Non Prime"
有趣的是,提到Coq缓慢的Compute (isPrime 220)
与Haskell编译(并优化!)的(is Prime 220)
超快速版本之间的巨大时差。