简化自然的漂亮印刷

时间:2014-03-27 12:27:33

标签: isabelle

假设我写了一个用于反转列表的函数。我想用value命令测试它,只是为了向自己保证我可能做对了。但输出看起来很可怕:

value "reverse [1,8,3]"
> "[1 + 1 + 1, 1 + 1 + (1 + 1) + (1 + 1 + (1 + 1)), 1]" :: "'a list"

如果我告诉Isabelle将这些数字字符视为自然,那么输出会更糟:

value "reverse [1::nat,8,3]"
> "[Suc (Suc (Suc 0)), Suc (Suc (Suc (Suc (Suc (Suc (Suc (Suc 0))))))), Suc 0]" :: "nat list"

有时我会求助于使用字符串,但对于所有这些撇号而言,这看起来有点滑稽:

value "reverse [''1'',''8'',''3'']"
> "[''3'', ''8'', ''1'']" :: "char list list"

我是否可以指示Isabelle的漂亮打印机将Suc (Suc (Suc 0))打印为3,依此类推?也许通过给syntaxtranslations命令提供一些神奇的咒语?


这是我的完整示例,如果您想将其粘贴到Isabelle中:

theory Scratch imports Main begin

fun reverse where 
  "reverse [] = []"
| "reverse (x#xs) = reverse xs @ [x]"

value "reverse [1,8,3]"
value "reverse [1::nat,8,3]"
value "reverse [''1'',''8'',''3'']"

end

2 个答案:

答案 0 :(得分:5)

简答:我的第一个想法是使用类型int,因为(与nat不同),其代码生成器设置默认使用二进制数字表示。

如果您不想对"~~/src/HOL/Library/Code_Target_Nat"类型使用Suc表示形式,那么导入nat也是一个好主意。

说明: Isabelle中的数字使用Num.thy中定义的构造函数进行编码;例如5numeral (Bit1 (Bit0 One))的缩写。此处OneBit0Bit1num类型的构造函数。 numeral已重载,适用于1和关联+的任何类型。以下是numeral的代码方程式:

lemma numeral_code [code]:
  "numeral One = 1"
  "numeral (Bit0 n) = (let m = numeral n in m + m)"
  "numeral (Bit1 n) = (let m = numeral n in m + m + 1)"

如果我们为5::'a::numeral生成代码,则类型1上的+'a会被视为未解释的常量,因此它们会保留在输出中:{{1} }。

(1 + 1) + (1 + 1) + 1生成代码的工作方式相同,只是我们的代码5::nat1代码+nat。因此,Suc会进一步缩短为(1 + 1) + (1 + 1) + 1

类型Suc (Suc (Suc (Suc (Suc 0))))的工作方式不同。 int中的代码生成器设置使用类型Int.thy的三个构造函数:intPos类型Neg,以及num => int0声明会导致代码生成期间code_abbrev类型numeral的每次出现都被num => int替换。代码运行后,然后在Isabelle显示结果之前将Pos变回Pos。因此numeral评估为5::int

特殊代码设置理论: 5包含一些用于自定义数字代码生成的不同理论。

  • src/HOL/Library告诉代码生成器使用目标语言(例如SML或Haskell)的内置数字类型"~~/src/HOL/Library/Code_Target_Nat"。例如,nat通常被翻译为SML 5::nat;但是,加载此库后,它将在SML中转换为numeral (Bit1 (Bit0 One))5的结果随后被转换回伊莎贝尔数字表示。

  • value是相同的,但对于"~~/src/HOL/Library/Code_Target_Int"类型而不是int

  • nat只需加载前两个库。它只会影响"~~/src/HOL/Library/Code_Target_Numeral"nat类型,而不会影响类int中的任何其他类型。

  • numeral使用与"~~/src/HOL/Library/Code_Binary_Nat"的默认代码设置相同的样式配置nat:使用构造函数int0以及{{{ 1}}声明。使用此库,nat_of_num::num => nat也会返回code_abbrev

答案 1 :(得分:2)

注意:我希望我的回答并不能阻止Brian Huffman或Florian Haftmann给出答案。如果确实如此,那将是一件坏事。希望我只是做一些gofer工作来设置它们中的任何一个。

简答1:相关的邮件列表电子邮件是Re: [isabelle] value no longer pretty-prints numbers of type nat

简答2: nat的解决方案是导入"~~/src/HOL/Library/Code_Target_Nat"。因为我不清楚numeralnum如何在低级别与HOL完全联系的细节,我给你的解决方案不一定是好的和最终的溶液

我的答案很大一部分是在Brian Huffman或Florian Haftmann来到这里之前,Num.thy的作者,#34;我也对此感兴趣,因为它与numeral有关,numeral是HOL的一个重要组成部分。关于使用nat的错综复杂的信息越多,越好#34;

基本上,他们为Isabelle2013-1做了设计选择更改,即numeraldeclare[[show_sorts=true]]的默认值以后继形式表示。这就是邮件列表电子邮件的内容。

如果您使用value "reverse [1,8,3]",则会看到您的numeral正在使用类型类numeral。我之所以提到这一点,是因为我一直在努力学习nat,甚至使用具体类型,例如int44,使用常量例如5numeral涉及nat,至少是输入。即使使用numeral这样的具体类型,simp也可以参与正在使用的nat规则。

在说出更多内容之前,为value "reverse [1::nat,8,3]"获得良好"~~/src/HOL/Library/Code_Target_Nat" 输出的一种方法是再次使用以下导入:

value "reverse [1,8,3]"

我对您的问题感兴趣的原因是因为这只是Andreas Lochbihler在该电子邮件中看到的即插即用解决方案。

我无法通过导入"~~/src/HOL/Library/Code_Target_Numeral" numeral不使用1的总和:

numeral

所以,我想知道如何让lemma "(3::nat) = z" using[[simp_trace, simp_trace_depth_limit=100, linarith_trace, rule_trace]] using[[blast_trace, blast_stats]] apply simp oops 成为我们喜欢看的好形式。

无论如何,[1]SIMPLIFIER INVOKED ON THE FOLLOWING TERM: 3 = z [1]Procedure "Num.reorient_numeral" produced rewrite rule: ?a1 = ?b1 ≡ ?b1 = ?a1 [1]Applying instance of rewrite rule ?a1 = ?b1 ≡ ?b1 = ?a1 [1]Rewriting: 3 = z ≡ z = 3 是使用数字常量的核心。考虑一下:

Num

simp追踪的一部分是:

{{1}}

如果你看一下涉及数字常数的简单跟踪,你会发现{{1}}规则显示了很多,这些规则来自Num.thy中最优秀的规则。