Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Archive-of-Formal-Proofs/thys/Stable_Matching/   (Sammlung formaler Beweise Version 2026-5©)  Datei vom 29.4.2026 mit Größe 20 kB image not shown  

Quelle  Basis.thy

  Sprache: Isabelle
 

(*<*)
theory Basis
imports
  Main
  "HOL-Library.While_Combinator"
begin

(*>*)
section Preliminaries

(*>*)(*<*)

subsection HOL Detritus

lemma Above_union:
  shows "x Above r (X Y) x Above r X x Above r Y"
unfolding Above_def by blast

lemma Above_Field:
  assumes "x Above r X"
  shows "x Field r"
using assms unfolding Above_def by blast

lemma AboveS_Field:
  assumes "x AboveS r X"
  shows "x Field r"
using assms unfolding AboveS_def by blast

lemma Above_Linear_singleton:
  assumes "x Field r"
  assumes "Linear_order r"
  shows "x Above r {x}"
using assms unfolding Above_def order_on_defs by (force dest: refl_onD)

lemma subseqs_set:
  assumes "y set (subseqs xs)"
  shows "set y set xs"
using assms by (metis Pow_iff image_eqI subseqs_powset)

primrec map_of_default :: "'v ==> ('k × 'v) list ==> 'k ==> 'v" where
  "map_of_default v0 [] k = v0"
"map_of_default v0 (kv # kvs) k = (if k = fst kv then snd kv else map_of_default v0 kvs k)"

lemmas set_elem_equalityI = Set.equalityI[OF Set.subsetI Set.subsetI]

lemmas total_onI = iffD2[OF total_on_def, rule_format]

lemma partial_order_on_acyclic:
  assumes "partial_order_on A r"
  shows "acyclic (r - Id)"
by (metis acyclic_irrefl assms irrefl_diff_Id partial_order_on_def preorder_on_def trancl_id trans_diff_Id)

lemma finite_Linear_order_induct[consumes 3, case_names step]:
  assumes "Linear_order r"
  assumes "x Field r"
  assumes "finite r"
  assumes step: "x. [x Field r; y. y aboveS r x ==> P y] ==> P x"
  shows "P x"
using assms(2)
proof(induct rule: wf_induct[of "r-1 - Id"])
  from assms(1,3show "wf (r-1 - Id)"
    using linear_order_on_well_order_on linear_order_on_converse
    unfolding well_order_on_def by blast
next
  case (2 x) then show ?case
    by - (rule step; auto simp: aboveS_def intro: FieldI2)
qed

text

  sometimes want a notion of monotonicity over some set.

 


definition mono_on :: "'a::order set ==> ('a ==> 'b::order) ==> bool" where
  "mono_on A f = (xA. yA. x y f x f y)"

lemmas mono_onI = iffD2[OF mono_on_def, rule_format]
lemmas mono_onD = iffD1[OF mono_on_def, rule_format]

lemma mono_onE:
  "[mono_on A f; x A; y A; x y; f x f y ==> thesis] ==> thesis"
using mono_onD by blast

lemma mono_on_mono:
  "mono_on UNIV = mono"
by (clarsimp simp: mono_on_def mono_def fun_eq_iff)


(*>*)
subsection MaxR: maximum elements of linear orders

text

  generalize the existing @{const "max"} and @{const "Max"} functions
  work on orders defined over sets. See \S\ref{sec:cf-linear} for
 -function related lemmas.

 


locale MaxR =
  fixes r :: "'a::finite rel"
  assumes r_Linear_order: "Linear_order r"
begin

text

  basic function chooses the largest of two elements:

 


definition maxR :: "'a ==> 'a ==> 'a" where
  "maxR x y = (if (x, y) r then y else x)"
(*<*)

lemma maxR_domain:
  shows "{x, y} A ==> maxR x y A"
unfolding maxR_def by simp

lemma maxR_range:
  shows "maxR x y {x, y}"
unfolding maxR_def by simp

lemma maxR_rangeD:
  "maxR x y x ==> maxR x y = y"
  "maxR x y y ==> maxR x y = x"
unfolding maxR_def by auto

lemma maxR_idem:
  shows "maxR x x = x"
unfolding maxR_def by simp

lemma maxR_absorb2:
  shows "(x, y) r ==> maxR x y = y"
unfolding maxR_def by simp

lemma maxR_absorb1:
  shows "(y, x) r ==> maxR x y = x"
using r_Linear_order unfolding maxR_def by (simp add: order_on_defs antisym_def)

lemma maxR_assoc:
  shows "{x,y,z} Field r ==> maxR (maxR x y) z = maxR x (maxR y z)"
using r_Linear_order unfolding maxR_def by simp (metis order_on_defs(1-3) total_on_def trans_def)

lemma maxR_commute:
  shows "{x,y} Field r ==> maxR x y = maxR y x"
using r_Linear_order unfolding maxR_def by (fastforce simp: order_on_defs antisym_def total_on_def)

lemmas maxR_simps =
  maxR_idem
  maxR_absorb1
  maxR_absorb2

(*>*)
text

  hoist this to finite sets using the @{const "Finite_Set.fold"}
 . For code generation purposes it seems inevitable that we
  to fuse the fold and filter into a single total recursive
 .

 


definition MaxR_f :: "'a ==> 'a option ==> 'a option" where
  "MaxR_f x acc = (if x Field r then Some (case acc of None ==> x | Some y ==> maxR x y) else acc)"

interpretation MaxR_f: comp_fun_idem MaxR_f
using %invisible r_Linear_order
by unfold_locales (fastforce simp: fun_eq_iff maxR_def MaxR_f_def order_on_defs total_on_def antisymD elim: transE split: option.splits)+

definition MaxR_opt :: "'a set ==> 'a option" where
  MaxR_opt_eq_fold': "MaxR_opt A = Finite_Set.fold MaxR_f None A"
(*<*)

lemma empty [simp]:
  shows "MaxR_opt {} = None"
by (simp add: MaxR_opt_eq_fold')

lemma
  shows insert: "MaxR_opt (insert x A) = (if x Field r then Some (case MaxR_opt A of None ==> x | Some y ==> maxR x y) else MaxR_opt A)"
    and range_Some[rule_format]: "MaxR_opt A = Some a a A Field r"
using finite[of A] by induct (auto simp: MaxR_opt_eq_fold' maxR_def MaxR_f_def split: option.splits)

lemma range_None:
  assumes "MaxR_opt A = None"
  shows "A Field r = {}"
using assms by (metis Int_iff insert all_not_in_conv insert_absorb option.simps(3))

lemma domain_empty:
  assumes "A Field r = {}"
  shows "MaxR_opt A = None"
using assms by (metis empty_iff option.exhaust range_Some)

lemma domain:
  shows "MaxR_opt (A Field r) = MaxR_opt A"
using finite[of A] by induct (simp_all add: insert)

lemmas MaxR_opt_code = MaxR_opt_eq_fold'[where A="set A", unfolded MaxR_f.fold_set_fold] for A

lemma range:
  shows "MaxR_opt A Some ` (A Field r) {None}"
using range_Some notin_range_Some by fastforce

lemma union:
  shows "MaxR_opt (A B) = (case MaxR_opt A of None ==> MaxR_opt B | Some mA ==> Some (case MaxR_opt B of None ==> mA | Some mB ==> maxR mA mB))"
using finite[of A] by induct (auto simp: maxR_assoc insert dest!: range_Some split: option.splits)

lemma mono:
  assumes "MaxR_opt A = Some x"
  shows "y. MaxR_opt (A B) = Some y (x, y) r"
using finite[of B]
proof induct
  case empty with assms show ?case
    using range_Some underS_incl_iff[OF r_Linear_order] by fastforce
next
  note ins = insert
  case (insert b B) with assms r_Linear_order show ?case
    unfolding order_on_defs total_on_def by (fastforce simp: ins maxR_def elim: transE intro: FieldI1)
qed


declare [[simproc del: eliminate_false_implies]]

lemma MaxR_opt_is_greatest:
  assumes "MaxR_opt A = Some x"
  assumes "y A Field r"
  shows "(y, x) r"
using finite[of A] assms
proof(induct arbitrary: x)
  note ins = insert
  case (insert a A)
  show ?case
  proof (cases "y = x")
    case True
    thus "(y, x) r"
      using r_Linear_order insert by (auto simp: order_on_defs refl_on_def)
  next
    case False
    show "(y, x) r"
    proof (rule ccontr)
      assume "(y, x) r"
      from insert have "x Field r" "y Field r"
        by (auto simp: maxR_def ins dest!: range_None range_Some split: if_splits option.splits)
      from (y, x) r and y x and insert obtain z where z: "(x, z) r" "(y, z) r" "z Field r"
        by (auto simp: maxR_def ins dest!: range_None range_Some split: if_splits option.splits)
      have "(x, y) r"
        using r_Linear_order (y, x) r x Field r y Field r y x
        by (auto simp: order_on_defs total_on_def)
      have "trans r"
        using r_Linear_order by (auto simp: order_on_defs)
      from this and (x, y) r and (y, z) r have "(x, z) r"
        by (rule transD)
      with (x, z) r show False by contradiction
    qed
  qed
qed simp

lemma greatest_is_MaxR_opt:
  assumes "x A Field r"
  assumes "y A Field r. (y, x) r"
  shows "MaxR_opt A = Some x"
using finite[of A] assms
proof(induct arbitrary: x)
  note ins = insert
  case (insert a A) then show ?case
    using maxR_absorb1 maxR_absorb2
    by (fastforce simp: maxR_def ins dest: range_None range_Some split: option.splits)
qed simp

lemma subset:
  assumes "set_option (MaxR_opt B) A"
  assumes "A B"
  shows "MaxR_opt B = MaxR_opt A"
using union[where A=A and B="B-A"] range[of "B - A"] assms
by (auto simp: Un_absorb1 finite_subset maxR_def split: option.splits)

(*>*)

end

interpretation MaxR_empty: MaxR "{}"
by unfold_locales simp

interpretation MaxR_singleton: MaxR "{(x,x)}" for x
by unfold_locales simp

lemma MaxR_r_domain [iff]:
  assumes "MaxR r"
  shows "MaxR (Restr r A)"
using assms Linear_order_Restr unfolding MaxR_def by blast


subsection Linear orders from lists

text

  the easiest way to specify a concrete linear order is with a
 . Here these run from greatest to least.

 


primrec linord_of_listP :: "'a ==> 'a ==> 'a list ==> bool" where
  "linord_of_listP x y [] False"
"linord_of_listP x y (z # zs) (z = y x set (z # zs)) linord_of_listP x y zs"

definition linord_of_list :: "'a list ==> 'a rel" where
  "linord_of_list xs {(x, y). linord_of_listP x y xs}"

(*<*)

lemma linord_of_list_linord_of_listP:
  shows "xy linord_of_list xs linord_of_listP (fst xy) (snd xy) xs"
unfolding linord_of_list_def split_def by simp

lemma linord_of_listP_linord_of_list:
  shows "linord_of_listP x y xs (x, y) linord_of_list xs"
unfolding linord_of_list_def by simp

lemma linord_of_listP_empty:
  shows "(x y. ¬linord_of_listP x y xs) xs = []"
by (metis linord_of_listP.simps list.exhaust list.set_intros(1))

lemma linord_of_listP_domain:
  assumes "linord_of_listP x y xs"
  shows "x set xs y set xs"
using assms by (induct xs) auto

lemma linord_of_list_empty[iff]:
  "linord_of_list [] = {}"
  "linord_of_list xs = {} xs = []"
unfolding linord_of_list_def by (simp_all add: linord_of_listP_empty)

lemma linord_of_list_singleton:
  "(x, y) linord_of_list [z] x = z y = z"
by (force simp: linord_of_list_linord_of_listP)

lemma linord_of_list_range:
  "linord_of_list xs set xs × set xs"
unfolding linord_of_list_def by (induct xs) auto

lemma linord_of_list_Field [simp]:
  "Field (linord_of_list xs) = set xs"
unfolding linord_of_list_def by (induct xs) (auto simp: Field_def)

lemma linord_of_listP_append:
  "linord_of_listP x y (xs @ ys) linord_of_listP x y xs linord_of_listP x y ys (y set xs x set ys)"
by (induct xs) auto

lemma linord_of_list_append:
  "(x, y) linord_of_list (xs @ ys) (x, y) linord_of_list xs (x, y) linord_of_list ys (y set xs x set ys)"
unfolding linord_of_list_def by (simp add: linord_of_listP_append)

lemma linord_of_list_refl_on:
  shows "refl_on (set xs) (linord_of_list xs)"
unfolding linord_of_list_def
by (induct xs) (auto intro!: refl_onI simp: refl_onD dest: refl_onD subsetD[OF linord_of_list_range])

lemma linord_of_list_trans:
  assumes "distinct xs"
  shows "trans (linord_of_list xs)"
using assms unfolding linord_of_list_def
by (induct xs) (auto intro!: transI dest: linord_of_listP_domain elim: transE)

lemma linord_of_list_antisym:
  assumes "distinct xs"
  shows "antisym (linord_of_list xs)"
using assms unfolding linord_of_list_def
by (induct xs) (auto intro!: antisymI dest: linord_of_listP_domain simp: antisymD)

lemma linord_of_list_total_on:
  shows "total_on (set xs) (linord_of_list xs)"
unfolding total_on_def linord_of_list_def by (induct xs) auto

lemma linord_of_list_Restr:
  assumes "x C"
  notes in_set_remove1[simp del] (* suppress warning *)
  shows "Restr (linord_of_list (remove1 x xs)) C = Restr (linord_of_list xs) C"
using assms unfolding linord_of_list_def by (induct xs) (auto iff: in_set_remove1)

lemma linord_of_list_nth:
  assumes "(xs ! i, xs ! j) linord_of_list xs"
  assumes "i < length xs" "j < length xs"
  assumes "distinct xs"
  shows "j i"
using %invisible assms
proof(induct xs arbitrary: i j)
  case (Cons x xs i j) show ?case
  proof(cases "i < length xs")
    case True with Cons show ?thesis
      by (auto simp: linord_of_list_linord_of_listP nth_equal_first_eq less_Suc_eq_0_disj linord_of_listP_domain)
  next
    case False with Cons show ?thesis by fastforce
  qed
qed simp

(*>*)
text

lemma linord_of_list_Linear_order:
  assumes "distinct xs"
  assumes "ys = set xs"
  shows "linear_order_on ys (linord_of_list xs)"
using %invisible assms linord_of_list_range linord_of_list_refl_on linord_of_list_trans linord_of_list_antisym linord_of_list_total_on
unfolding order_on_defs by force

text

  finite linear order is generated by a list.

 


(*<*)

inductive sorted_on :: "'a rel ==> 'a list ==> bool" where
  Nil [iff]: "sorted_on r []"
| Cons [intro!]: "[x Field r; yset xs. (x, y) r; sorted_on r xs] ==> sorted_on r (x # xs)"

inductive_cases sorted_on_inv[elim!]:
  "sorted_on r []"
  "sorted_on r (x # xs)"

primrec insort_key_on :: "'a rel ==> ('b ==> 'a) ==> 'b ==> 'b list ==> 'b list" where
  "insort_key_on r f x [] = [x]"
"insort_key_on r f x (y # ys) =
    (if (f x, f y) r then (x # y # ys) else y # insort_key_on r f x ys)"

definition sort_key_on :: "'a rel ==> ('b ==> 'a) ==> 'b list ==> 'b list" where
  "sort_key_on r f xs = foldr (insort_key_on r f) xs []"

definition insort_insert_key_on :: "'a rel ==> ('b ==> 'a) ==> 'b ==> 'b list ==> 'b list" where
  "insort_insert_key_on r f x xs =
    (if f x f ` set xs then xs else insort_key_on r f x xs)"

abbreviation "sort_on r sort_key_on r (λx. x)"
abbreviation "insort_on r insort_key_on r (λx. x)"
abbreviation "insort_insert_on r insort_insert_key_on r (λx. x)"

context
  fixes r :: "'a rel"
  assumes "Linear_order r"
begin

lemma sorted_on_single [iff]:
  shows "sorted_on r [x] x Field r"
by (metis empty_iff list.distinct(1) list.set(1) nth_Cons_0 sorted_on.simps)

lemma sorted_on_many:
  assumes "(x, y) r"
  assumes "sorted_on r (y # zs)"
  shows "sorted_on r (x # y # zs)"
using assms Linear_order r unfolding order_on_defs by (auto elim: transE intro: FieldI1)

lemma sorted_on_Cons:
  shows "sorted_on r (x # xs) (x Field r sorted_on r xs (yset xs. (x, y) r))"
using Linear_order r unfolding order_on_defs by (induct xs arbitrary: x) (auto elim: transE)

lemma sorted_on_distinct_set_unique:
  assumes "sorted_on r xs" "distinct xs" "sorted_on r ys" "distinct ys" "set xs = set ys"
  shows "xs = ys"
proof -
  from assms have 1"length xs = length ys" by (auto dest!: distinct_card)
  from assms show ?thesis
  proof(induct rule: list_induct2[OF 1])
    case (2 x xs y ys) with Linear_order r show ?case
      unfolding order_on_defs
        by (simp add: sorted_on_Cons) (metis antisymD insertI1 insert_eq_iff)
  qed simp
qed

lemma set_insort_on:
  shows "set (insort_key_on r f x xs) = insert x (set xs)"
by (induct xs) auto

lemma sort_key_on_simps [simp]:
  shows "sort_key_on r f [] = []"
        "sort_key_on r f (x#xs) = insort_key_on r f x (sort_key_on r f xs)"
by (simp_all add: sort_key_on_def)

lemma set_sort_on [simp]:
  shows "set (sort_key_on r f xs) = set xs"
by (induct xs) (simp_all add: set_insort_on)

lemma distinct_insort_on:
  shows "distinct (insort_key_on r f x xs) = (x set xs distinct xs)"
by(induct xs) (auto simp: set_insort_on)

lemma distinct_sort_on [simp]:
  shows "distinct (sort_key_on r f xs) = distinct xs"
by (induct xs) (simp_all add: distinct_insort_on)

lemma sorted_on_insort_key_on:
  assumes "f ` set (x # xs) Field r"
  shows "sorted_on r (map f (insort_key_on r f x xs)) = sorted_on r (map f xs)"
using assms
proof(induct xs)
  case (Cons x xs) with Linear_order r show ?case
    unfolding order_on_defs
    by (auto 4 4 simp: sorted_on_Cons sorted_on_many set_insort_on refl_on_def total_on_def elim: transE)
qed simp

lemma sorted_on_insort_on:
  assumes "set (x # xs) Field r"
  shows "sorted_on r (insort_on r x xs) = sorted_on r xs"
using sorted_on_insort_key_on[where f="λx. x"] assms by simp

theorem sorted_on_sort_key_on [simp]:
  assumes "f ` set xs Field r"
  shows "sorted_on r (map f (sort_key_on r f xs))"
using assms by (induct xs) (simp_all add: sorted_on_insort_key_on)

theorem sorted_on_sort_on [simp]:
  assumes "set xs Field r"
  shows "sorted_on r (sort_on r xs)"
using sorted_on_sort_key_on[where f="λx. x"] assms by simp

lemma finite_sorted_on_distinct_unique:
  assumes "A Field r"
  assumes "finite A"
  shows "!xs. set xs = A sorted_on r xs distinct xs"
proof -
  from finite A obtain xs where "set xs = A distinct xs"
    using finite_distinct_list by blast
  with A Field r show ?thesis
    by (fastforce intro!: ex1I[where a="sort_on r xs"] simp: sorted_on_distinct_set_unique)
qed

end

lemma sorted_on_linord_of_list_subseteq_r:
  assumes "Linear_order r"
  assumes "sorted_on r xs"
  assumes "distinct xs"
  shows "linord_of_list (rev xs) r"
using assms
proof(induct xs)
  case (Cons x xs)
  then have "linord_of_list (rev xs) r" by (simp add: sorted_on_Cons)
  with Cons.prems show ?case
    by (clarsimp simp: linord_of_list_append linord_of_list_singleton sorted_on_Cons)
       (meson contra_subsetD subsetI underS_incl_iff)
qed simp

lemma sorted_on_linord_of_list:
  assumes "Linear_order r"
  assumes "set xs = Field r"
  assumes "sorted_on r xs"
  assumes "distinct xs"
  shows "linord_of_list (rev xs) = r"
proof(rule equalityI)
  from assms show "linord_of_list (rev xs) r"
    using sorted_on_linord_of_list_subseteq_r by blast
next
  { fix x y assume xy: "(x, y) r"
    with Linear_order r have "(y, x) r - Id"
      using Linear_order_in_diff_Id by (fastforce intro: FieldI1)
    with linord_of_list_Linear_order[of "rev xs" "Field r"] assms xy
    have "(x, y) linord_of_list (rev xs)"
      by simp (metis Diff_subset FieldI1 FieldI2 Linear_order_in_diff_Id linord_of_list_Field set_rev sorted_on_linord_of_list_subseteq_r subset_eq) }
  then show "r linord_of_list (rev xs)" by clarsimp
qed

lemma linord_of_listP_rev:
  assumes "z # zs set (subseqs xs)"
  assumes "y set zs"
  shows "linord_of_listP z y (rev xs)"
using assms by (induct xs) (auto simp: Let_def linord_of_listP_append dest: subseqs_set)

lemma linord_of_list_sorted_on_subseqs:
  assumes "ys set (subseqs xs)"
  assumes "distinct xs"
  shows "sorted_on (linord_of_list (rev xs)) ys"
using assms
proof(induct ys)
  case (Cons y ys) then show ?case
    using linord_of_list_Linear_order[where xs="rev xs" and ys="Field (linord_of_list (rev xs))"]
    by (force simp: Cons_in_subseqsD sorted_on_Cons linord_of_list_linord_of_listP linord_of_listP_rev dest: subseqs_set)
qed simp

lemma linord_of_list_sorted_on:
  assumes "distinct xs"
  shows "sorted_on (linord_of_list (rev xs)) xs"
by (rule linord_of_list_sorted_on_subseqs[OF subseqs_refl distinct xs])

(*>*)

lemma linear_order_on_list:
  assumes "linear_order_on ys r"
  assumes "ys = Field r"
  assumes "finite ys"
  shows "!xs. r = linord_of_list xs distinct xs set xs = ys"
using %invisible finite_sorted_on_distinct_unique[of r ys] sorted_on_linord_of_list[of r] assms
by simp (metis distinct_rev linord_of_list_sorted_on rev_rev_ident set_rev)

(*<*)

end
(*>*)

Messung V0.5 in Prozent
C=75 H=94 G=84

¤ Dauer der Verarbeitung: 0.8 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.