伊莎贝尔为什么不简化我的“if _ then _ else”结构的主体?

时间:2013-03-26 01:14:41

标签: isabelle

我有以下Isabelle目标:

lemma "⟦ if foo then a ≠ a else b ≠ b ⟧ ⟹ False"

没有任何策略simpfastclarsimpblastfastforce等在目标上取得任何进展,尽管它相当简单。

为什么Isabelle不简化if构造的主体,以便“a≠a”和“b≠b”成为False,从而解决目标?

4 个答案:

答案 0 :(得分:6)

if_weak_cong同余规则

默认情况下,Isabelle包含一组影响简化发生位置的“同余规则”。特别是,默认同余规则为if_weak_cong,如下所示:

b = c ⟹ (if b then x else y) = (if c then x else y)

此同余规则告诉简化器简化if语句(b = c)的条件,但从不尝试简化if语句的主体。

您可以使用以下方法禁用同余规则:

apply (simp cong del: if_weak_cong)

或用替代(更强大的)同余规则覆盖它:

apply (simp cong: if_cong)

这两个都将解决上述问题。

为什么if_weak_cong在默认的通配集

另一个合理的问题可能是:“为什么if_weak_cong会出现在默认同余集中,如果它导致上述问题?”

一个动机是阻止简化器无限地展开递归函数,例如在以下情况中:

fun fact where
    "fact (n :: nat) = (if n = 0 then 1 else (n * fact (n - 1)))"

在这种情况下,

lemma "fact 3 = 6"
  by simp

解决目标,而

lemma "fact 3 = 6"
  by (simp cong del: if_weak_cong)

将简化器发送到循环中,因为fact定义的右侧不断展开。

第二种情况往往比原始问题中的情景更频繁地发生,这促使if_weak_cong成为默认情况。

答案 1 :(得分:5)

拆分规则

除了案例分析和同余规则之外,还有第三种方法可以使用简化器来解决这个目标:分离器。分离器允许简化器自己执行有限形式的案例分析。只有当该术语不能进一步简化时才会运行(分裂案例很容易导致目标爆炸)。

引理split_if_asm指示拆分器在假设中拆分if

lemma "⟦ if foo then a ≠ a else b ≠ b ⟧ ⟹ False"
  by (simp split: split_if_asm)

可以使用split方法执行单步拆分:

lemma "⟦ if foo then a ≠ a else b ≠ b ⟧ ⟹ False"
  apply (split split_if_asm)
  apply simp_all
  done

请注意,在结论(if)中拆分split_if的规则是默认设置的一部分。

BTW,对于每种数据类型t,数据类型包提供拆分规则t.splitt.split_asm,它们为涉及类型{{1}的case表达式提供案例分析}。

答案 2 :(得分:4)

在包含if _ then _ else _的证明中取得进展的另一种自然方式是对条件的案例分析,例如,

lemma "(if foo then a ~= a else b ~= b) ==> False"
  by (cases foo) simp_all

或者如果foo不是自由变量,而是由最外层的元级通用量词限定(在apply-scripts中通常就是这种情况):

lemma "!!foo. (if foo then a ~= a else b ~= b) ==> False"
  apply (case_tac foo)
  apply simp_all
done

不幸的是,如果foo受到另一种量词的约束,例如

lemma "ALL foo. (if foo then a ~= a else b ~= b) ==> False"

或嵌套假设中的元级通用量词,例如

lemma "True ==> (!!foo. (if foo then a ~= a else b ~= b)) ==> False"

casescase_tac都不适用。

注意:另请参阅here了解casescase_tac之间的(轻微)差异。

答案 3 :(得分:4)

同余规则

正如其他答案中已经提到的,if_weak_cong同余规则阻止简化器简化if语句的分支。在这个答案中,我想详细说明简化器对同余规则的使用。

有关详细信息,另请参阅Isabelle/Isar Reference Manual中有关简化器的章节(特别是第9.3.2节)。

同余规则控制简化器如何降级为术语。它们可用于限制重写并提供其他假设。默认情况下,如果简化器遇到函数应用程序s t,它将同时下降到st以将它们重写为s't',然后再尝试重写生成的术语s' t'

对于每个常量(或变量)c,可以注册单个同余规则。规则if_weak_cong默认注册为常量If(基于if ... then ... else ...语法):

?b = ?c ⟹ (if ?b then ?x else ?y) = (if ?c then ?x else ?y)

如下所示:"如果您遇到术语if ?b then ?x else ?y?b可以简化为?c,则将if ?b then ?x else ?y重写为if ?c then ?x else ?y &#34 ;.由于同余规则替换默认策略,因此禁止重写?x?y

if_weak_cong的替代方案是强同余规则if_cong

⟦ ?b = ?c; (?c ⟹ ?x = ?u); (¬ ?c ⟹ ?y = ?v) ⟧
    ⟹ (if ?b then ?x else ?y) = (if ?c then ?u else ?v)

注意两个假设(?c ⟹ ?x = ?u)(¬ ?c ⟹ ?y = ?v):它们告诉简化器,它可以假设在简化if的左(或右)分支时条件成立(或不成立)。 / p>

例如,考虑简化器在目标上的行为

if foo ∨ False then ¬foo ∨ False else foo ⟹ False

并假设我们对foo一无所知。然后,

  • apply simp:使用规则if_weak_cong,这将简化为 if foo then ¬ foo ∨ False else foo ⟹ False,只重写条件
  • apply (simp cong del: if_weak_cong):没有任何一致性规则,这将是  简化为 if foo then ¬ foo else foo ⟹ False,因为条件和分支被重写
  • apply (simp cong: if_cong del: if_cancel):使用规则if_cong,此目标即可 简化为 if foo then False else False ⟹ False:条件foo ∨ False将是 改写为foo。对于这两个分支,简化器现在重写 foo ⟹ ¬foo ∨ False¬foo ⟹ foo ∨ False,两者都明显改写为 假

    (我删除了if_cancel,这通常会完全解决剩下的目标)