在 Isabelle 中定义常量之间的函数
Defining functions between constants in Isabelle
我是一名刚开始习惯伊莎贝尔的数学家,一些本应非常简单的事情结果却令人沮丧。如何定义两个常量之间的函数?比如,函数 f: {1,2,3} \to {1,2,4} 映射 1 到 1、2 到 4 和 3 到 2?
我想我成功地将集合定义为常量 t1 和 t2,但(我猜是因为它们不是数据类型)我不能尝试
definition f ::"t1 => t2" where
"f 1 = 1" |
"f 2 = 4" |
"f 3 = 2"
我相信这个困难背后一定存在根本性的误解,所以我感谢任何指导。
您的问题涉及多个方面。
首先,要使某些东西快速运行,请使用 fun
关键字而不是 definition
,如下所示:
fun test :: "nat ⇒ nat" where
"test (Suc 0) = 1" |
"test (Suc (Suc 0)) = 4" |
"test (Suc (Suc (Suc 0))) = 2" |
"test _ = undefined"
您不能使用 definition
关键字直接在定义的头部对任何参数进行模式匹配,而可以使用 fun
。另请注意,我已将重载的数字文字(1、2、3 等)替换为模式匹配中 nat
数据类型(0
和 Suc
)的构造函数。
另一种方法是坚持使用 definition
,但使用 case
语句将函数参数的案例分析推入定义主体,如下所示:
definition test2 :: "nat ⇒ nat" where
"test2 x ≡
case x of
(Suc 0) ⇒ 1
| (Suc (Suc 0)) ⇒ 4
| (Suc (Suc (Suc 0))) ⇒ 2
| _ ⇒ undefined"
请注意像 test2
这样的定义在默认情况下不会被简化器展开,如果您想扩展 [=] 的出现,您需要手动将定理 test2_def
添加到简化器的简化集22=] 在证明中。
您还可以使用 typedef
定义与您的两个三元素集相对应的新类型(您不能直接将集合用作类型),但我个人会坚持使用 nat
.
编辑:要使用 typedef
,请执行以下操作:
typedef t1 = "{x::nat. x = 1 ∨ x = 2 ∨ x = 3}"
by auto
definition test :: "t1 ⇒ t1" where
"test x ≡
case (Rep_t1 x) of
| Suc 0 ⇒ Abs_t1 1
| Suc (Suc 0) ⇒ Abs_t1 4
| Suc (Suc (Suc 0)) ⇒ Abs_t1 2"
不过,我自己并没有真正使用过 typedef
,因此这可能不是使用它的最佳方式,其他人可能会建议一些其他方式。 typedef
所做的是通过为新类型识别一组非空居民,从现有类型中开辟出一个新类型。此处由 auto
结束的证明义务只是为了证明新类型的定义集确实是非空的,在这种情况下,我将自然数的三元素集分割成一个新类型,称为 t1
,因此证明相当简单。创建了两个新常量,Abs_t1
和 Rep_t1
,它们允许您在自然类型和新类型之间来回移动。如果你在 typedef
命令后加上 print_theorems
,你会看到 Isabelle 自动为你生成的关于 t1
的几个新定理。
我是一名刚开始习惯伊莎贝尔的数学家,一些本应非常简单的事情结果却令人沮丧。如何定义两个常量之间的函数?比如,函数 f: {1,2,3} \to {1,2,4} 映射 1 到 1、2 到 4 和 3 到 2?
我想我成功地将集合定义为常量 t1 和 t2,但(我猜是因为它们不是数据类型)我不能尝试
definition f ::"t1 => t2" where
"f 1 = 1" |
"f 2 = 4" |
"f 3 = 2"
我相信这个困难背后一定存在根本性的误解,所以我感谢任何指导。
您的问题涉及多个方面。
首先,要使某些东西快速运行,请使用 fun
关键字而不是 definition
,如下所示:
fun test :: "nat ⇒ nat" where
"test (Suc 0) = 1" |
"test (Suc (Suc 0)) = 4" |
"test (Suc (Suc (Suc 0))) = 2" |
"test _ = undefined"
您不能使用 definition
关键字直接在定义的头部对任何参数进行模式匹配,而可以使用 fun
。另请注意,我已将重载的数字文字(1、2、3 等)替换为模式匹配中 nat
数据类型(0
和 Suc
)的构造函数。
另一种方法是坚持使用 definition
,但使用 case
语句将函数参数的案例分析推入定义主体,如下所示:
definition test2 :: "nat ⇒ nat" where
"test2 x ≡
case x of
(Suc 0) ⇒ 1
| (Suc (Suc 0)) ⇒ 4
| (Suc (Suc (Suc 0))) ⇒ 2
| _ ⇒ undefined"
请注意像 test2
这样的定义在默认情况下不会被简化器展开,如果您想扩展 [=] 的出现,您需要手动将定理 test2_def
添加到简化器的简化集22=] 在证明中。
您还可以使用 typedef
定义与您的两个三元素集相对应的新类型(您不能直接将集合用作类型),但我个人会坚持使用 nat
.
编辑:要使用 typedef
,请执行以下操作:
typedef t1 = "{x::nat. x = 1 ∨ x = 2 ∨ x = 3}"
by auto
definition test :: "t1 ⇒ t1" where
"test x ≡
case (Rep_t1 x) of
| Suc 0 ⇒ Abs_t1 1
| Suc (Suc 0) ⇒ Abs_t1 4
| Suc (Suc (Suc 0)) ⇒ Abs_t1 2"
不过,我自己并没有真正使用过 typedef
,因此这可能不是使用它的最佳方式,其他人可能会建议一些其他方式。 typedef
所做的是通过为新类型识别一组非空居民,从现有类型中开辟出一个新类型。此处由 auto
结束的证明义务只是为了证明新类型的定义集确实是非空的,在这种情况下,我将自然数的三元素集分割成一个新类型,称为 t1
,因此证明相当简单。创建了两个新常量,Abs_t1
和 Rep_t1
,它们允许您在自然类型和新类型之间来回移动。如果你在 typedef
命令后加上 print_theorems
,你会看到 Isabelle 自动为你生成的关于 t1
的几个新定理。