我想通过类比this one定义以下函数:
fun int_divide :: "int option ⇒ int option ⇒ real option" where
"int_divide _ (Some (int 0)) = None"
| "int_divide (Some a) (Some b) = Some (a / b)"
| "int_divide _ _ = None"
fun real_divide :: "real option ⇒ real option ⇒ real option" where
"real_divide _ (Some (real 0)) = None"
| "real_divide (Some a) (Some b) = Some (a / b)"
| "real_divide _ _ = None"
但是这些类型没有int
或real
构造函数。 int
和real
类型定义为quotient_type
。而且我在他们的理论中找不到看起来像构造函数的东西。
以下定义不起作用:
definition int0 :: "int" where
"int0 = Abs_Integ (0,0)"
fun int_divide :: "int option ⇒ int option ⇒ real option" where
"int_divide _ (Some int0) = None"
| "int_divide (Some a) (Some b) = Some (a / b)"
| "int_divide _ _ = None"
如何查找某个类型的所有构造函数?或者至少是quotient_type
?或者如何定义所需的构造函数?
答案 0 :(得分:3)
并非每个类型都是由自由构造函数构建的。设置'a set
和实数real
不是。当然可以显示同构并将其声明为构造函数,例如集合'a set
和谓词'a => bool
之间,但这对定义函数和证明无用。
您可以使用ML块查找已注册的构造函数。例如,以下显示了nat
的构造函数。
ML ‹Ctr_Sugar.ctr_sugar_of @{context} @{type_name nat} |> Option.map #ctrs›
可以使用free_constructors
注册用户定义的构造函数,tutorial on (co)datatype definitions
(可从文档面板中获取)中记录。
这已经说过,我不认为尝试为各种数字类型定义自由构造函数有很多意义,因为你还必须证明关于数字上所有操作如何表现的引理w.r.t.对这些新的构造者。这是很多工作。使用条件而不是模式匹配可能更容易,比如
fun int_divide :: "int option ⇒ int option ⇒ real option" where
"int_divide (Some a) (Some b) = (if b = 0 then None else Some (a / b))"
| "int_divide _ _ = None"
另一个建议是通过使用option
monad和函数option
进行排序来避免参数中的所有Option.bind
。
答案 1 :(得分:2)
除了Andreas的答案之外,Isabelle / HOL中的类型定义总是以某种基础类型为模。例如。整数被定义为自然数对的商。
最初在这些类型上定义函数的典型方法是直接通过从类型定义获得的态射,它在底层基类型和新类型之间进行转换(通常类似于Abs_mytype
和{{1 }}或通过Rep_mytype
,它允许您直接将函数从基类型提升到新类型。
但是,对于像lift_definition
和int
这样的库类型,这是不可取的。你不应该窥视这些类型的内部表示,而只是抽象地使用它们,就像你在“普通”的纸笔数学中一样。