扩展 Isabelle 引理中的所有定义
Expanding all definitions in Isabelle lemma
拜托,我怎样才能告诉伊莎贝尔展开我所有的 definition
,因为这样证明就很简单了?不幸的是,没有默认扩展或简化发生,基本上我得到了原始表达式作为子目标。
示例:
theory Test
imports Main
begin
definition b0 :: "nat⇒nat"
where "b0 n ≡ (n mod 2)"
definition b1 :: "nat⇒nat"
where "b1 n ≡ (n div 2)"
lemma "(a::nat)≤3 ∧ (b::nat)≤3 ⟶
2*(b1 a)+(b0 a)+2*(b1 b)+(b0 b) = a+b"
apply auto
oops
end
在oops
之前回复:
proof (prove)
goal (1 subgoal):
1. a ≤ 3 ⟹
b ≤ 3 ⟹ 2 * b1 a + b0 a + 2 * b1 b + b0 b = a + b
是的,我一直忘记默认情况下不在简化中使用定义。
将定义显式添加到简化规则解决了这个问题:
lemma "(a::nat)≤3 ∧ (b::nat)≤3 ⟶
2*(b1 a)+(b0 a)+2*(b1 b)+(b0 b) = a+b"
by (simp add: b0_def b1_def)
这样就可以正确使用定义(b0
、b1
)。
我的推荐:unfolding
有一个特殊关键字 unfolding
用于在证明开始时解包定义。对于您的示例,这将是:
unfolding b0_def b1_def by simp
我认为unfolding
是最优雅的方式。它还有助于编写证明。在内部,这(主要是?)等同于使用 unfold
-method:
apply (unfold b0_def b1_def) by simp
这将递归地 (!) 使用您提供的一组等式来重写证明目标。 (由于递归,你不应该提供一组可能产生循环的等式......)
备选方案:使用简化器
在可能存在循环的情况下,简化器可能能够在不 运行 进入这些循环的情况下实现良好的展开,也许是通过与其他简化交错进行。在这种情况下,by (simp add: b0_def b1_def)
,正如您所建议的那样,非常好!
替代定义:也许它只是一个 abbreviation
(没有 definition
)?
如果您发现自己在每个实例中都展开定义,您可以考虑使用 abbreviation
而不是 definition
。然后,一些 Isabelle 魔术会在没有进一步提示的情况下为您完成 packing/unpacking。 abbeviation
只会影响用户与伊莎贝尔的交流方式。它不会在对象级别引入新符号,因此不会有 b1_def
事实等。
abbreviation b0 :: "nat⇒nat"
where "b0 n ≡ (n mod 2)"
通常不推荐:使用简化器构建类似于缩写的东西
如果您(无论出于何种原因)想要在对象级别定义一个名称,但几乎在每个实例中都展开它,您也可以将定义等式直接输入简化器。
definition b0 :: "nat⇒nat"
where [simp]: "b0 n ≡ (n mod 2)"
(通常最后一个选项应该没什么理由。)
拜托,我怎样才能告诉伊莎贝尔展开我所有的 definition
,因为这样证明就很简单了?不幸的是,没有默认扩展或简化发生,基本上我得到了原始表达式作为子目标。
示例:
theory Test
imports Main
begin
definition b0 :: "nat⇒nat"
where "b0 n ≡ (n mod 2)"
definition b1 :: "nat⇒nat"
where "b1 n ≡ (n div 2)"
lemma "(a::nat)≤3 ∧ (b::nat)≤3 ⟶
2*(b1 a)+(b0 a)+2*(b1 b)+(b0 b) = a+b"
apply auto
oops
end
在oops
之前回复:
proof (prove)
goal (1 subgoal):
1. a ≤ 3 ⟹
b ≤ 3 ⟹ 2 * b1 a + b0 a + 2 * b1 b + b0 b = a + b
是的,我一直忘记默认情况下不在简化中使用定义。
将定义显式添加到简化规则解决了这个问题:
lemma "(a::nat)≤3 ∧ (b::nat)≤3 ⟶
2*(b1 a)+(b0 a)+2*(b1 b)+(b0 b) = a+b"
by (simp add: b0_def b1_def)
这样就可以正确使用定义(b0
、b1
)。
我的推荐:unfolding
有一个特殊关键字 unfolding
用于在证明开始时解包定义。对于您的示例,这将是:
unfolding b0_def b1_def by simp
我认为unfolding
是最优雅的方式。它还有助于编写证明。在内部,这(主要是?)等同于使用 unfold
-method:
apply (unfold b0_def b1_def) by simp
这将递归地 (!) 使用您提供的一组等式来重写证明目标。 (由于递归,你不应该提供一组可能产生循环的等式......)
备选方案:使用简化器
在可能存在循环的情况下,简化器可能能够在不 运行 进入这些循环的情况下实现良好的展开,也许是通过与其他简化交错进行。在这种情况下,by (simp add: b0_def b1_def)
,正如您所建议的那样,非常好!
替代定义:也许它只是一个 abbreviation
(没有 definition
)?
如果您发现自己在每个实例中都展开定义,您可以考虑使用 abbreviation
而不是 definition
。然后,一些 Isabelle 魔术会在没有进一步提示的情况下为您完成 packing/unpacking。 abbeviation
只会影响用户与伊莎贝尔的交流方式。它不会在对象级别引入新符号,因此不会有 b1_def
事实等。
abbreviation b0 :: "nat⇒nat"
where "b0 n ≡ (n mod 2)"
通常不推荐:使用简化器构建类似于缩写的东西
如果您(无论出于何种原因)想要在对象级别定义一个名称,但几乎在每个实例中都展开它,您也可以将定义等式直接输入简化器。
definition b0 :: "nat⇒nat"
where [simp]: "b0 n ≡ (n mod 2)"
(通常最后一个选项应该没什么理由。)