[英]Isabelle: linord proof
我嘗試為自定義數據類型創建自定義線性順序失敗,以下是我的代碼:
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
標有(* ++ *)的定義不正確,如果刪除該定義,則最后一個顯示會出現問題。
我該如何糾正證明? 為什么倒數第二個節目部分突出?
當定義一個類型的類(的操作less_eq
和less
在的情況下linorder
),只能用於過載操作的名稱,如果推斷出的類型的動作的恰好正在定義重載實例相匹配。 特別是,如果類型過於通用,則該類型不是專用的。
less_eq
的定義有效,因為soflord
將n1
和n2
的類型限制為st
,因此less_eq
與st => st => bool
類型less_eq
使用,這正是此處所需要的。 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
),但是您還可以更好地控制自動化策略。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.