src/HOL/Library/Uprod.thy
author wenzelm
Fri, 05 Apr 2019 17:05:32 +0200
changeset 70067 9b34dbeb1103
parent 68406 6beb45f6cf67
child 70113 c8deb8ba6d05
permissions -rw-r--r--
auxiliary operation for common uses of 'compile_generated_files';
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
66563
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
     1
(* Title: HOL/Library/Uprod.thy
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
     2
   Author: Andreas Lochbihler, ETH Zurich *)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
     3
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
     4
section \<open>Unordered pairs\<close>
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
     5
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
     6
theory Uprod imports Main begin
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
     7
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
     8
typedef ('a, 'b) commute = "{f :: 'a \<Rightarrow> 'a \<Rightarrow> 'b. \<forall>x y. f x y = f y x}"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
     9
  morphisms apply_commute Abs_commute
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    10
  by auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    11
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    12
setup_lifting type_definition_commute
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    13
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    14
lemma apply_commute_commute: "apply_commute f x y = apply_commute f y x"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    15
by(transfer) simp
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    16
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    17
context includes lifting_syntax begin
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    18
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    19
lift_definition rel_commute :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> ('c \<Rightarrow> 'd \<Rightarrow> bool) \<Rightarrow> ('a, 'c) commute \<Rightarrow> ('b, 'd) commute \<Rightarrow> bool"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    20
is "\<lambda>A B. A ===> A ===> B" .
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    21
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    22
end
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    23
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    24
definition eq_upair :: "('a \<times> 'a) \<Rightarrow> ('a \<times> 'a) \<Rightarrow> bool"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    25
where "eq_upair = (\<lambda>(a, b) (c, d). a = c \<and> b = d \<or> a = d \<and> b = c)"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    26
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    27
lemma eq_upair_simps [simp]:
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    28
  "eq_upair (a, b) (c, d) \<longleftrightarrow> a = c \<and> b = d \<or> a = d \<and> b = c"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    29
by(simp add: eq_upair_def)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    30
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    31
lemma equivp_eq_upair: "equivp eq_upair"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    32
by(auto simp add: equivp_def fun_eq_iff)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    33
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    34
quotient_type 'a uprod = "'a \<times> 'a" / eq_upair by(rule equivp_eq_upair)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    35
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    36
lift_definition Upair :: "'a \<Rightarrow> 'a \<Rightarrow> 'a uprod" is Pair parametric Pair_transfer[of "A" "A" for A] .
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    37
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    38
lemma uprod_exhaust [case_names Upair, cases type: uprod]:
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    39
  obtains a b where "x = Upair a b"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    40
by transfer fastforce
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    41
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    42
lemma Upair_inject [simp]: "Upair a b = Upair c d \<longleftrightarrow> a = c \<and> b = d \<or> a = d \<and> b = c"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    43
by transfer auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    44
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    45
code_datatype Upair
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    46
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    47
lift_definition case_uprod :: "('a, 'b) commute \<Rightarrow> 'a uprod \<Rightarrow> 'b" is case_prod
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    48
  parametric case_prod_transfer[of A A for A] by auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    49
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    50
lemma case_uprod_simps [simp, code]: "case_uprod f (Upair x y) = apply_commute f x y"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    51
by transfer auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    52
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    53
lemma uprod_split: "P (case_uprod f x) \<longleftrightarrow> (\<forall>a b. x = Upair a b \<longrightarrow> P (apply_commute f a b))"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    54
by transfer auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    55
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    56
lemma uprod_split_asm: "P (case_uprod f x) \<longleftrightarrow> \<not> (\<exists>a b. x = Upair a b \<and> \<not> P (apply_commute f a b))"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    57
by transfer auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    58
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66936
diff changeset
    59
lift_definition not_equal :: "('a, bool) commute" is "(\<noteq>)" by auto
66563
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    60
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    61
lemma apply_not_equal [simp]: "apply_commute not_equal x y \<longleftrightarrow> x \<noteq> y"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    62
by transfer simp
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    63
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    64
definition proper_uprod :: "'a uprod \<Rightarrow> bool"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    65
where "proper_uprod = case_uprod not_equal"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    66
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    67
lemma proper_uprod_simps [simp, code]: "proper_uprod (Upair x y) \<longleftrightarrow> x \<noteq> y"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    68
by(simp add: proper_uprod_def)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    69
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    70
context includes lifting_syntax begin
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    71
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    72
private lemma set_uprod_parametric':
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    73
  "(rel_prod A A ===> rel_set A) (\<lambda>(a, b). {a, b}) (\<lambda>(a, b). {a, b})"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    74
by transfer_prover
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    75
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    76
lift_definition set_uprod :: "'a uprod \<Rightarrow> 'a set" is "\<lambda>(a, b). {a, b}" 
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    77
  parametric set_uprod_parametric' by auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    78
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    79
lemma set_uprod_simps [simp, code]: "set_uprod (Upair x y) = {x, y}"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    80
by transfer simp
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    81
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    82
lemma finite_set_uprod [simp]: "finite (set_uprod x)"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    83
by(cases x) simp
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    84
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    85
private lemma map_uprod_parametric':
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    86
  "((A ===> B) ===> rel_prod A A ===> rel_prod B B) (\<lambda>f. map_prod f f) (\<lambda>f. map_prod f f)"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    87
by transfer_prover
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    88
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    89
lift_definition map_uprod :: "('a \<Rightarrow> 'b) \<Rightarrow> 'a uprod \<Rightarrow> 'b uprod" is "\<lambda>f. map_prod f f"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    90
  parametric map_uprod_parametric' by auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    91
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    92
lemma map_uprod_simps [simp, code]: "map_uprod f (Upair x y) = Upair (f x) (f y)"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    93
by transfer simp
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    94
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    95
private lemma rel_uprod_transfer':
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66936
diff changeset
    96
  "((A ===> B ===> (=)) ===> rel_prod A A ===> rel_prod B B ===> (=))
66563
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    97
   (\<lambda>R (a, b) (c, d). R a c \<and> R b d \<or> R a d \<and> R b c) (\<lambda>R (a, b) (c, d). R a c \<and> R b d \<or> R a d \<and> R b c)"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    98
by transfer_prover
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
    99
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   100
lift_definition rel_uprod :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> 'a uprod \<Rightarrow> 'b uprod \<Rightarrow> bool"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   101
  is "\<lambda>R (a, b) (c, d). R a c \<and> R b d \<or> R a d \<and> R b c" parametric rel_uprod_transfer'
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   102
by auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   103
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   104
lemma rel_uprod_simps [simp, code]:
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   105
  "rel_uprod R (Upair a b) (Upair c d) \<longleftrightarrow> R a c \<and> R b d \<or> R a d \<and> R b c"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   106
by transfer auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   107
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   108
lemma Upair_parametric [transfer_rule]: "(A ===> A ===> rel_uprod A) Upair Upair"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   109
unfolding rel_fun_def by transfer auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   110
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   111
lemma case_uprod_parametric [transfer_rule]:
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   112
  "(rel_commute A B ===> rel_uprod A ===> B) case_uprod case_uprod"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   113
unfolding rel_fun_def by transfer(force dest: rel_funD)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   114
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   115
end
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   116
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   117
bnf uprod: "'a uprod" 
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   118
  map: map_uprod
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   119
  sets: set_uprod
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   120
  bd: natLeq
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   121
  rel: rel_uprod
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   122
proof -
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   123
  show "map_uprod id = id" unfolding fun_eq_iff by transfer auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   124
  show "map_uprod (g \<circ> f) = map_uprod g \<circ> map_uprod f" for f :: "'a \<Rightarrow> 'b" and g :: "'b \<Rightarrow> 'c"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   125
    unfolding fun_eq_iff by transfer auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   126
  show "map_uprod f x = map_uprod g x" if "\<And>z. z \<in> set_uprod x \<Longrightarrow> f z = g z" 
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   127
    for f :: "'a \<Rightarrow> 'b" and g x using that by transfer auto
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66936
diff changeset
   128
  show "set_uprod \<circ> map_uprod f = (`) f \<circ> set_uprod" for f :: "'a \<Rightarrow> 'b" by transfer auto
66563
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   129
  show "card_order natLeq" by(rule natLeq_card_order)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   130
  show "BNF_Cardinal_Arithmetic.cinfinite natLeq" by(rule natLeq_cinfinite)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   131
  show "ordLeq3 (card_of (set_uprod x)) natLeq" for x :: "'a uprod"
68406
6beb45f6cf67 utilize 'flip'
nipkow
parents: 67411
diff changeset
   132
    by (auto simp flip: finite_iff_ordLess_natLeq intro: ordLess_imp_ordLeq)
66563
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   133
  show "rel_uprod R OO rel_uprod S \<le> rel_uprod (R OO S)"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   134
    for R :: "'a \<Rightarrow> 'b \<Rightarrow> bool" and S :: "'b \<Rightarrow> 'c \<Rightarrow> bool" by(rule predicate2I)(transfer; auto)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   135
  show "rel_uprod R = (\<lambda>x y. \<exists>z. set_uprod z \<subseteq> {(x, y). R x y} \<and> map_uprod fst z = x \<and> map_uprod snd z = y)"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   136
    for R :: "'a \<Rightarrow> 'b \<Rightarrow> bool" by transfer(auto simp add: fun_eq_iff)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   137
qed
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   138
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   139
lemma pred_uprod_code [simp, code]: "pred_uprod P (Upair x y) \<longleftrightarrow> P x \<and> P y"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   140
by(simp add: pred_uprod_def)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   141
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   142
instantiation uprod :: (equal) equal begin
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   143
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   144
definition equal_uprod :: "'a uprod \<Rightarrow> 'a uprod \<Rightarrow> bool"
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66936
diff changeset
   145
where "equal_uprod = (=)"
66563
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   146
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   147
lemma equal_uprod_code [code]:
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   148
  "HOL.equal (Upair x y) (Upair z u) \<longleftrightarrow> x = z \<and> y = u \<or> x = u \<and> y = z"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   149
unfolding equal_uprod_def by simp
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   150
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   151
instance by standard(simp add: equal_uprod_def)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   152
end
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   153
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   154
quickcheck_generator uprod constructors: Upair
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   155
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   156
lemma UNIV_uprod: "UNIV = (\<lambda>x. Upair x x) ` UNIV \<union> (\<lambda>(x, y). Upair x y) ` Sigma UNIV (\<lambda>x. UNIV - {x})"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   157
apply(rule set_eqI)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   158
subgoal for x by(cases x) auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   159
done
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   160
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   161
context begin
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   162
private lift_definition upair_inv :: "'a uprod \<Rightarrow> 'a"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   163
is "\<lambda>(x, y). if x = y then x else undefined" by auto
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   164
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   165
lemma finite_UNIV_prod [simp]:
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   166
  "finite (UNIV :: 'a uprod set) \<longleftrightarrow> finite (UNIV :: 'a set)" (is "?lhs = ?rhs")
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   167
proof
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   168
  assume ?lhs
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   169
  hence "finite (range (\<lambda>x :: 'a. Upair x x))" by(rule finite_subset[rotated]) simp
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   170
  hence "finite (upair_inv ` range (\<lambda>x :: 'a. Upair x x))" by(rule finite_imageI)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   171
  also have "upair_inv (Upair x x) = x" for x :: 'a by transfer simp
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   172
  then have "upair_inv ` range (\<lambda>x :: 'a. Upair x x) = UNIV" by(auto simp add: image_image)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   173
  finally show ?rhs .
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   174
qed(simp add: UNIV_uprod)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   175
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   176
end
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   177
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   178
lemma card_UNIV_uprod:
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   179
  "card (UNIV :: 'a uprod set) = card (UNIV :: 'a set) * (card (UNIV :: 'a set) + 1) div 2"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   180
  (is "?UPROD = ?A * _ div _")
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   181
proof(cases "finite (UNIV :: 'a set)")
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   182
  case True
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   183
  from True obtain f :: "nat \<Rightarrow> 'a" where bij: "bij_betw f {0..<?A} UNIV"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   184
    by (blast dest: ex_bij_betw_nat_finite)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   185
  hence [simp]: "f ` {0..<?A} = UNIV" by(rule bij_betw_imp_surj_on)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   186
  have "UNIV = (\<lambda>(x, y). Upair (f x) (f y)) ` (SIGMA x:{0..<?A}. {..x})"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   187
    apply(rule set_eqI)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   188
    subgoal for x
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   189
      apply(cases x)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   190
      apply(clarsimp)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   191
      subgoal for a b
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   192
        apply(cases "inv_into {0..<?A} f a \<le> inv_into {0..<?A} f b")
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   193
        subgoal by(rule rev_image_eqI[where x="(inv_into {0..<?A} f _, inv_into {0..<?A} f _)"])
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   194
                  (auto simp add: inv_into_into[where A="{0..<?A}" and f=f, simplified] intro: f_inv_into_f[where f=f, symmetric])
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   195
        subgoal
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   196
          apply(simp only: not_le)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   197
          apply(drule less_imp_le)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   198
          apply(rule rev_image_eqI[where x="(inv_into {0..<?A} f _, inv_into {0..<?A} f _)"])
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   199
          apply(auto simp add: inv_into_into[where A="{0..<?A}" and f=f, simplified] intro: f_inv_into_f[where f=f, symmetric])
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   200
          done
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   201
        done
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   202
      done
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   203
    done
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   204
  hence "?UPROD = card \<dots>" by simp
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   205
  also have "\<dots> = card (SIGMA x:{0..<?A}. {..x})"
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   206
    apply(rule card_image)
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   207
    using bij[THEN bij_betw_imp_inj_on]
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   208
    by(simp add: inj_on_def Ball_def)(metis leD le_eq_less_or_eq le_less_trans)
66936
cf8d8fc23891 tuned some proofs and added some lemmas
haftmann
parents: 66563
diff changeset
   209
  also have "\<dots> = sum Suc {0..<?A}"
cf8d8fc23891 tuned some proofs and added some lemmas
haftmann
parents: 66563
diff changeset
   210
    by (subst card_SigmaI) simp_all
cf8d8fc23891 tuned some proofs and added some lemmas
haftmann
parents: 66563
diff changeset
   211
  also have "\<dots> = sum of_nat {Suc 0..?A}"
67411
3f4b0c84630f restored naming of lemmas after corresponding constants
haftmann
parents: 67399
diff changeset
   212
    using sum.atLeastLessThan_reindex [symmetric, of Suc 0 ?A id]
66936
cf8d8fc23891 tuned some proofs and added some lemmas
haftmann
parents: 66563
diff changeset
   213
    by (simp del: sum_op_ivl_Suc add: atLeastLessThanSuc_atLeastAtMost)
66563
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   214
  also have "\<dots> = ?A * (?A + 1) div 2"
66936
cf8d8fc23891 tuned some proofs and added some lemmas
haftmann
parents: 66563
diff changeset
   215
    using gauss_sum_from_Suc_0 [of ?A, where ?'a = nat] by simp
66563
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   216
  finally show ?thesis .
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   217
qed simp
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   218
87b9eb69d5ba add type of unordered pairs
Andreas Lochbihler
parents:
diff changeset
   219
end