(******************************************************************************)
(* Project: Isabelle/UTP Toolkit *)
(* File: Finite_Fun.thy *)
(* Authors: Simon Foster and Frank Zeyda *)
(* Emails: simon.foster@york.ac.uk and frank.zeyda@york.ac.uk *)
(******************************************************************************)
section ‹ Finite Functions ›
theory Finite_Fun
imports Map_Extra Partial_Fun FSet_Extra
begin
subsection ‹ Finite function type and operations ›
typedef ('a, 'b) ffun = "{f :: ('a, 'b) pfun. finite(pdom(f))}"
morphisms pfun_of Abs_pfun
by (rule_tac x="{}p " in exI, auto)
setup_lifting type_definition_ffun
lift_definition ffun_app :: "('a, 'b) ffun ==> 'a ==> 'b" (‹ _'(_')f › [999 ,0 ] 999 ) is "pfun_app" .
lift_definition ffun_upd :: "('a, 'b) ffun ==> 'a ==> 'b ==> ('a, 'b) ffun" is "pfun_upd" by simp
lift_definition fdom :: "('a, 'b) ffun ==> 'a set" is pdom .
lift_definition fran :: "('a, 'b) ffun ==> 'b set" is pran .
lift_definition ffun_comp :: "('b, 'c) ffun ==> ('a, 'b) ffun ==> ('a, 'c) ffun" (infixl ‹ ∘ f › 55 ) is pfun_comp by auto
lift_definition ffun_member :: "'a × 'b ==> ('a, 'b) ffun ==> bool" (infix ‹ ∈ f › 50 ) is "(∈ p )" .
lift_definition fdom_res :: "'a set ==> ('a, 'b) ffun ==> ('a, 'b) ffun" (infixl ‹ ⊲ f › 85 )
is "pdom_res" by simp
lift_definition fran_res :: "('a, 'b) ffun ==> 'b set ==> ('a, 'b) ffun" (infixl ‹ ⊳ f › 85 )
is pran_res by simp
lift_definition ffun_graph :: "('a, 'b) ffun ==> ('a × 'b) set" is pfun_graph .
lift_definition graph_ffun :: "('a × 'b) set ==> ('a, 'b) ffun" is
"λ R. if (finite (Domain R)) then graph_pfun R else pempty"
by (simp add: finite_Domain)
instantiation ffun :: (type, type) zero
begin
lift_definition zero_ffun :: "('a, 'b) ffun" is "0" by simp
instance ..
end
abbreviation fempty :: "('a, 'b) ffun" (‹ {}f › )
where "fempty ≡ 0"
instantiation ffun :: (type, type) plus
begin
lift_definition plus_ffun :: "('a, 'b) ffun ==> ('a, 'b) ffun ==> ('a, 'b) ffun" is "(+)" by simp
instance ..
end
instantiation ffun :: (type, type) minus
begin
lift_definition minus_ffun :: "('a, 'b) ffun ==> ('a, 'b) ffun ==> ('a, 'b) ffun" is "(-)"
by (metis finite_Diff finite_Domain pdom_graph_pfun pdom_pfun_graph_finite pfun_graph_inv pfun_graph_minus)
instance ..
end
instance ffun :: (type, type) monoid_add
by (intro_classes, (transfer, simp add: add.assoc)+)
instantiation ffun :: (type, type) inf
begin
lift_definition inf_ffun :: "('a, 'b) ffun ==> ('a, 'b) ffun ==> ('a, 'b) ffun" is inf
by (meson finite_Int infinite_super pdom_inter)
instance ..
end
abbreviation ffun_inter :: "('a, 'b) ffun ==> ('a, 'b) ffun ==> ('a, 'b) ffun" (infixl ‹ ∩ f › 80 )
where "ffun_inter ≡ inf"
instantiation ffun :: (type, type) order
begin
lift_definition less_eq_ffun :: "('a, 'b) ffun ==> ('a, 'b) ffun ==> bool" is
"λ f g. f ⊆ p g" .
lift_definition less_ffun :: "('a, 'b) ffun ==> ('a, 'b) ffun ==> bool" is
"λ f g. f < g" .
instance
by (intro_classes, (transfer, auto)+)
end
abbreviation ffun_subset :: "('a, 'b) ffun ==> ('a, 'b) ffun ==> bool" (infix ‹ ⊂ f › 50 )
where "ffun_subset ≡ less"
abbreviation ffun_subset_eq :: "('a, 'b) ffun ==> ('a, 'b) ffun ==> bool" (infix ‹ ⊆ f › 50 )
where "ffun_subset_eq ≡ less_eq"
instance ffun :: (type, type) semilattice_inf
by (intro_classes, (transfer, auto)+)
lemma ffun_subset_eq_least [simp]:
"{}f ⊆ f f"
by (transfer, auto)
syntax
"_FfunUpd" :: "[('a, 'b) ffun, maplets] => ('a, 'b) ffun" (‹ _'(_')f › [900 ,0 ]900 )
"_Ffun" :: "maplets => ('a, 'b) ffun" (‹ (1{_}f )› )
syntax_consts
"_FfunUpd" "_Ffun" ⇌ ffun_upd
translations
"_FfunUpd m (_Maplets xy ms)" == "_FfunUpd (_FfunUpd m xy) ms"
"_FfunUpd m (_maplet x y)" == "CONST ffun_upd m x y"
"_Ffun ms" => "_FfunUpd (CONST fempty) ms"
"_Ffun (_Maplets ms1 ms2)" <= "_FfunUpd (_Ffun ms1) ms2"
"_Ffun ms" <= "_FfunUpd (CONST fempty) ms"
subsection ‹ Algebraic laws ›
lemma ffun_comp_assoc: "f ∘ f (g ∘ f h) = (f ∘ f g) ∘ f h"
by (transfer, simp add: pfun_comp_assoc)
lemma pfun_override_dist_comp:
"(f + g) ∘ f h = (f ∘ f h) + (g ∘ f h)"
by (transfer, simp add: pfun_override_dist_comp)
lemma ffun_minus_unit [simp]:
fixes f :: "('a, 'b) ffun"
shows "f - 0 = f"
by (transfer, simp)
lemma ffun_minus_zero [simp]:
fixes f :: "('a, 'b) ffun"
shows "0 - f = 0"
by (transfer, simp)
lemma ffun_minus_self [simp]:
fixes f :: "('a, 'b) ffun"
shows "f - f = 0"
by (transfer, simp)
lemma ffun_plus_commute:
"fdom(f) ∩ fdom(g) = {} ==> f + g = g + f"
by (transfer, metis pfun_plus_commute)
lemma ffun_minus_plus_commute:
"fdom(g) ∩ fdom(h) = {} ==> (f - g) + h = (f + h) - g"
by (transfer, simp add: pfun_minus_plus_commute)
lemma ffun_plus_minus:
"f ⊆ f g ==> (g - f) + f = g"
by (transfer, simp add: pfun_plus_minus)
lemma ffun_minus_common_subset:
"[ h ⊆ f f; h ⊆ f g ] ==> (f - h = g - h) = (f = g)"
by (transfer, simp add: pfun_minus_common_subset)
lemma ffun_minus_plus:
"fdom(f) ∩ fdom(g) = {} ==> (f + g) - g = f"
by (transfer, simp add: pfun_minus_plus)
lemma ffun_plus_pos: "x + y = {}f ==> x = {}f "
by (transfer, simp add: pfun_plus_pos)
lemma ffun_le_plus: "fdom x ∩ fdom y = {} ==> x ≤ x + y"
by (transfer, simp add: pfun_le_plus)
subsection ‹ Membership, application, and update ›
lemma ffun_ext: "[ ∧ x y. (x, y) ∈ f f ⟷ (x, y) ∈ f g ] ==> f = g"
by (transfer, simp add: pfun_ext)
lemma ffun_member_alt_def:
"(x, y) ∈ f f ⟷ (x ∈ fdom f ∧ f(x)f = y)"
by (transfer, simp add: pfun_member_alt_def)
lemma ffun_member_plus:
"(x, y) ∈ f f + g ⟷ ((x ∉ fdom(g) ∧ (x, y) ∈ f f) ∨ (x, y) ∈ f g)"
by (transfer, simp add: pfun_member_plus)
lemma ffun_member_minus:
"(x, y) ∈ f f - g ⟷ (x, y) ∈ f f ∧ (¬ (x, y) ∈ f g)"
by (transfer, simp add: pfun_member_minus)
lemma ffun_app_upd_1 [simp]: "x = y ==> (f(x ↦ v)f )(y)f = v"
by (transfer, simp)
lemma ffun_app_upd_2 [simp]: "x ≠ y ==> (f(x ↦ v)f )(y)f = f(y)f "
by (transfer, simp)
lemma ffun_upd_ext [simp]: "x ∈ fdom(f) ==> f(x ↦ f(x)f )f = f"
by (transfer, simp)
lemma ffun_app_add [simp]: "x ∈ fdom(g) ==> (f + g)(x)f = g(x)f "
by (transfer, simp)
lemma ffun_upd_add [simp]: "f + g(x ↦ v)f = (f + g)(x ↦ v)f "
by (transfer, simp)
lemma ffun_upd_twice [simp]: "f(x ↦ u, x ↦ v)f = f(x ↦ v)f "
by (transfer, simp)
lemma ffun_upd_comm:
assumes "x ≠ y"
shows "f(y ↦ u, x ↦ v)f = f(x ↦ v, y ↦ u)f "
using assms by (transfer, simp add: pfun_upd_comm)
lemma ffun_upd_comm_linorder [simp]:
fixes x y :: "'a :: linorder"
assumes "x < y"
shows "f(y ↦ u, x ↦ v)f = f(x ↦ v, y ↦ u)f "
using assms by (transfer, auto)
lemma ffun_app_minus [simp]: "x ∉ fdom g ==> (f - g)(x)f = f(x)f "
by (transfer, auto)
lemma ffun_upd_minus [simp]:
"x ∉ fdom g ==> (f - g)(x ↦ v)f = (f(x ↦ v)f - g)"
by (transfer, auto)
lemma fdom_member_minus_iff [simp]:
"x ∉ fdom g ==> x ∈ fdom(f - g) ⟷ x ∈ fdom(f)"
by (transfer, simp)
lemma fsubseteq_ffun_upd1 [intro]:
"[ f ⊆ f g; x ∉ fdom(g) ] ==> f ⊆ f g(x ↦ v)f "
by (transfer, auto)
lemma fsubseteq_ffun_upd2 [intro]:
"[ f ⊆ f g; x ∉ fdom(f) ] ==> f ⊆ f g(x ↦ v)f "
by (transfer, auto)
lemma psubseteq_pfun_upd3 [intro]:
"[ f ⊆ f g; g(x)f = v ] ==> f ⊆ f g(x ↦ v)f "
by (transfer, auto)
lemma fsubseteq_dom_subset:
"f ⊆ f g ==> fdom(f) ⊆ fdom(g)"
by (transfer, auto simp add: psubseteq_dom_subset)
lemma fsubseteq_ran_subset:
"f ⊆ f g ==> fran(f) ⊆ fran(g)"
by (transfer, simp add: psubseteq_ran_subset)
subsection ‹ Domain laws ›
lemma fdom_finite [simp]: "finite(fdom(f))"
by (transfer, simp)
lemma fdom_zero [simp]: "fdom 0 = {}"
by (transfer, simp)
lemma fdom_plus [simp]: "fdom (f + g) = fdom f ∪ fdom g"
by (transfer, auto)
lemma fdom_inter: "fdom (f ∩ f g) ⊆ fdom f ∩ fdom g"
by (transfer, meson pdom_inter)
lemma fdom_comp [simp]: "fdom (g ∘ f f) = fdom (f ⊳ f fdom g)"
by (transfer, auto)
lemma fdom_upd [simp]: "fdom (f(k ↦ v)f ) = insert k (fdom f)"
by (transfer, simp)
lemma fdom_fdom_res [simp]: "fdom (A ⊲ f f) = A ∩ fdom(f)"
by (transfer, auto)
lemma fdom_graph_ffun [simp]:
"finite (Domain R) ==> fdom (graph_ffun R) = Domain R"
by (transfer, simp add: Domain_fst graph_map_dom)
subsection ‹ Range laws ›
lemma fran_zero [simp]: "fran 0 = {}"
by (transfer, simp)
lemma fran_upd [simp]: "fran (f(k ↦ v)f ) = insert v (fran ((- {k}) ⊲ f f))"
by (transfer, auto)
lemma fran_fran_res [simp]: "fran (f ⊳ f A) = fran(f) ∩ A"
by (transfer, auto)
lemma fran_comp [simp]: "fran (g ∘ f f) = fran (fran f ⊲ f g)"
by (transfer, auto)
subsection ‹ Domain restriction laws ›
lemma fdom_res_zero [simp]: "A ⊲ f {}f = {}f "
by (transfer, auto)
lemma fdom_res_empty [simp]:
"({} ⊲ f f) = {}f "
by (transfer, auto)
lemma fdom_res_fdom [simp]:
"fdom(f) ⊲ f f = f"
by (transfer, auto)
lemma pdom_res_upd_in [simp]:
"k ∈ A ==> A ⊲ f f(k ↦ v)f = (A ⊲ f f)(k ↦ v)f "
by (transfer, auto)
lemma pdom_res_upd_out [simp]:
"k ∉ A ==> A ⊲ f f(k ↦ v)f = A ⊲ f f"
by (transfer, auto)
lemma fdom_res_override [simp]: "A ⊲ f (f + g) = (A ⊲ f f) + (A ⊲ f g)"
by (metis fdom_res.rep_eq pdom_res_override pfun_of_inject plus_ffun.rep_eq)
lemma fdom_res_minus [simp]: "A ⊲ f (f - g) = (A ⊲ f f) - g"
by (transfer, auto)
lemma fdom_res_swap: "(A ⊲ f f) ⊳ f B = A ⊲ f (f ⊳ f B)"
by (transfer, simp add: pdom_res_swap)
lemma fdom_res_twice [simp]: "A ⊲ f (B ⊲ f f) = (A ∩ B) ⊲ f f"
by (transfer, auto)
lemma fdom_res_comp [simp]: "A ⊲ f (g ∘ f f) = g ∘ f (A ⊲ f f)"
by (transfer, simp)
subsection ‹ Range restriction laws ›
lemma fran_res_zero [simp]: "{}f ⊳ f A = {}f "
by (transfer, auto)
lemma fran_res_upd_1 [simp]: "v ∈ A ==> f(x ↦ v)f ⊳ f A = (f ⊳ f A)(x ↦ v)f "
by (transfer, auto)
lemma fran_res_upd_2 [simp]: "v ∉ A ==> f(x ↦ v)f ⊳ f A = ((- {x}) ⊲ f f) ⊳ f A"
by (transfer, auto)
lemma fran_res_override: "(f + g) ⊳ f A ⊆ f (f ⊳ f A) + (g ⊳ f A)"
by (transfer, simp add: pran_res_override)
subsection ‹ Graph laws ›
lemma ffun_graph_inv: "graph_ffun (ffun_graph f) = f"
by (transfer, auto simp add: pfun_graph_inv finite_Domain)
lemma ffun_graph_zero: "ffun_graph 0 = {}"
by (transfer, simp add: pfun_graph_zero)
lemma ffun_graph_minus: "ffun_graph (f - g) = ffun_graph f - ffun_graph g"
by (transfer, simp add: pfun_graph_minus)
lemma ffun_graph_inter: "ffun_graph (f ∩ f g) = ffun_graph f ∩ ffun_graph g"
by (transfer, simp add: pfun_graph_inter)
subsection ‹ Partial Function Lens ›
definition ffun_lens :: "'a ==> ('b ==> ('a, 'b) ffun)" where
[lens_defs]: "ffun_lens i = ( lens_get = λ s. s(i)f , lens_put = λ s v. s(i ↦ v)f ) "
lemma ffun_lens_mwb [simp]: "mwb_lens (ffun_lens i)"
by (unfold_locales, simp_all add: ffun_lens_def)
lemma ffun_lens_src: "S i = {f. i ∈ fdom(f)}"
by (auto simp add: lens_defs lens_source_def, metis ffun_upd_ext)
text ‹ Hide implementation details for finite functions ›
lifting_update ffun.lifting
lifting_forget ffun.lifting
end
Messung V0.5 in Prozent C=87 H=99 G=93
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland