我需要定义一个扩展的布尔类型(ebool = bool ∪ {⊥}
)和该类型的一组操作(连接等)。
这是理论:
theory EboolTest
imports Main "~~/src/HOL/Library/Adhoc_Overloading"
begin
notation
bot ("⊥")
declare [[coercion_enabled]]
typedef ebool = "UNIV :: bool option set" ..
definition ebool :: "bool ⇒ ebool" where
"ebool b = Abs_ebool (Some b)"
declare [[coercion "ebool :: bool ⇒ ebool"]]
instantiation ebool :: bot
begin
definition "⊥ ≡ Abs_ebool None"
instance ..
end
free_constructors case_ebool for
ebool
| "⊥ :: ebool"
apply (metis Rep_ebool_inverse bot_ebool_def ebool_def not_Some_eq)
apply (smt Abs_ebool_inverse ebool_def iso_tuple_UNIV_I option.inject)
by (simp add: Abs_ebool_inject bot_ebool_def ebool_def)
lemmas ebool2_cases = ebool.exhaust[case_product ebool.exhaust]
lemmas ebool3_cases = ebool.exhaust[case_product ebool.exhaust ebool.exhaust]
fun ebool_and :: "ebool ⇒ ebool ⇒ ebool" (infixr "∧" 35) where
"ebool_and a b = ebool (HOL.conj a b)"
| "ebool_and False _ = False"
| "ebool_and _ False = False"
| "ebool_and ⊥ _ = ⊥"
| "ebool_and _ ⊥ = ⊥"
no_notation HOL.conj (infixr "∧" 35)
consts "(∧)" :: "'a ⇒ 'a ⇒ 'a"
adhoc_overloading "(∧)" HOL.conj
adhoc_overloading "(∧)" ebool_and
end
以下工作正常:
value "True ∧ (False::ebool)"
value "True ∧ ⊥"
但是以下返回ebool
,但是我希望看到bool
:
value "True ∧ False"
看来我的方法不好。您能建议一个更好的方法吗?也许我根本无法重载标准操作?
答案 0 :(得分:1)
首先,我对此感到有些惊讶:
consts "(∧)" :: "'a ⇒ 'a ⇒ 'a"
完全有效。听起来像个错误,因为(...)
标记是为系统保留的。 (为公平起见,它确实会显示警告,除非您确切知道自己在做什么,否则忽略它们是不明智的。)
但是要回过头来讨论您的实际问题,我认为您不应该使用adhoc_overloading
重载Main
会提供的语法。
还有其他选择。例如,您可以使用粗体字。在this theory中使用。
或者您可以使用其他符号,例如&&
。
作为附录:我认为强制和自发超载之间可能存在怪异的相互作用。两种工具本身都很好,但是要注意它们是否相互影响。