如何为存在量词生成代码
How to generate code for the existential quantifier
这是一个示例理论:
datatype ty = A | B | C
inductive test where
"test A B"
| "test B C"
inductive test2 where
"¬(∃z. test x z) ⟹ test2 x"
code_pred [show_modes] test .
code_pred [show_modes] test2 .
values "{x. test2 A}"
生成的代码尝试枚举超过 ty
。所以它失败了。
我正在尝试定义 test
谓词的可执行版本:
definition "test_ex x ≡ ∃y. test x y"
definition "test_ex_fun x ≡
Predicate.singleton (λ_. False)
(Predicate.map (λ_. True) (test_i_o x))"
lemma test_ex_code [code_abbrev, simp]:
"test_ex_fun = test_ex"
apply (intro ext)
unfolding test_ex_def test_ex_fun_def Predicate.singleton_def
apply (simp split: if_split)
但我无法证明引理。您能提出更好的方法吗?
好吧,values
抱怨 ty
不像 enum
。因此,在这种特殊情况下,最容易执行此实例化。
instantiation ty :: enum
begin
definition enum_ty :: "ty list" where
"enum_ty = [A,B,C]"
definition "enum_all_ty f = list_all f [A,B,C]"
definition "enum_ex_ty f = list_ex f [A,B,C]"
instance
proof (intro_classes)
let ?U = "UNIV :: ty set"
show id: "?U = set enum_class.enum"
unfolding enum_ty_def
using ty.exhaust by auto
fix P
show "enum_class.enum_all P = Ball ?U P"
"enum_class.enum_ex P = Bex ?U P"
unfolding id enum_all_ty_def enum_ex_ty_def enum_ty_def by auto
show "distinct (enum_class.enum :: ty list)" unfolding enum_ty_def by auto
qed
之后,您的 values
-命令评估没有问题。
我认为引理无法证明,我应该另辟蹊径。但可以证明如下:
lemma test_ex_code [code_abbrev, simp]:
"Predicate.singleton (λ_. False)
(Predicate.map (λ_. True) (test_i_o x)) = (∃y. test x y)"
apply (intro ext iffI)
unfolding Predicate.singleton_def
apply (simp_all split: if_split)
apply (metis SUP1_E mem_Collect_eq pred.sel test_i_o_def)
apply (intro conjI impI)
apply (smt SUP1_E the_equality)
apply (metis (full_types) SUP1_E SUP1_I mem_Collect_eq pred.sel test_i_o_def)
done
有趣的是,引理结构和证明结构似乎独立于具体谓词。我想任何谓词都有一个通用的解决方案。
通过引入另一个归纳谓词,可以使归纳谓词参数上的存在量词可执行。例如:
inductive test2_aux where "test x z ==> test2_aux x"
inductive test2 where "~ test2_aux x ==> test2 x"
使用适当的 code_pred
语句。 test2_aux
前提下的自由变量 z
就像存在主义一样。由于此转换是规范的,code_pred
有一个预处理器可以这样做:
code_pred [inductify] test2 .
完成任务。
这是一个示例理论:
datatype ty = A | B | C
inductive test where
"test A B"
| "test B C"
inductive test2 where
"¬(∃z. test x z) ⟹ test2 x"
code_pred [show_modes] test .
code_pred [show_modes] test2 .
values "{x. test2 A}"
生成的代码尝试枚举超过 ty
。所以它失败了。
我正在尝试定义 test
谓词的可执行版本:
definition "test_ex x ≡ ∃y. test x y"
definition "test_ex_fun x ≡
Predicate.singleton (λ_. False)
(Predicate.map (λ_. True) (test_i_o x))"
lemma test_ex_code [code_abbrev, simp]:
"test_ex_fun = test_ex"
apply (intro ext)
unfolding test_ex_def test_ex_fun_def Predicate.singleton_def
apply (simp split: if_split)
但我无法证明引理。您能提出更好的方法吗?
好吧,values
抱怨 ty
不像 enum
。因此,在这种特殊情况下,最容易执行此实例化。
instantiation ty :: enum
begin
definition enum_ty :: "ty list" where
"enum_ty = [A,B,C]"
definition "enum_all_ty f = list_all f [A,B,C]"
definition "enum_ex_ty f = list_ex f [A,B,C]"
instance
proof (intro_classes)
let ?U = "UNIV :: ty set"
show id: "?U = set enum_class.enum"
unfolding enum_ty_def
using ty.exhaust by auto
fix P
show "enum_class.enum_all P = Ball ?U P"
"enum_class.enum_ex P = Bex ?U P"
unfolding id enum_all_ty_def enum_ex_ty_def enum_ty_def by auto
show "distinct (enum_class.enum :: ty list)" unfolding enum_ty_def by auto
qed
之后,您的 values
-命令评估没有问题。
我认为引理无法证明,我应该另辟蹊径。但可以证明如下:
lemma test_ex_code [code_abbrev, simp]:
"Predicate.singleton (λ_. False)
(Predicate.map (λ_. True) (test_i_o x)) = (∃y. test x y)"
apply (intro ext iffI)
unfolding Predicate.singleton_def
apply (simp_all split: if_split)
apply (metis SUP1_E mem_Collect_eq pred.sel test_i_o_def)
apply (intro conjI impI)
apply (smt SUP1_E the_equality)
apply (metis (full_types) SUP1_E SUP1_I mem_Collect_eq pred.sel test_i_o_def)
done
有趣的是,引理结构和证明结构似乎独立于具体谓词。我想任何谓词都有一个通用的解决方案。
通过引入另一个归纳谓词,可以使归纳谓词参数上的存在量词可执行。例如:
inductive test2_aux where "test x z ==> test2_aux x"
inductive test2 where "~ test2_aux x ==> test2 x"
使用适当的 code_pred
语句。 test2_aux
前提下的自由变量 z
就像存在主义一样。由于此转换是规范的,code_pred
有一个预处理器可以这样做:
code_pred [inductify] test2 .
完成任务。