我是一位刚开始习惯于Isabelle的数学家,而且应该非常简单的事情变得令人沮丧。如何在两个常量之间定义函数?比方说,函数f:{1,2,3} \到{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"
我认为这种困难背后肯定存在一个根本的误解,所以我很感激任何指导。
答案 0 :(得分:4)
您的问题有很多方面。
首先,要快速开展工作,请使用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
。另请注意,我已在模式匹配中使用nat
数据类型(0
和Suc
)的构造函数替换了重载的数字文字(1,2,3等)。 / p>
另一种方法是坚持使用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
添加到简化器的simpset中证明中test2
。
您还可以使用typedef
定义与您的两个三元素集相对应的新类型(您不能直接使用集合作为类型),但我个人会坚持使用{{1 }}
编辑:要使用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
命令后放置print_theorems
,您会看到Isabelle为您自动生成的有关typedef
的几个新定理。