我定义了2种值和一个强制转换函数:
theory FSetIndTest
imports Main "~~/src/HOL/Library/FSet"
begin
datatype val1 = A | B
datatype val2 = C | D
inductive cast_val :: "val1 ⇒ val2 ⇒ bool" where
"cast_val A C"
| "cast_val B D"
此外,我为值列表定义了强制转换功能:
inductive cast_list :: "val1 list ⇒ val2 list ⇒ bool" where
"cast_list [] []"
| "cast_val x y ⟹ cast_list xs ys ⟹ cast_list (x#xs) (y#ys)"
code_pred [show_modes] cast_list .
values "{x. cast_list [A, B] x}"
values "{x. cast_list x [C, D]}"
我需要为fset
定义一个类似的函数。
这是第一次尝试。似乎生成的实现是非终止的:
inductive cast_fset1 :: "val1 fset ⇒ val2 fset ⇒ bool" where
"cast_fset1 {||} {||}"
| "cast_val x y ⟹ cast_fset1 xs ys ⟹
cast_fset1 (finsert x xs) (finsert y ys)"
code_pred [show_modes] cast_fset1 .
(*values "{x. cast_fset1 {|A, B|} x}"*)
这是另一种尝试。给定第一个参数,不允许计算第二个参数:
inductive cast_fset2 :: "val1 fset ⇒ val2 fset ⇒ bool" where
"⋀x y. x |∈| xs ⟹ y |∈| ys ⟹ cast_val x y ⟹
cast_fset2 xs ys"
code_pred [show_modes] cast_fset2 .
以下版本可以正常工作,但是使用功能性cast_val_fun
而不是归纳cast_val
。而且它仅在一个方向上起作用:
fun cast_val_fun :: "val1 ⇒ val2" where
"cast_val_fun A = C"
| "cast_val_fun B = D"
inductive cast_fset3 :: "val1 fset ⇒ val2 fset ⇒ bool" where
"cast_fset3 x (fimage cast_val_fun x)"
code_pred [show_modes] cast_fset3 .
values "{x. cast_fset3 {|A, B|} x}"
这是另一个非终止的实现:
inductive cast_fset4 :: "val1 fset ⇒ val2 fset ⇒ bool" where
"cast_list xs ys ⟹
cast_fset4 (fset_of_list xs) (fset_of_list ys)"
code_pred [show_modes] cast_fset4 .
(*values "{x. cast_fset4 {|A, B|} x}"*)
您能否建议在终止实现的情况下为fsets定义强制转换功能的归纳版本?
更新:
为cast_fset1生成以下代码:
cast_fset1_o_o =
sup (Predicate.bind (Predicate.single ()) (λx. case x of () ⇒ Predicate.single ({||}, {||})))
(Predicate.bind (Predicate.single ())
(λx. case x of
() ⇒
Predicate.bind cast_fset1_o_o
(λx. case x of
(xs_, ys_) ⇒
Predicate.bind cast_val_o_o
(λxa. case xa of
(x_, y_) ⇒ Predicate.single (finsert x_ xs_, finsert y_ ys_)))))
cast_fset1_i_o ?xa =
sup (Predicate.bind (Predicate.single ?xa)
(λx. if x = {||} then Predicate.single {||} else bot))
(Predicate.bind (Predicate.single ?xa)
(λx. Predicate.bind cast_fset1_o_o
(λxa. case xa of
(xs_, ys_) ⇒
Predicate.bind cast_val_o_o
(λxb. case xb of
(xa_, y_) ⇒
if x = finsert xa_ xs_ then Predicate.single (finsert y_ ys_)
else bot))))
cast_fset1_i_o
调用cast_fset1_o_o
。后者是非终止的。我认为这是因为fset
没有任何构造函数。但是我不知道如何解决它。如何在没有构造函数的情况下为数据类型生成代码?
更新2:
多集的行为相同:
code_pred [show_modes] rel_mset' .
values 2 "{x. (rel_mset' cast_val) {#A, B#} x}"
返回{mset [D, C], mset [C, D]} ∪ ...
mset [D, C]
和mset [C, D]
相等。以下表达式返回的Abs_fset {D, C}
和Abs_fset {C, D}
也相等:
values 2 "{x. cast_fset1 {|A, B|} x}"
如何为fset
,multiset
...定义一个归纳谓词,以便它使用某些规范列表表示来计算集合并且不返回重复值?