扩展 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)

这样就可以正确使用定义(b0b1)。

我的推荐: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)"

(通常最后一个选项应该没什么理由。)