Theory HOLCFUtils
section ‹HOLCF Utility lemmas›
theory HOLCFUtils
imports HOLCF
begin
text ‹
We use @{theory HOLCF} to define the denotational semantics. By default, HOLCF does not turn the regular ‹set› type into a partial order, so this is done here. Some of the lemmas here are contributed by Brian Huffman.
We start by making the type ‹bool› a pointed chain-complete partial order.
›
instantiation bool :: po
begin
definition
"x ⊑ y ⟷ (x ⟶ y)"
instance by standard (unfold below_bool_def, fast+)
end
instance bool :: chfin
apply standard
apply (drule finite_range_imp_finch)
apply (rule finite)
apply (simp add: finite_chain_def)
done
instance bool :: pcpo
proof
have "∀y. False ⊑ y" by (simp add: below_bool_def)
thus "∃x::bool. ∀y. x ⊑ y" ..
qed
lemma is_lub_bool: "S <<| (True ∈ S)"
unfolding is_lub_def is_ub_def below_bool_def by auto
lemma lub_bool: "lub S = (True ∈ S)"
using is_lub_bool by (rule lub_eqI)
lemma bottom_eq_False[simp]: "⊥ = False"
by (rule below_antisym [OF minimal], simp add: below_bool_def)
text ‹
To convert between the squared syntax used by @{theory HOLCF} and the regular, round syntax for sets, we state some of the equivalencies.
›
instantiation set :: (type) po
begin
definition
"A ⊑ B ⟷ A ⊆ B"
instance by standard (unfold below_set_def, fast+)
end
lemma sqsubset_is_subset: "A ⊑ B ⟷ A ⊆ B"
by (fact below_set_def)
lemma is_lub_set: "S <<| ⋃S"
unfolding is_lub_def is_ub_def below_set_def by fast
lemma lub_is_union: "lub S = ⋃S"
using is_lub_set by (rule lub_eqI)
instance set :: (type) cpo
by standard (fast intro: is_lub_set)
lemma emptyset_is_bot[simp]: "{} ⊑ S"
by (simp add:sqsubset_is_subset)
instance set :: (type) pcpo
by standard (fast intro: emptyset_is_bot)
lemma bot_bool_is_emptyset[simp]: "⊥ = {}"
using emptyset_is_bot by (rule bottomI [symmetric])
text ‹
To actually use these instance in ‹fixrec› definitions or fixed-point inductions, we need continuity requrements for various boolean and set operations.
›
lemma cont2cont_disj [simp, cont2cont]:
assumes f: "cont (λx. f x)" and g: "cont (λx. g x)"
shows "cont (λx. f x ∨ g x)"
apply (rule cont_apply [OF f])
apply (rule chfindom_monofun2cont)
apply (rule monofunI, simp add: below_bool_def)
apply (rule cont_compose [OF _ g])
apply (rule chfindom_monofun2cont)
apply (rule monofunI, simp add: below_bool_def)
done
lemma cont2cont_imp[simp, cont2cont]:
assumes f: "cont (λx. ¬ f x)" and g: "cont (λx. g x)"
shows "cont (λx. f x ⟶ g x)"
unfolding imp_conv_disj by (rule cont2cont_disj[OF f g])
lemma cont2cont_Collect [simp, cont2cont]:
assumes "⋀y. cont (λx. f x y)"
shows "cont (λx. {y. f x y})"
apply (rule contI)
apply (subst cont2contlubE [OF assms], assumption)
apply (auto simp add: is_lub_def is_ub_def below_set_def lub_bool)
done
lemma cont2cont_mem [simp, cont2cont]:
assumes "cont (λx. f x)"
shows "cont (λx. y ∈ f x)"
apply (rule cont_compose [OF _ assms])
apply (rule contI)
apply (auto simp add: is_lub_def is_ub_def below_bool_def lub_is_union)
done
lemma cont2cont_union [simp, cont2cont]:
"cont (λx. f x) ⟹ cont (λx. g x)
⟹ cont (λx. f x ∪ g x)"
unfolding Un_def by simp
lemma cont2cont_insert [simp, cont2cont]:
assumes "cont (λx. f x)"
shows "cont (λx. insert y (f x))"
unfolding insert_def using assms
by (intro cont2cont)
lemmas adm_subset = adm_below[where ?'b = "'a::type set", unfolded sqsubset_is_subset]
lemma cont2cont_UNION[cont2cont,simp]:
assumes "cont f"
and "⋀ y. cont (λx. g x y)"
shows "cont (λx. ⋃y∈ f x. g x y)"
proof(induct rule: contI2[case_names Mono Limit])
case Mono
show "monofun (λx. ⋃y∈f x. g x y)"
by (rule monofunI)(auto iff:sqsubset_is_subset dest: monofunE[OF assms(1)[THEN cont2mono]] monofunE[OF assms(2)[THEN cont2mono]])
next
case (Limit Y)
have "(⋃y∈f (⨆ i. Y i). g (⨆ j. Y j) y) ⊆ (⨆ k. ⋃y∈f (Y k). g (Y k) y)"
proof
fix x assume "x ∈ (⋃y∈f (⨆ i. Y i). g (⨆ j. Y j) y)"
then obtain y where "y∈f (⨆ i. Y i)" and "x∈ g (⨆ j. Y j) y" by auto
hence "y ∈ (⨆ i. f (Y i))" and "x∈ (⨆ j. g (Y j) y)" by (auto simp add: cont2contlubE[OF assms(1) Limit(1)] cont2contlubE[OF assms(2) Limit(1)])
then obtain i and j where yi: "y∈ f (Y i)" and xj: "x∈ g (Y j) y" by (auto simp add:lub_is_union)
obtain k where "i≤k" and "j≤k" by (erule_tac x = "max i j" in meta_allE)auto
from yi and xj have "y ∈ f (Y k)" and "x∈ g (Y k) y"
using monofunE[OF assms(1)[THEN cont2mono], OF chain_mono[OF Limit(1) ‹i≤k›]]
and monofunE[OF assms(2)[THEN cont2mono], OF chain_mono[OF Limit(1) ‹j≤k›]]
by (auto simp add:sqsubset_is_subset)
hence "x∈ (⋃y∈ f (Y k). g (Y k) y)" by auto
thus "x∈ (⨆ k. ⋃y∈f (Y k). g (Y k) y)" by (auto simp add:lub_is_union)
qed
thus ?case by (simp add:sqsubset_is_subset)
qed
lemma cont2cont_Let_simple[simp,cont2cont]:
assumes "cont (λx. g x t)"
shows "cont (λx. let y = t in g x y)"
unfolding Let_def using assms .
lemma cont2cont_case_list [simp, cont2cont]:
assumes "⋀y. cont (λx. f1 x)"
and "⋀y z. cont (λx. f2 x y z)"
shows "cont (λx. case_list (f1 x) (f2 x) l)"
using assms
by (cases l) auto
text ‹As with the continuity lemmas, we need admissibility lemmas.›
lemma adm_not_mem:
assumes "cont (λx. f x)"
shows "adm (λx. y ∉ f x)"
using assms
apply (erule_tac t = f in adm_subst)
proof (rule admI)
fix Y :: "nat ⇒ 'b set"
assume chain: "chain Y"
assume "∀i. y ∉ Y i" hence "(⨆ i. y ∈ Y i) = False"
by auto
thus "y ∉ (⨆ i. Y i)"
using chain unfolding lub_bool lub_is_union by auto
qed
lemma adm_id[simp]: "adm (λx . x)"
by (rule adm_chfin)
lemma adm_Not[simp]: "adm Not"
by (rule adm_chfin)
lemma adm_prod_split:
assumes "adm (λp. f (fst p) (snd p))"
shows "adm (λ(x,y). f x y)"
using assms unfolding split_def .
lemma adm_ball':
assumes "⋀ y. adm (λx. y ∈ A x ⟶ P x y)"
shows "adm (λx. ∀y ∈ A x . P x y)"
by (subst Ball_def, rule adm_all[OF assms])
lemma adm_not_conj:
"⟦adm (λx. ¬ P x); adm (λx. ¬ Q x)⟧ ⟹ adm (λx. ¬ (P x ∧ Q x))"
by simp
lemma adm_single_valued:
assumes "cont (λx. f x)"
shows "adm (λx. single_valued (f x))"
using assms
unfolding single_valued_def
by (intro adm_lemmas adm_not_mem cont2cont adm_subst[of f])
text ‹
To match Shivers' syntax we introduce the power-syntax for iterated function application.
›
abbreviation niceiterate (‹(_⇗_⇖)› [1000] 1000)
where "niceiterate f i ≡ iterate i⋅f"
end