我有以下伊莎贝尔目标:
lemma "⟦ if foo then a ≠ a else b ≠ b ⟧ ⟹ False"
战术没有simp
, fast
, clarsimp
, blast
, fastforce
等作出目标任何进展,尽管它是非常简单的。
为什么不伊莎贝尔只是简化了的身体if
结构,使两者“一≠A”和“b≠B”变成False
,从而解决了目标?
我有以下伊莎贝尔目标:
lemma "⟦ if foo then a ≠ a else b ≠ b ⟧ ⟹ False"
战术没有simp
, fast
, clarsimp
, blast
, fastforce
等作出目标任何进展,尽管它是非常简单的。
为什么不伊莎贝尔只是简化了的身体if
结构,使两者“一≠A”和“b≠B”变成False
,从而解决了目标?
if_weak_cong
一致性规则 默认情况下,伊莎贝尔包括一组的影响,其中简化发生的“一致性规则”。 特别是,默认的一致性规则是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
是默认设置。
除了案例分析和一致性规则,还有就是要解决此目标与简化器第三种方式:分离器。 分路器允许其自身执行区分分析的有限形式的简化器。 它只是运行的时候内无法对自己的任何进一步简化(分裂的情况下,很容易导致目标的爆炸)。
引理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
)是默认安装的一部分。
顺便说一句,对于每个数据类型t
,数据类型包提供分割规则t.split
和t.split_asm
其中用于提供情况分析case
,涉及的类型表达式t
。
正如在其他的答案已经指出的, if_weak_cong
一致性规则防止简化器从简化if语句的分支。 在这个答案,我想阐述一下通过简化器使用的一致性规则了一下。
有关详细信息,还参见关于简化器中相应的章节伊莎贝尔/ ISAR参考手册 (特别是9.3.2节)。
同余规则控制简化器如何下降到条款。 它们可以被用来限制重写,并提供额外的假设。 默认情况下,如果简化器遇到一个功能应用st
将下降俱进s
和t
他们改写为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
”。 由于一致性规则替换默认的策略,这种禁止的任何重写?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 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
,这两者显然改写为False。
(我删除if_cancel
,这通常会解决剩下的目标完全)
含在做一个证明进步的另一种自然的方式if _ then _ else _
是案例分析的条件,例如,
lemma "(if foo then a ~= a else b ~= b) ==> False"
by (cases foo) simp_all
或者如果foo
不是自由可变的,但最外侧的元级通用量词结合的(如通常是在应用的脚本的情况下):
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"
既不cases
也不case_tac
都适用。
注:参见这里对之间的(少量)差异cases
和case_tac
。