我试图为4值逻辑定义连接函数(false,true,null和error):
datatype 'a maybe = Just "'a" | Nothing | Error
type_synonym bool4 = "bool maybe"
abbreviation JF :: "bool4" where "JF ≡ Just False"
abbreviation JT :: "bool4" where "JT ≡ Just True"
abbreviation BN :: "bool4" where "BN ≡ Nothing"
abbreviation BE :: "bool4" where "BE ≡ Error"
fun and4 :: "bool4 ⇒ bool4 ⇒ bool4" where
"and4 JF b = JF"
| "and4 a JF = JF"
| "and4 BE b = BE"
| "and4 a BE = BE"
| "and4 BN b = BN"
| "and4 a BN = BN"
| "and4 a b = JT"
我希望第一种模式优先于最后的模式。
似乎定义错了。我试图评估以下表达式:
value "and4 JF b"
value "and4 a JF"
第一个按预期返回JF。但第二个不能简化。
结果我无法证明连词的交换性:
lemma and4_commut:
"and4 a b = and4 b a"
建议在"Defining Recursive Functions in Isabelle/HOL" by Alexander Krauss中使用function
代替fun
。但我得到12个虚假子目标:
function and4 :: "bool4 ⇒ bool4 ⇒ bool4" where
"and4 JF b = JF"
| "and4 a JF = JF"
| "and4 BE b = BE"
| "and4 a BE = BE"
| "and4 BN b = BN"
| "and4 a BN = BN"
| "and4 a b = JT"
apply pat_completeness
apply auto
我想这是因为该功能存在冲突模式。例如,and4 JF BE
与第1和第4个模式匹配。结合的结果可能是JF或BE。
定义此类功能的正确方法是什么?以及如何证明其可交换性?我可以使用case of
构造,但它使函数定义复杂化。
答案 0 :(得分:2)
value
命令通常无法很好地处理自由变量(如a
)。
然而,您可以通过区分来证明定理FooAndValue a JF = JF
:
lemma and4_JF_right [simp]: "and4 a JF = JF"
proof (cases a)
case (Just b)
thus ?thesis by (cases b) simp_all
qed simp_all
或者,使用自定义case
规则稍微冗长一点:
lemma bool4_cases [case_names JF JT BN BE]:
"(a = JF ⟹ P) ⟹ (a = JT ⟹ P) ⟹ (a = BN ⟹ P) ⟹ (a = BE ⟹ P) ⟹ P"
by (cases a) auto
lemma and4_JF_right [simp]: "and4 a JF = JF"
by (cases a rule: bool4_cases) simp_all
有了这个,证明交换可以通过简单的单线感应来完成。
fun
命令没有给你and4 a JF = JF
作为定理的原因,即使你在定义中确实写了那个,确实你有重叠模式并使用顺序模式匹配,即函数定义中的第二个“等式”仅适用于第一个“等式”。
fun
必须解决重叠模式以适应这种顺序匹配,在此之后,and4 a JF = JF
保持不明显(通常)。您可以查看and4.simps
以确切了解fun
做了什么。
如果我没记错的话,你也可以使用普通function
来重叠模式而不需要顺序匹配,但是你必须证明重叠方程是兼容的。在你的情况下,我认为这不会让事情变得更容易。
您可以做的另一件事(根据您的使用情况可能更容易使用)将不使用bool maybe
,而是定义4构造函数数据类型并在该类型上定义线性排序,JF < BE < BN < JT
,然后and4
等同于min
。