伊莎贝尔:linord证明

时间:2015-12-07 19:35:10

标签: isabelle

我尝试为自定义数据类型创建自定义线性订单失败,以下是我的代码:

theory Scratch
imports Main 
begin

  datatype st  = Str "string"

  fun solf_str_int:: "string ⇒ int" where
    "solf_str_int str = (if (size str) > 0
                       then int(nat_of_char (hd str) + 1) + 100 *     (solf_str_int (tl str))
                       else 0)"

  fun soflord:: "st ⇒ st ⇒ bool" where
    "soflord s1 s2 = (case s1 of Str ss1 ⇒ (case s2 of Str ss2 ⇒ 
                        (solf_str_int ss1) ≤ (solf_str_int ss2)))"

instantiation st :: linorder
begin
  definition nleq: "less_eq n1 n2 == soflord n1 n2"  
  definition neq: "eq n1 n2 == (n1 ≤ n2) ∧ (n2 ≤ n1)"
  definition nle:  "less n1 n2 == (n1 ≤ n2) ∧ (¬(n1 = n2))" (* ++ *)

  instance proof
    fix n1 n2 x y :: st
    show "n1 ≤ n1" by (simp add:nleq split:st.split)
    show "(n1 ≤ n2) ∨ (n2 ≤ n1)" by (simp add:nleq split:st.split)     (*why is 'by ()' highlited?*)
    (*this fail if I comment line ++ out*)
    show "(x < y) = (x ≤ y ∧ (¬ (y ≤ x)))" by (simp add:nleq neq split:node.split)

  qed
end
end

标有(* ++ *)的定义不正确,如果删除它,最后一个节目会出现问题。

如何更正证明? 为什么第二个最后一个节目部分突出显示?

1 个答案:

答案 0 :(得分:2)

less_eq的情况下定义类型类(lesslinorder)的操作时,只有在推断类型的情况下才能使用重载操作的名称。该操作完全匹配正在定义的重载实例。特别是,如果结果太过笼统,那么这种类型就不是专门的。

less_eq的定义有效,因为soflordn1n2的类型限制为st,因此less_eq与类型一起使用st => st => bool,这正是这里所需要的。对于less,类型推断计算最常规的类型'b :: ord => 'b => bool。由于这不是预期的类型st => st => bool,Isabelle并不认为该定义是重载操作的定义,因此抱怨您想要完全重新定义现有操作。如果您根据需要限制类型,则定义按预期工作。

definition nle:  "less n1 (n2 :: st) == (n1 ≤ n2) ∧ (¬(n1 = n2))"

但是,您的定义未在st上定义线性顺序。问题是违反了反对称性。例如,两个字符串Str ''d''Str [Char Nibble0 Nibble0, Char Nibble0 Nibble0](即,在代码点0由两个字符组成的字符串)在您的订单中是“等效的”,尽管它们是不同的值。您也尝试在st上定义相等性,但在高阶逻辑中,不能定义相等性。它取决于您构建类型的方式。如果你真的想要根据你的订单识别相同的字符串,你必须首先构造一个商,例如,使用商包。

by(simp ...)的紫色高亮表示证明方法simp仍在运行。在您的情况下,它不会终止,因为simp将继续展开solf_str_int的定义等式:它的右侧包含左侧的实例。我建议您通过=左侧的模式匹配来定义函数。然后,只有当它们可以消耗模式时才使用这些方程。因此,您必须自己触发案例区分(例如使用cases),但您也可以更好地控制自动化策略。