这是一个初学者的问题。
我正在阅读“Isabelle / HOL中的编程和证明”教程。
我想打印“1 + 2”的结果。
所以我写道:
value "1 + 2"
给出了:
"1 + (1 + 1)"
:: "'a"
我希望看到结果,即“3”。我怎么能在伊莎贝尔那里做到这一点? 如果我在定理证明器中标准化“1 + 2”,则显示结果3。我只想在伊莎贝尔做同样的事。
请注意,我昨天开始使用Isabelle。
答案 0 :(得分:10)
在Isabelle中,整数文字(也称为数字常量)如...,-2
,-1
,0
,1
, 2
,...已超载。
有零(zero
),一(one
),正数(numeral
)和负数(neg_numeral
)的类型类。后两者还包含添加剂半群的类型类(semigroup_add
) - 允许使用+
- 和添加剂组(group_add
) - 允许使用+
和-
(也是一元) - 分别使用。 (另请注意,加号本身(op +
)在班级plus
中已超载。)
现在,如果您输入表达式,Isabelle会推断出最常见的类型。通常这比一般人预期的要普遍。这正是你遇到的。考虑一些例子:
input inferred type type class
0 'a 'a::zero
1 'a 'a::one
op + 'a => 'a => 'a 'a::plus
1 + 2 'a 'a::numeral
x + y 'a 'a::plus
Suc 0 + y nat (nat is an instance, among others,
of class semigroup_add)
在这种情况下,您可以通过明确添加类型约束来告诉系统您的通用类型较少,例如,(1::nat) + 2
会导致整体类型nat
。
如果您使用Isabelle / jEdit,您可以方便地调查此类情况,而不会在理论中引入declare [[...]]
之类的噪音。例如,输入
value "1 + 2"
输出面板中的,您会看到
"1 + (1 + 1)"
:: "'a"
现在你可以 Ctrl - 在输出中的'a
上点击(即按下控制按钮并用鼠标点击)。这会告诉您'a
在课程numeral
中。您可以进一步 Ctrl - 单击numeral
以获得此类型类的定义。
如果您将输入更改为(对于自然数字)
value "(1::nat) + 2"
或(对于整数)
value "(1::int) + 2"
输出将是
"Suc (Suc (Suc 0)))" :: "nat"
和
"3" :: "int"
正如所料。
更新:请注意,自然数字(类型nat
)将以一元表示形式打印,例如:0
,Suc 0
,Suc (Suc 0)
, ......
但是,这不应与1 + (1 + (1 + ...))
混淆(它是任意类型的numeral
)。这种“Peano数字”构成了适当的自然数,好像nat
定义如下:
datatype nat = 0 | Suc nat
所以这只是关于漂亮印刷,但在逻辑上无关紧要。
答案 1 :(得分:3)
这是我的问题。一个初学者到另一个,多么幸运。
我不知道所有细节,但是如果你没有为常量1和2指定类型,那么你正在使用numeral
,它都是{{3} }}
试试这个并查看输出面板:
declare[[show_consts=true]]
declare[[show_types=true]]
declare[[show_sorts=true]]
value "1 + 2"
value "1 + (2::nat)"
theorem "1 + 2 = z"
apply simp
oops
您会看到1+2
是numeral
,并且不会自动简化,或者说,通过扩展为“后继”形式的补充来简化过多。
value "1 + (2::nat)"
确实被简化为“首选人形”。
在simp
之后,1 + 2
会简化为“首选表单”,即使它是numeral
。