如何定义重叠模式的函数?

时间:2017-03-22 07:41:08

标签: isabelle

我试图为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构造,但它使函数定义复杂化。

1 个答案:

答案 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