我试图证明以下引理:
lemma tranclp_fun_preserve:
"(⋀x y. x ≠ y ⟹ f x ≠ f y) ⟹
(⋀x y. f x ≠ f y ⟹ x ≠ y) ⟹
(⋀x y. f x = f y ⟹ x = y) ⟹
(λ x y. P x y)⇧+⇧+ (f x) (f y) ⟹ (λ x y. P (f x) (f y))⇧+⇧+ x y"
apply (erule tranclp.cases)
apply blast
lemma tranclp_fun_preserve2:
"(⋀x y. x ≠ y ⟹ f x ≠ f y) ⟹
(⋀x y. f x ≠ f y ⟹ x ≠ y) ⟹
(⋀x y. f x = f y ⟹ x = y) ⟹
(λ x y. P (f x) (f y))⇧+⇧+ x y ⟹ (λ x y. P x y)⇧+⇧+ (f x) (f y)"
apply (erule tranclp.cases)
apply blast
但是,我被卡住了。我应该为函数f
选择另一组假设吗?你能建议如何证明lemmas tranclp_fun_preserve
和tranclp_fun_preserve2
吗?
UPDATE
我的函数是单射的,最后描述了一个特殊的属性。我担心下面的例子太长了。但是,我想让它更现实一些。这里有两种辅助类型errorable
和nullable
:
(*** errorable ***)
notation
bot ("⊥")
typedef 'a errorable ("_⇩⊥" [21] 21) = "UNIV :: 'a option set" ..
definition errorable :: "'a ⇒ 'a errorable" ("_⇩⊥" [1000] 1000) where
"errorable x = Abs_errorable (Some x)"
instantiation errorable :: (type) bot
begin
definition "⊥ ≡ Abs_errorable None"
instance ..
end
free_constructors case_errorable for
errorable
| "⊥ :: 'a errorable"
apply (metis Rep_errorable_inverse bot_errorable_def errorable_def not_Some_eq)
apply (metis Abs_errorable_inverse UNIV_I errorable_def option.inject)
by (simp add: Abs_errorable_inject bot_errorable_def errorable_def)
(*** nullable ***)
class opt =
fixes null :: "'a" ("ε")
typedef 'a nullable ("_⇩□" [21] 21) = "UNIV :: 'a option set" ..
definition nullable :: "'a ⇒ 'a nullable" ("_⇩□" [1000] 1000) where
"nullable x = Abs_nullable (Some x)"
instantiation nullable :: (type) opt
begin
definition "ε ≡ Abs_nullable None"
instance ..
end
free_constructors case_nullable for
nullable
| "ε :: 'a nullable"
apply (metis Rep_nullable_inverse null_nullable_def nullable_def option.collapse)
apply (simp add: Abs_nullable_inject nullable_def)
by (metis Abs_nullable_inverse UNIV_I null_nullable_def nullable_def option.distinct(1))
两种价值观:
datatype any = BoolVal "bool⇩⊥" | NatVal "nat⇩⊥" | RealVal "real⇩⊥" | InvalidAny unit
datatype oany = OBoolVal "bool⇩⊥⇩□" | ONatVal "nat⇩⊥⇩□" | ORealVal "real⇩⊥⇩□" | OInvalidAny "unit⇩□"
这是函数f
(any_to_oany
)的一个具体例子,它是单射的:
inductive any_oany :: "any ⇒ oany ⇒ bool" where
"any_oany (BoolVal x) (OBoolVal x⇩□)"
| "any_oany (NatVal x) (ONatVal x⇩□)"
| "any_oany (RealVal x) (ORealVal x⇩□)"
| "any_oany (InvalidAny x) (OInvalidAny x⇩□)"
fun any_to_oany :: "any ⇒ oany" where
"any_to_oany (BoolVal x) = (OBoolVal x⇩□)"
| "any_to_oany (NatVal x) = (ONatVal x⇩□)"
| "any_to_oany (RealVal x) = (ORealVal x⇩□)"
| "any_to_oany (InvalidAny x) = (OInvalidAny x⇩□)"
lemma any_oany_eq_fun:
"any_oany x y ⟷ any_to_oany x = y"
by (cases x; cases y; auto simp: any_oany.simps)
以下是P
(cast_oany
)关系的具体示例:
inductive cast_any :: "any ⇒ any ⇒ bool" where
"cast_any (BoolVal ⊥) (InvalidAny ())"
| "cast_any (NatVal ⊥) (RealVal ⊥)"
| "cast_any (NatVal x⇩⊥) (RealVal (real x)⇩⊥)"
| "cast_any (RealVal ⊥) (InvalidAny ())"
inductive cast_oany :: "oany ⇒ oany ⇒ bool" where
"cast_any x y ⟹ any_oany x ox ⟹ any_oany y oy ⟹
cast_oany ox oy"
| "cast_oany (OBoolVal ε) (OInvalidAny ε)"
| "cast_oany (ONatVal ε) (ORealVal ε)"
| "cast_oany (ORealVal ε) (OInvalidAny ε)"
我在cast_any
上证明了cast_oany
和any
的等价性:
lemma cast_any_implies_cast_oany:
"cast_any x y ⟹ cast_oany (any_to_oany x) (any_to_oany y)"
by (simp add: any_oany_eq_fun cast_oany.intros(1))
lemma cast_oany_implies_cast_any:
"cast_oany (any_to_oany x) (any_to_oany y) ⟹ cast_any x y"
by (cases x; cases y; simp add: any_oany.simps cast_oany.simps)
我的最终目标是为这些关系的传递性封闭证明类似的引理:
lemma trancl_cast_oany_implies_cast_any:
"cast_oany⇧+⇧+ (any_to_oany x) (any_to_oany y) ⟹ cast_any⇧+⇧+ x y"
lemma trancl_cast_any_implies_cast_oany:
"cast_any⇧+⇧+ x y ⟹ cast_oany⇧+⇧+ (any_to_oany x) (any_to_oany y)"
我证明了以下中间引理:
lemma trancl_cast_oany_implies_cast_any':
"(λx y. cast_oany (any_to_oany x) (any_to_oany y))⇧+⇧+ x y ⟹
cast_any⇧+⇧+ x y"
apply (erule tranclp_trans_induct)
apply (simp add: cast_oany_implies_cast_any tranclp.r_into_trancl)
by auto
lemma trancl_cast_any_implies_cast_oany':
"cast_any⇧+⇧+ x y ⟹
(λx y. cast_oany (any_to_oany x) (any_to_oany y))⇧+⇧+ x y"
apply (erule tranclp_trans_induct)
apply (simp add: cast_any_implies_cast_oany tranclp.r_into_trancl)
by auto
最后,如果我能从原始问题证明以下引理,那么我将能够证明我的目标引理。
lemma tranclp_fun_preserve:
"cast_oany⇧+⇧+ (any_to_oany x) (any_to_oany y) ⟹
(λx y. cast_oany (any_to_oany x) (any_to_oany y))⇧+⇧+ x y"
lemma tranclp_fun_preserve2:
"(λx y. cast_oany (any_to_oany x) (any_to_oany y))⇧+⇧+ x y ⟹
cast_oany⇧+⇧+ (any_to_oany x) (any_to_oany y)"
在这一段中,我提供了any_to_oany
函数的一个重要属性。 oany
值集由两部分组成:
OBoolVal ε
,ONatVal ε
,ORealVal ε
,OInvalidAny ε
)关系cast_oany
分别将第一部分内部和第二部分内部的值相关联。不同部分的值之间没有关系。函数any_to_oany
仅将值映射到第二部分。我不知道这个属性的正确名称是什么:子集1和2相对于cast_oany
关系是“关闭的”。并且函数any_to_oany
仅将值映射到一个子集,并且它在该子集上是双射的。
回答原始问题
这个答案为函数提供了(温和的)充分条件,可以根据你问题中从lemmas tranclp_fun_preserve
和tranclp_fun_preserve2
推断的定义来保留闭包属性。
特别是,如果函数是双射的,那么它保留了闭包的属性。 Isabelle的证明如下。但是,请注意,证据可能会以更好的方式重申。
theory so_wkfppc_1
imports
Complex_Main
"HOL-Library.FuncSet"
begin
lemma tranclp_fun_preserve_1:
fixes f:: "'a ⇒ 'b"
and R :: "'b ⇒ 'b ⇒ bool"
and x x'::'a
assumes as_f: "bij f"
and prem: "R⇧+⇧+ (f x) (f x')"
shows "(λ x x'. R (f x) (f x'))⇧+⇧+ x x'"
proof -
define g where g: "g = the_inv_into UNIV f"
define P where P: "P = (λ y y'. (λ x x'. R (f x) (f x'))⇧+⇧+ (g y) (g y'))"
define y where y: "y = f x"
define y' where y': "y' = f x'"
from prem y y' have major: "R⇧+⇧+ y y'" by blast
from P as_f g have cases_1: "⋀y y'. R y y' ⟹ P y y'"
using bij_betw_imp_surj_on bij_is_inj f_the_inv_into_f by fastforce
from P have cases_2:
"⋀x y z. R⇧+⇧+ x y ⟹ P x y ⟹ R⇧+⇧+ y z ⟹ P y z ⟹ P x z"
by auto
from major cases_1 cases_2 have "P y y'" by (rule tranclp_trans_induct)
with P as_f y y' g show ?thesis by (simp add: bij_is_inj the_inv_f_f)
qed
lemma tranclp_fun_preserve_2:
fixes f:: "'a ⇒ 'b"
and R :: "'b ⇒ 'b ⇒ bool"
and x x'::'a
assumes as_f: "bij f"
and prem: "(λ x x'. R (f x) (f x'))⇧+⇧+ x x'"
shows "R⇧+⇧+ (f x) (f x')"
proof -
define P where P: "P = (λ x x'. (λ y y'. R y y')⇧+⇧+ (f x) (f x'))"
define r where r: "r = (λ x x'. R (f x) (f x'))"
define y where y: "y = f x"
define y' where y': "y' = f x'"
from prem r y y' have major: "r⇧+⇧+ x x'" by blast
from P as_f r have cases_1: "⋀y y'. r y y' ⟹ P y y'"
using bij_betw_imp_surj_on bij_is_inj f_the_inv_into_f by fastforce
from P have cases_2:
"⋀x y z. r⇧+⇧+ x y ⟹ P x y ⟹ r⇧+⇧+ y z ⟹ P y z ⟹ P x z"
by auto
from major cases_1 cases_2 have inv_conc: "P x x'"
by (rule tranclp_trans_induct)
with P as_f y y' show ?thesis by (simp add: bij_is_inj the_inv_f_f)
qed
end
我相信有几点评论是有道理的:
f
的生物活性是保持封闭性质的充分条件。(⋀x y. x ≠ y ⟹ f x ≠ f y) ⟺ (⋀x y. f x = f y ⟹ x = y)
。当然,这些前提中的任何一个都可以用来表明f
是一个内射函数。然而,使用缩写inj
(HOL/Fun.thy
)来表示f
是一个内射函数可能更好。tranclp_fun_preserve
有一个反例可以找到,例如,使用nitpick
。特别是,反例证明,如果f
不是满射的,那么它可能无法保留闭合的性质。对更新的回应
感谢您提供进一步的详细信息。请在下面找到lemmas tranclp_fun_preserve
和tranclp_fun_preserve2
的证明(如您的更新中所述):
theory so_wkfppc_2
imports
Complex_Main
"HOL-Library.FuncSet"
begin
(*** general theory of functions that preserve properties of closure ***)
definition rel_closed_under :: "('a ⇒ 'a ⇒ bool) ⇒ 'a set ⇒ bool" where
"rel_closed_under R A =
(∀x x'::'a. R x x' ⟶ (x ∈ A ∧ x' ∈ A) ∨ (x ∈ -A ∧ x' ∈ -A))"
lemma rel_tcl_closed_under:
fixes R :: "'a ⇒ 'a ⇒ bool"
and A :: "'a set"
assumes as_ra: "rel_closed_under R A"
shows "rel_closed_under R⇧+⇧+ A"
proof -
define P where P:
"P = (λ x x' :: 'a. (x ∈ A ∧ x' ∈ A) ∨ (x ∈ -A ∧ x' ∈ -A))"
{
fix x x' :: 'a
assume as_major: "R⇧+⇧+ x x'"
from as_ra P have cases_1:
"⋀x y. R x y ⟹ P x y" by (simp add: rel_closed_under_def)
from P have "⋀x y z. R⇧+⇧+ x y ⟹ P x y ⟹ R⇧+⇧+ y z ⟹ P y z ⟹ P x z"
by blast
with as_major cases_1 have "P x x'" by (rule tranclp_trans_induct)
}
then have "⋀x x'. R⇧+⇧+ x x' ⟹ P x x'" by blast
with P rel_closed_under_def show ?thesis by blast
qed
lemma tranclp_fun_preserve_gen_1:
fixes f:: "'a ⇒ 'b"
and R :: "'b ⇒ 'b ⇒ bool"
and B :: "'b set"
and x x'::'a
assumes as_f: "bij_betw f UNIV B"
and as_R: "rel_closed_under R B"
and prem: "R⇧+⇧+ (f x) (f x')"
shows "(λ x x'. R (f x) (f x'))⇧+⇧+ x x'"
proof -
define g where g: "g = the_inv_into UNIV f"
define gr where gr: "gr = restrict g (range f)"
define P where P:
"P =
(λ y y'. y ∈ B ⟶ y' ∈ B ⟶ (λ x x'. R (f x) (f x'))⇧+⇧+ (gr y) (gr y'))"
define y where y: "y = f x"
with as_f have y_in_B: "y ∈ B" using bij_betw_imp_surj_on by blast
define y' where y': "y' = f x'"
with as_f have y'_in_B: "y' ∈ B" using bij_betw_imp_surj_on by blast
from prem y y' have major: "R⇧+⇧+ y y'" by blast
from P as_f as_R g y_in_B y'_in_B have cases_1: "⋀y y'. R y y' ⟹ P y y'"
by (metis (no_types, lifting) bij_betw_imp_inj_on bij_betw_imp_surj_on
f_the_inv_into_f gr restrict_apply' tranclp.r_into_trancl)
from P have cases_2:
"⋀x y z. R⇧+⇧+ x y ⟹ P x y ⟹ R⇧+⇧+ y z ⟹ P y z ⟹ P x z"
by (smt ComplD as_R rel_closed_under_def rel_tcl_closed_under tranclp_trans)
from major cases_1 cases_2 have inv_conc: "P y y'"
by (rule tranclp_trans_induct)
with P as_f y y' g gr y'_in_B y_in_B show ?thesis
by (metis (no_types, lifting) bij_betw_imp_inj_on bij_betw_imp_surj_on
restrict_apply' the_inv_f_f)
qed
lemma tranclp_fun_preserve_gen_2:
fixes f:: "'a ⇒ 'b"
and R :: "'b ⇒ 'b ⇒ bool"
and B :: "'b set"
and x x'::'a
assumes as_f: "bij_betw f UNIV B"
and as_R: "rel_closed_under R B"
and prem: "(λ x x'. R (f x) (f x'))⇧+⇧+ x x'"
shows "R⇧+⇧+ (f x) (f x')"
proof -
define P where P: "P = (λ x x'. (λ y y'. R y y')⇧+⇧+ (f x) (f x'))"
define r where r: "r = (λ x x'. R (f x) (f x'))"
define y where y: "y = f x"
define y' where y': "y' = f x'"
from prem r y y' have major: "r⇧+⇧+ x x'" by blast
from P as_f r have cases_1: "⋀y y'. r y y' ⟹ P y y'"
using bij_betw_imp_surj_on bij_is_inj f_the_inv_into_f by fastforce
from P have cases_2:
"⋀x y z. r⇧+⇧+ x y ⟹ P x y ⟹ r⇧+⇧+ y z ⟹ P y z ⟹ P x z"
by auto
from major cases_1 cases_2 have inv_conc: "P x x'"
by (rule tranclp_trans_induct)
with P as_f y y' show ?thesis by (simp add: bij_is_inj the_inv_f_f)
qed
(*** errorable ***)
notation
bot ("⊥")
typedef 'a errorable ("_⇩⊥" [21] 21) = "UNIV :: 'a option set" ..
definition errorable :: "'a ⇒ 'a errorable" ("_⇩⊥" [1000] 1000) where
"errorable x = Abs_errorable (Some x)"
instantiation errorable :: (type) bot
begin
definition "⊥ ≡ Abs_errorable None"
instance ..
end
free_constructors case_errorable for
errorable
| "⊥ :: 'a errorable"
apply (metis Rep_errorable_inverse bot_errorable_def errorable_def not_Some_eq)
apply (metis Abs_errorable_inverse UNIV_I errorable_def option.inject)
by (simp add: Abs_errorable_inject bot_errorable_def errorable_def)
(*** nullable ***)
class opt =
fixes null :: "'a" ("ε")
typedef 'a nullable ("_⇩□" [21] 21) = "UNIV :: 'a option set" ..
definition nullable :: "'a ⇒ 'a nullable" ("_⇩□" [1000] 1000) where
"nullable x = Abs_nullable (Some x)"
instantiation nullable :: (type) opt
begin
definition "ε ≡ Abs_nullable None"
instance ..
end
free_constructors case_nullable for
nullable
| "ε :: 'a nullable"
apply (metis Rep_nullable_inverse null_nullable_def nullable_def option.collapse)
apply (simp add: Abs_nullable_inject nullable_def)
by (metis Abs_nullable_inverse UNIV_I null_nullable_def nullable_def option.distinct(1))
datatype any = BoolVal "bool⇩⊥" | NatVal "nat⇩⊥" | RealVal "real⇩⊥" | InvalidAny unit
datatype oany = OBoolVal "bool⇩⊥⇩□" | ONatVal "nat⇩⊥⇩□" | ORealVal "real⇩⊥⇩□" | OInvalidAny "unit⇩□"
inductive any_oany :: "any ⇒ oany ⇒ bool" where
"any_oany (BoolVal x) (OBoolVal x⇩□)"
| "any_oany (NatVal x) (ONatVal x⇩□)"
| "any_oany (RealVal x) (ORealVal x⇩□)"
| "any_oany (InvalidAny x) (OInvalidAny x⇩□)"
fun any_to_oany :: "any ⇒ oany" where
"any_to_oany (BoolVal x) = (OBoolVal x⇩□)"
| "any_to_oany (NatVal x) = (ONatVal x⇩□)"
| "any_to_oany (RealVal x) = (ORealVal x⇩□)"
| "any_to_oany (InvalidAny x) = (OInvalidAny x⇩□)"
lemma any_oany_eq_fun:
"any_oany x y ⟷ any_to_oany x = y"
by (cases x; cases y; auto simp: any_oany.simps)
inductive cast_any :: "any ⇒ any ⇒ bool" where
"cast_any (BoolVal ⊥) (InvalidAny ())"
| "cast_any (NatVal ⊥) (RealVal ⊥)"
| "cast_any (NatVal x⇩⊥) (RealVal (real x)⇩⊥)"
| "cast_any (RealVal ⊥) (InvalidAny ())"
inductive cast_oany :: "oany ⇒ oany ⇒ bool" where
"cast_any x y ⟹ any_oany x ox ⟹ any_oany y oy ⟹
cast_oany ox oy"
| "cast_oany (OBoolVal ε) (OInvalidAny ε)"
| "cast_oany (ONatVal ε) (ORealVal ε)"
| "cast_oany (ORealVal ε) (OInvalidAny ε)"
lemma cast_any_implies_cast_oany:
"cast_any x y ⟹ cast_oany (any_to_oany x) (any_to_oany y)"
by (simp add: any_oany_eq_fun cast_oany.intros(1))
lemma cast_oany_implies_cast_any:
"cast_oany (any_to_oany x) (any_to_oany y) ⟹ cast_any x y"
by (cases x; cases y; simp add: any_oany.simps cast_oany.simps)
lemma cast_oany_closed_under_range:
"rel_closed_under cast_oany (range any_to_oany)"
proof -
define B where B: "B = range any_to_oany"
define P where P:
"P = (λ x x'. (x ∈ B ∧ x' ∈ B) ∨ (x ∈ -B ∧ x' ∈ -B))"
{
fix x x'
assume as_c: "cast_oany x x'"
have obv_p: "(OBoolVal ε) ∉ range any_to_oany"
proof -
have "⋀x. any_to_oany x ≠ (OBoolVal ε)"
using any_oany.simps any_oany_eq_fun by auto
then show ?thesis by fastforce
qed
have oia_p: "(OInvalidAny ε) ∉ range any_to_oany"
proof -
have "⋀x. any_to_oany x ≠ (OInvalidAny ε)"
using any_oany.simps any_oany_eq_fun by auto
then show ?thesis by fastforce
qed
have onv_p: "(ONatVal ε) ∉ range any_to_oany"
proof -
have "⋀x. any_to_oany x ≠ (ONatVal ε)"
using any_oany.simps any_oany_eq_fun by auto
then show ?thesis by fastforce
qed
have orv_p: "(ORealVal ε) ∉ range any_to_oany"
proof -
have "⋀x. any_to_oany x ≠ (ORealVal ε)"
using any_oany.simps any_oany_eq_fun by auto
then show ?thesis by fastforce
qed
have "cast_oany x x' ⟹ P x x'"
proof (induction rule: cast_oany.induct)
case (1 x y ox oy) then show ?case using B P any_oany_eq_fun by auto
next
case 2 then show ?case
proof -
from B obv_p have obv: "(OBoolVal ε) ∈ -B" by simp
from B oia_p have oia: "(OInvalidAny ε) ∈ -B" by simp
from P obv oia show ?thesis by auto
qed
next
case 3 then show ?case
proof -
from onv_p B have onv: "(ONatVal ε) ∈ -B" by simp
from orv_p B have orv: "(ORealVal ε) ∈ -B" by simp
from P onv orv show ?thesis by auto
qed
next
case 4 then show ?case
proof -
from orv_p B have orv: "(ORealVal ε) ∈ -B" by simp
from oia_p B have oia: "(OInvalidAny ε) ∈ -B" by simp
from P orv oia show ?thesis by auto
qed
qed
}
with B P show ?thesis by (simp add: rel_closed_under_def)
qed
lemma inj_any_to_oany: "inj any_to_oany"
proof
fix x x' :: any
assume as_1: "x ∈ UNIV"
assume as_2: "x' ∈ UNIV"
assume as_3: "any_to_oany x = any_to_oany x'"
show "x = x'"
proof (case_tac x)
show c_1: "⋀x1::bool⇩⊥. x = BoolVal x1 ⟹ x = x'"
by (metis any.exhaust any_to_oany.simps(1)
any_to_oany.simps(2) any_to_oany.simps(3) any_to_oany.simps(4)
as_3 nullable.inject oany.distinct(2) oany.distinct(4)
oany.inject(1) oany.simps(10))
show c_2: "⋀x2::nat⇩⊥. x = NatVal x2 ⟹ x = x'"
by (metis any_to_oany.cases any_to_oany.simps(1)
any_to_oany.simps(2) any_to_oany.simps(3) any_to_oany.simps(4)
as_3 nullable.inject oany.distinct(1) oany.distinct(9)
oany.inject(2) oany.simps(12))
show c_3: "⋀x3::real⇩⊥. x = RealVal x3 ⟹ x = x'"
by (metis any.distinct(12) any.distinct(4) any.distinct(8)
any_oany.cases any_oany.intros(3) any_to_oany.elims
any_to_oany.simps(1) any_to_oany.simps(3) as_3 nullable.inject
oany.distinct(12) oany.distinct(3) oany.inject(3) oany.simps(12))
show c_4: "⋀x4::unit. x = InvalidAny x4 ⟹ x = x'"
by (metis any.distinct(5) any_to_oany.cases any_to_oany.simps(1)
any_to_oany.simps(2) any_to_oany.simps(3) any_to_oany.simps(4) as_3
nullable.inject oany.distinct(5) oany.inject(4) oany.simps(14)
oany.simps(16))
qed
qed
lemma bij_any_to_oany: "bij_betw any_to_oany UNIV (range any_to_oany)"
using inj_any_to_oany by (simp add: bij_betw_def)
lemma tranclp_fun_preserve:
fixes x y :: any
assumes "cast_oany⇧+⇧+ (any_to_oany x) (any_to_oany y)"
shows "(λx y. cast_oany (any_to_oany x) (any_to_oany y))⇧+⇧+ x y"
using bij_any_to_oany cast_oany_closed_under_range assms
by (rule tranclp_fun_preserve_gen_1)
lemma tranclp_fun_preserve2:
fixes x y :: any
assumes as: "(λx y. cast_oany (any_to_oany x) (any_to_oany y))⇧+⇧+ x y"
shows "cast_oany⇧+⇧+ (any_to_oany x) (any_to_oany y)"
using bij_any_to_oany cast_oany_closed_under_range assms
by (rule tranclp_fun_preserve_gen_2)
end
备注:
rel_closed_under
标识关系是否在给定集合下关闭。引理rel_tcl_closed_under
表明,如果一个关系在给定集合下是封闭的,那么这个关系的传递闭包也在这个集合下关闭。来自对原始问题的回答的lemmas tranclp_fun_preserve_1
和tranclp_fun_preserve_2
被修改并分别重命名为tranclp_fun_preserve_gen_1
和tranclp_fun_preserve_gen_2
。 qmxswpoi和tranclp_fun_preserve_gen_1
表示tranclp_fun_preserve_gen_2
保留了封闭的属性,如果f
是它的域和集合f
之间的双射,并且关系在集合B
下关闭。引理B
显示cast_oany_closed_under_range
在cast_oany
范围内关闭。引理any_to_oany
表明bij_any_to_oany
在其域和范围之间是双射的。 lemmas any_to_oany
和tranclp_fun_preserve
的证据直接来自tranclp_fun_preserve2
和tranclp_fun_preserve_gen_1
。