伊莎贝尔:将 "sqrt" 导出到 Haskell

Isabelle: Exporting "sqrt" to Haskell

免责声明:我完全是伊莎贝尔初学者。

我正在尝试将 "sqrt" 函数或使用 "sqrt" 的函数和定义导出到 Haskell。我的第一次尝试只是:

theory Scratch
   imports Complex_Main
begin
   definition val :: "real" where "val = sqrt 4"

   export_code val in Haskell 
end 

导致以下错误:

Wellsortedness error
(in code equation root ?n ?x ≡
              if equal_nat_inst.equal_nat ?n zero_nat_inst.zero_nat then zero_real_inst.zero_real
              else the_inv_into top_set_inst.top_set
                    (λy. times_real_inst.times_real (sgn_real_inst.sgn_real y)
                           (abs_real_inst.abs_real y ^ ?n))
                    ?x,
with dependency "val" -> "sqrt" -> "root"):
Type real not of sort {enum,equal}
No type arity real :: enum

所以我尝试用Haskell的"Prelude.sqrt"替换"sqrt":

code_printing
  constant sqrt ⇀ (Haskell) "Prelude.sqrt _"

export_code val in Haskell 

这仍然导致相同的错误。这对我来说似乎很奇怪,因为用某个任意函数 "f" 替换 "plus" 似乎没问题:

definition val' :: "nat" where "val' = plus 49 1"

code_printing
  constant plus ⇀ (Haskell) "_ `f` _" 

export_code val' in Haskell 

如何解决这个问题?

我不确定 code_printing 问题,但您希望这里发生什么? Wellsortedness error 在代码生成期间通常意味着您尝试导出的内容根本无法计算(或者至少 Isabelle 不知道如何计算)。

您希望 sqrt 2 之类的东西在 Haskell 中编译成什么? sqrt pi 呢?您不能希望为 所有 个实数生成可执行代码。 Isabelle 的默认实现仅限于有理数。

用 Haskell 的 sqrt 替换 Isabelle 的 sqrt 的代码打印只会给你一个类型错误,因为 Haskell 的 sqrt 适用于浮点数,不适用于 Isabelle 导出的 real 类型。

~~/src/HOL/Library/Code_Real_Approx_By_Float 中有一个文件将 Isabelle 对实数的运算映射到标准 ML 和 OCaml 中的浮点近似值,但这仅用于实验,因为如果你这样做,你将失去所有正确性保证的东西。

最后,形式证明存档中有一个条目提供了精确的可执行文件algebraic real numbers,因此您至少可以使用平方根等进行一些运算., 但这是一项艰巨的工作,在某些情况下性能可能会很差。

~~/src/HOL/Library/Discrete 中,Isabelle 中的 自然 数字也有一个 sqrt 操作(即向下舍入),并且可以轻松导出到Haskell.

在 AFP 中还有一个条目 Sqrt_Babylonian,其中包含计算 sqrt 的算法,直到给定精度 epsilon > 0,没有任何浮点舍入错误。

关于 Manuel 提到的代数数的复杂性,这实际上取决于您的输入。如果您使用嵌套平方根或组合不同的平方根(如 sqrt 2 + ... + sqrt 50),那么性能很快就会下降。但是,如果您很少使用平方根或总是在多个位置使用相同的平方根,那么代数数可能足够快。