src/HOL/Library/Poly_Mapping.thy
author nipkow
Mon, 07 Nov 2022 22:16:37 +0100
changeset 76484 defaa0b17424
parent 75455 91c16c5ad3e9
child 76987 4c275405faae
permissions -rw-r--r--
generalized sorted_sort_id to sort_key_id_if_sorted
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
     1
(* Author: Andreas Lochbihler, ETH Zurich
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
     2
   Author: Florian Haftmann, TU Muenchen
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
     3
   with some material ported from HOL Light by LCP
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
     4
*)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
     5
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
     6
section \<open>Polynomial mapping: combination of almost everywhere zero functions with an algebraic view\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
     7
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
     8
theory Poly_Mapping
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
     9
imports Groups_Big_Fun Fun_Lexorder More_List
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    10
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    11
70045
7b6add80e3a5 fixed markup in Poly_Mapping; Free_Abelian_Groups (but not yet imported by Algebra!)
paulson <lp15@cam.ac.uk>
parents: 70043
diff changeset
    12
subsection \<open>Preliminary: auxiliary operations for \emph{almost everywhere zero}\<close>
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    13
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    14
text \<open>
70045
7b6add80e3a5 fixed markup in Poly_Mapping; Free_Abelian_Groups (but not yet imported by Algebra!)
paulson <lp15@cam.ac.uk>
parents: 70043
diff changeset
    15
  A central notion for polynomials are functions being \emph{almost everywhere zero}.
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    16
  For these we provide some auxiliary definitions and lemmas.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    17
\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    18
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    19
lemma finite_mult_not_eq_zero_leftI:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    20
  fixes f :: "'b \<Rightarrow> 'a :: mult_zero"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    21
  assumes "finite {a. f a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    22
  shows "finite {a. g a * f a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    23
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    24
  have "{a. g a * f a \<noteq> 0} \<subseteq> {a. f a \<noteq> 0}" by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    25
  then show ?thesis using assms by (rule finite_subset)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    26
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    27
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    28
lemma finite_mult_not_eq_zero_rightI:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    29
  fixes f :: "'b \<Rightarrow> 'a :: mult_zero"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    30
  assumes "finite {a. f a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    31
  shows "finite {a. f a * g a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    32
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    33
  have "{a. f a * g a \<noteq> 0} \<subseteq> {a. f a \<noteq> 0}" by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    34
  then show ?thesis using assms by (rule finite_subset)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    35
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    36
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    37
lemma finite_mult_not_eq_zero_prodI:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    38
  fixes f g :: "'a \<Rightarrow> 'b::semiring_0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    39
  assumes "finite {a. f a \<noteq> 0}" (is "finite ?F")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    40
  assumes "finite {b. g b \<noteq> 0}" (is "finite ?G")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    41
  shows "finite {(a, b). f a * g b \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    42
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    43
  from assms have "finite (?F \<times> ?G)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    44
    by blast
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    45
  then have "finite {(a, b). f a \<noteq> 0 \<and> g b \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    46
    by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    47
  then show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    48
    by (rule rev_finite_subset) auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    49
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    50
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    51
lemma finite_not_eq_zero_sumI:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    52
  fixes f g :: "'a::monoid_add \<Rightarrow> 'b::semiring_0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    53
  assumes "finite {a. f a \<noteq> 0}" (is "finite ?F")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    54
  assumes "finite {b. g b \<noteq> 0}" (is "finite ?G")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    55
  shows "finite {a + b | a b. f a \<noteq> 0 \<and> g b \<noteq> 0}" (is "finite ?FG")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    56
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    57
  from assms have "finite (?F \<times> ?G)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    58
    by (simp add: finite_cartesian_product_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    59
  then have "finite (case_prod plus ` (?F \<times> ?G))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    60
    by (rule finite_imageI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    61
  also have "case_prod plus ` (?F \<times> ?G) = ?FG"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    62
    by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    63
  finally show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    64
    by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    65
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    66
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    67
lemma finite_mult_not_eq_zero_sumI:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    68
  fixes f g :: "'a::monoid_add \<Rightarrow> 'b::semiring_0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    69
  assumes "finite {a. f a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    70
  assumes "finite {b. g b \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    71
  shows "finite {a + b | a b. f a * g b \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    72
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    73
  from assms
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    74
  have "finite {a + b | a b. f a \<noteq> 0 \<and> g b \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    75
    by (rule finite_not_eq_zero_sumI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    76
  then show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    77
    by (rule rev_finite_subset) (auto dest: mult_not_zero)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    78
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    79
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    80
lemma finite_Sum_any_not_eq_zero_weakenI:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    81
  assumes "finite {a. \<exists>b. f a b \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    82
  shows "finite {a. Sum_any (f a) \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    83
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    84
  have "{a. Sum_any (f a) \<noteq> 0} \<subseteq> {a. \<exists>b. f a b \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    85
    by (auto elim: Sum_any.not_neutral_obtains_not_neutral)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    86
  then show ?thesis using assms by (rule finite_subset)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    87
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    88
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    89
context zero
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    90
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    91
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    92
definition "when" :: "'a \<Rightarrow> bool \<Rightarrow> 'a" (infixl "when" 20)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    93
where
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    94
  "(a when P) = (if P then a else 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    95
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    96
text \<open>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    97
  Case distinctions always complicate matters, particularly when
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    98
  nested.  The @{const "when"} operation allows to minimise these
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
    99
  if @{term 0} is the false-case value and makes proof obligations
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   100
  much more readable.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   101
\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   102
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   103
lemma "when" [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   104
  "P \<Longrightarrow> (a when P) = a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   105
  "\<not> P \<Longrightarrow> (a when P) = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   106
  by (simp_all add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   107
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   108
lemma when_simps [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   109
  "(a when True) = a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   110
  "(a when False) = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   111
  by simp_all
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   112
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   113
lemma when_cong:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   114
  assumes "P \<longleftrightarrow> Q"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   115
    and "Q \<Longrightarrow> a = b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   116
  shows "(a when P) = (b when Q)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   117
  using assms by (simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   118
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   119
lemma zero_when [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   120
  "(0 when P) = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   121
  by (simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   122
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   123
lemma when_when:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   124
  "(a when P when Q) = (a when P \<and> Q)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   125
  by (cases Q) simp_all
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   126
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   127
lemma when_commute:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   128
  "(a when Q when P) = (a when P when Q)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   129
  by (simp add: when_when conj_commute)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   130
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   131
lemma when_neq_zero [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   132
  "(a when P) \<noteq> 0 \<longleftrightarrow> P \<and> a \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   133
  by (cases P) simp_all
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   134
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   135
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   136
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   137
context monoid_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   138
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   139
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   140
lemma when_add_distrib:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   141
  "(a + b when P) = (a when P) + (b when P)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   142
  by (simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   143
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   144
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   145
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   146
context semiring_1
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   147
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   148
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   149
lemma zero_power_eq:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   150
  "0 ^ n = (1 when n = 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   151
  by (simp add: power_0_left)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   152
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   153
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   154
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   155
context comm_monoid_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   156
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   157
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   158
lemma Sum_any_when_equal [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   159
  "(\<Sum>a. (f a when a = b)) = f b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   160
  by (simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   161
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   162
lemma Sum_any_when_equal' [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   163
  "(\<Sum>a. (f a when b = a)) = f b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   164
  by (simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   165
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   166
lemma Sum_any_when_independent:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   167
  "(\<Sum>a. g a when P) = ((\<Sum>a. g a) when P)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   168
  by (cases P) simp_all
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   169
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   170
lemma Sum_any_when_dependent_prod_right:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   171
  "(\<Sum>(a, b). g a when b = h a) = (\<Sum>a. g a)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   172
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   173
  have "inj_on (\<lambda>a. (a, h a)) {a. g a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   174
    by (rule inj_onI) auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   175
  then show ?thesis unfolding Sum_any.expand_set
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   176
    by (rule sum.reindex_cong) auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   177
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   178
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   179
lemma Sum_any_when_dependent_prod_left:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   180
  "(\<Sum>(a, b). g b when a = h b) = (\<Sum>b. g b)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   181
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   182
  have "(\<Sum>(a, b). g b when a = h b) = (\<Sum>(b, a). g b when a = h b)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   183
    by (rule Sum_any.reindex_cong [of prod.swap]) (simp_all add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   184
  then show ?thesis by (simp add: Sum_any_when_dependent_prod_right)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   185
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   186
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   187
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   188
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   189
context cancel_comm_monoid_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   190
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   191
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   192
lemma when_diff_distrib:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   193
  "(a - b when P) = (a when P) - (b when P)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   194
  by (simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   195
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   196
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   197
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   198
context group_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   199
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   200
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   201
lemma when_uminus_distrib:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   202
  "(- a when P) = - (a when P)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   203
  by (simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   204
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   205
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   206
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   207
context mult_zero
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   208
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   209
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   210
lemma mult_when:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   211
  "a * (b when P) = (a * b when P)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   212
  by (cases P) simp_all
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   213
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   214
lemma when_mult:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   215
  "(a when P) * b = (a * b when P)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   216
  by (cases P) simp_all
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   217
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   218
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   219
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   220
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   221
subsection \<open>Type definition\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   222
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   223
text \<open>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   224
  The following type is of central importance:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   225
\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   226
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   227
typedef (overloaded) ('a, 'b) poly_mapping ("(_ \<Rightarrow>\<^sub>0 /_)" [1, 0] 0) =
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   228
  "{f :: 'a \<Rightarrow> 'b::zero. finite {x. f x \<noteq> 0}}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   229
  morphisms lookup Abs_poly_mapping
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   230
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   231
  have "(\<lambda>_::'a. (0 :: 'b)) \<in> ?poly_mapping" by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   232
  then show ?thesis by (blast intro!: exI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   233
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   234
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   235
declare lookup_inverse [simp]
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   236
declare lookup_inject [simp]
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   237
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   238
lemma lookup_Abs_poly_mapping [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   239
  "finite {x. f x \<noteq> 0} \<Longrightarrow> lookup (Abs_poly_mapping f) = f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   240
  using Abs_poly_mapping_inverse [of f] by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   241
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   242
lemma finite_lookup [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   243
  "finite {k. lookup f k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   244
  using poly_mapping.lookup [of f] by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   245
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   246
lemma finite_lookup_nat [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   247
  fixes f :: "'a \<Rightarrow>\<^sub>0 nat"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   248
  shows "finite {k. 0 < lookup f k}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   249
  using poly_mapping.lookup [of f] by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   250
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   251
lemma poly_mapping_eqI:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   252
  assumes "\<And>k. lookup f k = lookup g k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   253
  shows "f = g"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   254
  using assms unfolding poly_mapping.lookup_inject [symmetric]
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   255
  by blast
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   256
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   257
lemma poly_mapping_eq_iff: "a = b \<longleftrightarrow> lookup a = lookup b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   258
  by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   259
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   260
text \<open>
70045
7b6add80e3a5 fixed markup in Poly_Mapping; Free_Abelian_Groups (but not yet imported by Algebra!)
paulson <lp15@cam.ac.uk>
parents: 70043
diff changeset
   261
  We model the universe of functions being \emph{almost everywhere zero}
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   262
  by means of a separate type @{typ "('a, 'b) poly_mapping"}.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   263
  For convenience we provide a suggestive infix syntax which
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   264
  is a variant of the usual function space syntax.  Conversion between both types
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   265
  happens through the morphisms
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   266
  \begin{quote}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   267
    @{term_type lookup}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   268
  \end{quote}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   269
  \begin{quote}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   270
    @{term_type Abs_poly_mapping}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   271
  \end{quote}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   272
  satisfying
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   273
  \begin{quote}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   274
    @{thm lookup_inverse}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   275
  \end{quote}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   276
  \begin{quote}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   277
    @{thm lookup_Abs_poly_mapping}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   278
  \end{quote}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   279
  Luckily, we have rarely to deal with those low-level morphisms explicitly
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   280
  but rely on Isabelle's \emph{lifting} package with its method \<open>transfer\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   281
  and its specification tool \<open>lift_definition\<close>.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   282
\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   283
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   284
setup_lifting type_definition_poly_mapping
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   285
code_datatype Abs_poly_mapping\<comment>\<open>FIXME? workaround for preventing \<open>code_abstype\<close> setup\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   286
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   287
text \<open>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   288
  @{typ "'a \<Rightarrow>\<^sub>0 'b"} serves distinctive purposes:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   289
  \begin{enumerate}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   290
    \item A clever nesting as @{typ "(nat \<Rightarrow>\<^sub>0 nat) \<Rightarrow>\<^sub>0 'a"}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   291
      later in theory \<open>MPoly\<close> gives a suitable
70045
7b6add80e3a5 fixed markup in Poly_Mapping; Free_Abelian_Groups (but not yet imported by Algebra!)
paulson <lp15@cam.ac.uk>
parents: 70043
diff changeset
   292
      representation type for polynomials \emph{almost for free}:
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   293
      Interpreting @{typ "nat \<Rightarrow>\<^sub>0 nat"} as a mapping from variable identifiers
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   294
      to exponents yields monomials, and the whole type maps monomials
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   295
      to coefficients.  Lets call this the \emph{ultimate interpretation}.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   296
    \item A further more specialised type isomorphic to @{typ "nat \<Rightarrow>\<^sub>0 'a"}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   297
      is apt to direct implementation using code generation
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   298
      \cite{Haftmann-Nipkow:2010:code}.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   299
  \end{enumerate}
70045
7b6add80e3a5 fixed markup in Poly_Mapping; Free_Abelian_Groups (but not yet imported by Algebra!)
paulson <lp15@cam.ac.uk>
parents: 70043
diff changeset
   300
  Note that despite the names \emph{mapping} and \emph{lookup} suggest something
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   301
  implementation-near, it is best to keep @{typ "'a \<Rightarrow>\<^sub>0 'b"} as an abstract
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   302
  \emph{algebraic} type
70045
7b6add80e3a5 fixed markup in Poly_Mapping; Free_Abelian_Groups (but not yet imported by Algebra!)
paulson <lp15@cam.ac.uk>
parents: 70043
diff changeset
   303
  providing operations like \emph{addition}, \emph{multiplication} without any notion
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   304
  of key-order, data structures etc.  This implementations-specific notions are
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   305
  easily introduced later for particular implementations but do not provide any
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   306
  gain for specifying logical properties of polynomials.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   307
\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   308
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   309
subsection \<open>Additive structure\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   310
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   311
text \<open>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   312
  The additive structure covers the usual operations \<open>0\<close>, \<open>+\<close> and
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   313
  (unary and binary) \<open>-\<close>.  Recalling the ultimate interpretation, it
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   314
  is obvious that these have just lift the corresponding operations on values
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   315
  to mappings.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   316
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   317
  Isabelle has a rich hierarchy of algebraic type classes, and in such situations
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   318
  of pointwise lifting a typical pattern is to have instantiations for a considerable
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   319
  number of type classes.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   320
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   321
  The operations themselves are specified using \<open>lift_definition\<close>, where
70045
7b6add80e3a5 fixed markup in Poly_Mapping; Free_Abelian_Groups (but not yet imported by Algebra!)
paulson <lp15@cam.ac.uk>
parents: 70043
diff changeset
   322
  the proofs of the \emph{almost everywhere zero} property can be significantly involved.
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   323
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   324
  The @{const lookup} operation is supposed to be usable explicitly (unless in
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   325
  other situations where the morphisms between types are somehow internal
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   326
  to the \emph{lifting} package).  Hence it is good style to provide explicit rewrite
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   327
  rules how @{const lookup} acts on operations immediately.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   328
\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   329
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   330
instantiation poly_mapping :: (type, zero) zero
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   331
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   332
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   333
lift_definition zero_poly_mapping :: "'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   334
  is "\<lambda>k. 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   335
  by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   336
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   337
instance ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   338
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   339
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   340
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   341
lemma Abs_poly_mapping [simp]: "Abs_poly_mapping (\<lambda>k. 0) = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   342
  by (simp add: zero_poly_mapping.abs_eq)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   343
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   344
lemma lookup_zero [simp]: "lookup 0 k = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   345
  by transfer rule
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   346
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   347
instantiation poly_mapping :: (type, monoid_add) monoid_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   348
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   349
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   350
lift_definition plus_poly_mapping ::
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   351
    "('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> ('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> 'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   352
  is "\<lambda>f1 f2 k. f1 k + f2 k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   353
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   354
  fix f1 f2 :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   355
  assume "finite {k. f1 k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   356
    and "finite {k. f2 k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   357
  then have "finite ({k. f1 k \<noteq> 0} \<union> {k. f2 k \<noteq> 0})" by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   358
  moreover have "{x. f1 x + f2 x \<noteq> 0} \<subseteq> {k. f1 k \<noteq> 0} \<union> {k. f2 k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   359
    by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   360
  ultimately show "finite {x. f1 x + f2 x \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   361
    by (blast intro: finite_subset)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   362
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   363
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   364
instance
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   365
  by intro_classes (transfer, simp add: fun_eq_iff ac_simps)+
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   366
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   367
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   368
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   369
lemma lookup_add:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   370
  "lookup (f + g) k = lookup f k + lookup g k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   371
  by transfer rule
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   372
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   373
instance poly_mapping :: (type, comm_monoid_add) comm_monoid_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   374
  by intro_classes (transfer, simp add: fun_eq_iff ac_simps)+
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   375
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   376
lemma lookup_sum: "lookup (sum pp X) i = sum (\<lambda>x. lookup (pp x) i) X"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   377
  by (induction rule: infinite_finite_induct) (auto simp: lookup_add)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   378
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   379
(*instance poly_mapping :: (type, "{monoid_add, cancel_semigroup_add}") cancel_semigroup_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   380
  by intro_classes (transfer, simp add: fun_eq_iff)+*)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   381
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   382
instantiation poly_mapping :: (type, cancel_comm_monoid_add) cancel_comm_monoid_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   383
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   384
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   385
lift_definition minus_poly_mapping :: "('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> ('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> 'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   386
  is "\<lambda>f1 f2 k. f1 k - f2 k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   387
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   388
  fix f1 f2 :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   389
  assume "finite {k. f1 k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   390
    and "finite {k. f2 k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   391
  then have "finite ({k. f1 k \<noteq> 0} \<union> {k. f2 k \<noteq> 0})" by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   392
  moreover have "{x. f1 x - f2 x \<noteq> 0} \<subseteq> {k. f1 k \<noteq> 0} \<union> {k. f2 k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   393
    by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   394
  ultimately show "finite {x. f1 x - f2 x \<noteq> 0}" by (blast intro: finite_subset)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   395
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   396
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   397
instance
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   398
  by intro_classes (transfer, simp add: fun_eq_iff diff_diff_add)+
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   399
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   400
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   401
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   402
instantiation poly_mapping :: (type, ab_group_add) ab_group_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   403
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   404
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   405
lift_definition uminus_poly_mapping :: "('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> 'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   406
  is uminus
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   407
  by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   408
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   409
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   410
instance
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   411
  by intro_classes (transfer, simp add: fun_eq_iff ac_simps)+
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   412
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   413
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   414
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   415
lemma lookup_uminus [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   416
  "lookup (- f) k = - lookup f k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   417
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   418
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   419
lemma lookup_minus:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   420
  "lookup (f - g) k = lookup f k - lookup g k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   421
  by transfer rule
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   422
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   423
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   424
subsection \<open>Multiplicative structure\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   425
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   426
instantiation poly_mapping :: (zero, zero_neq_one) zero_neq_one
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   427
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   428
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   429
lift_definition one_poly_mapping :: "'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   430
  is "\<lambda>k. 1 when k = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   431
  by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   432
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   433
instance
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   434
  by intro_classes (transfer, simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   435
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   436
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   437
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   438
lemma lookup_one:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   439
  "lookup 1 k = (1 when k = 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   440
  by transfer rule
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   441
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   442
lemma lookup_one_zero [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   443
  "lookup 1 0 = 1"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   444
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   445
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   446
definition prod_fun :: "('a \<Rightarrow> 'b) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'a::monoid_add \<Rightarrow> 'b::semiring_0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   447
where
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   448
  "prod_fun f1 f2 k = (\<Sum>l. f1 l * (\<Sum>q. (f2 q when k = l + q)))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   449
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   450
lemma prod_fun_unfold_prod:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   451
  fixes f g :: "'a :: monoid_add \<Rightarrow> 'b::semiring_0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   452
  assumes fin_f: "finite {a. f a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   453
  assumes fin_g: "finite {b. g b \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   454
  shows "prod_fun f g k = (\<Sum>(a, b). f a * g b when k = a + b)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   455
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   456
  let ?C = "{a. f a \<noteq> 0} \<times> {b. g b \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   457
  from fin_f fin_g have "finite ?C" by blast
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   458
  moreover have "{a. \<exists>b. (f a * g b when k = a + b) \<noteq> 0} \<times>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   459
    {b. \<exists>a. (f a * g b when k = a + b) \<noteq> 0} \<subseteq> {a. f a \<noteq> 0} \<times> {b. g b \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   460
    by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   461
  ultimately show ?thesis using fin_g
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   462
    by (auto simp add: prod_fun_def
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   463
      Sum_any.cartesian_product [of "{a. f a \<noteq> 0} \<times> {b. g b \<noteq> 0}"] Sum_any_right_distrib mult_when)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   464
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   465
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   466
lemma finite_prod_fun:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   467
  fixes f1 f2 :: "'a :: monoid_add \<Rightarrow> 'b :: semiring_0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   468
  assumes fin1: "finite {l. f1 l \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   469
  and fin2: "finite {q. f2 q \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   470
  shows "finite {k. prod_fun f1 f2 k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   471
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   472
  have *: "finite {k. (\<exists>l. f1 l \<noteq> 0 \<and> (\<exists>q. f2 q \<noteq> 0 \<and> k = l + q))}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   473
    using assms by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   474
  { fix k l
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   475
    have "{q. (f2 q when k = l + q) \<noteq> 0} \<subseteq> {q. f2 q \<noteq> 0 \<and> k = l + q}" by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   476
    with fin2 have "sum f2 {q. f2 q \<noteq> 0 \<and> k = l + q} = (\<Sum>q. (f2 q when k = l + q))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   477
      by (simp add: Sum_any.expand_superset [of "{q. f2 q \<noteq> 0 \<and> k = l + q}"]) }
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   478
  note aux = this
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   479
  have "{k. (\<Sum>l. f1 l * sum f2 {q. f2 q \<noteq> 0 \<and> k = l + q}) \<noteq> 0}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   480
    \<subseteq> {k. (\<exists>l. f1 l * sum f2 {q. f2 q \<noteq> 0 \<and> k = l + q} \<noteq> 0)}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   481
    by (auto elim!: Sum_any.not_neutral_obtains_not_neutral)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   482
  also have "\<dots> \<subseteq> {k. (\<exists>l. f1 l \<noteq> 0 \<and> sum f2 {q. f2 q \<noteq> 0 \<and> k = l + q} \<noteq> 0)}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   483
    by (auto dest: mult_not_zero)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   484
  also have "\<dots> \<subseteq> {k. (\<exists>l. f1 l \<noteq> 0 \<and> (\<exists>q. f2 q \<noteq> 0 \<and> k = l + q))}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   485
    by (auto elim!: sum.not_neutral_contains_not_neutral)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   486
  finally have "finite {k. (\<Sum>l. f1 l * sum f2 {q. f2 q \<noteq> 0 \<and> k = l + q}) \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   487
    using * by (rule finite_subset)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   488
  with aux have "finite {k. (\<Sum>l. f1 l * (\<Sum>q. (f2 q when k = l + q))) \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   489
    by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   490
  with fin2 show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   491
   by (simp add: prod_fun_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   492
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   493
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   494
instantiation poly_mapping :: (monoid_add, semiring_0) semiring_0
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   495
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   496
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   497
lift_definition times_poly_mapping :: "('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> ('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> 'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   498
  is prod_fun
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   499
by(rule finite_prod_fun)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   500
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   501
instance
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   502
proof
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   503
  fix a b c :: "'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   504
  show "a * b * c = a * (b * c)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   505
  proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   506
    fix f g h :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   507
    assume fin_f: "finite {a. f a \<noteq> 0}" (is "finite ?F")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   508
    assume fin_g: "finite {b. g b \<noteq> 0}" (is "finite ?G")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   509
    assume fin_h: "finite {c. h c \<noteq> 0}" (is "finite ?H")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   510
    from fin_f fin_g have fin_fg: "finite {(a, b). f a * g b \<noteq> 0}" (is "finite ?FG")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   511
      by (rule finite_mult_not_eq_zero_prodI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   512
    from fin_g fin_h have fin_gh: "finite {(b, c). g b * h c \<noteq> 0}" (is "finite ?GH")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   513
      by (rule finite_mult_not_eq_zero_prodI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   514
    from fin_f fin_g have fin_fg': "finite {a + b | a b. f a * g b \<noteq> 0}" (is "finite ?FG'")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   515
      by (rule finite_mult_not_eq_zero_sumI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   516
    then have fin_fg'': "finite {d. (\<Sum>(a, b). f a * g b when d = a + b) \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   517
      by (auto intro: finite_Sum_any_not_eq_zero_weakenI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   518
    from fin_g fin_h have fin_gh': "finite {b + c | b c. g b * h c \<noteq> 0}" (is "finite ?GH'")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   519
      by (rule finite_mult_not_eq_zero_sumI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   520
    then have fin_gh'': "finite {d. (\<Sum>(b, c). g b * h c when d = b + c) \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   521
      by (auto intro: finite_Sum_any_not_eq_zero_weakenI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   522
    show "prod_fun (prod_fun f g) h = prod_fun f (prod_fun g h)" (is "?lhs = ?rhs")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   523
    proof
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   524
      fix k
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   525
      from fin_f fin_g fin_h fin_fg''
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   526
      have "?lhs k = (\<Sum>(ab, c). (\<Sum>(a, b). f a * g b when ab = a + b) * h c when k = ab + c)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   527
        by (simp add: prod_fun_unfold_prod)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   528
      also have "\<dots> = (\<Sum>(ab, c). (\<Sum>(a, b). f a * g b * h c when k = ab + c when ab = a + b))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   529
        apply (subst Sum_any_left_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   530
        using fin_fg apply (simp add: split_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   531
        apply (subst Sum_any_when_independent [symmetric])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   532
        apply (simp add: when_when when_mult mult_when split_def conj_commute)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   533
        done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   534
      also have "\<dots> = (\<Sum>(ab, c, a, b). f a * g b * h c when k = ab + c when ab = a + b)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   535
        apply (subst Sum_any.cartesian_product2 [of "(?FG' \<times> ?H) \<times> ?FG"])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   536
        apply (auto simp add: finite_cartesian_product_iff fin_fg fin_fg' fin_h dest: mult_not_zero)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   537
        done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   538
      also have "\<dots> = (\<Sum>(ab, c, a, b). f a * g b * h c when k = a + b + c when ab = a + b)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   539
        by (rule Sum_any.cong) (simp add: split_def when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   540
      also have "\<dots> = (\<Sum>(ab, cab). (case cab of (c, a, b) \<Rightarrow> f a * g b * h c when k = a + b + c)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   541
        when ab = (case cab of (c, a, b) \<Rightarrow> a + b))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   542
        by (simp add: split_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   543
      also have "\<dots> = (\<Sum>(c, a, b). f a * g b * h c when k = a + b + c)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   544
        by (simp add: Sum_any_when_dependent_prod_left)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   545
      also have "\<dots> = (\<Sum>(bc, cab). (case cab of (c, a, b) \<Rightarrow> f a * g b * h c when k = a + b + c)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   546
        when bc = (case cab of (c, a, b) \<Rightarrow> b + c))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   547
        by (simp add: Sum_any_when_dependent_prod_left)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   548
      also have "\<dots> = (\<Sum>(bc, c, a, b). f a * g b * h c when k = a + b + c when bc = b + c)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   549
        by (simp add: split_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   550
      also have "\<dots> = (\<Sum>(bc, c, a, b). f a * g b * h c when bc = b + c when k = a + bc)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   551
        by (rule Sum_any.cong) (simp add: split_def when_def ac_simps)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   552
      also have "\<dots> = (\<Sum>(a, bc, b, c). f a * g b * h c when bc = b + c when k = a + bc)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   553
      proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   554
        have "bij (\<lambda>(a, d, b, c). (d, c, a, b))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   555
          by (auto intro!: bijI injI surjI [of _ "\<lambda>(d, c, a, b). (a, d, b, c)"] simp add: split_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   556
        then show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   557
          by (rule Sum_any.reindex_cong) auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   558
      qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   559
      also have "\<dots> = (\<Sum>(a, bc). (\<Sum>(b, c). f a * g b * h c when bc = b + c when k = a + bc))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   560
        apply (subst Sum_any.cartesian_product2 [of "(?F \<times> ?GH') \<times> ?GH"])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   561
        apply (auto simp add: finite_cartesian_product_iff fin_f fin_gh fin_gh' ac_simps dest: mult_not_zero)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   562
        done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   563
      also have "\<dots> = (\<Sum>(a, bc). f a * (\<Sum>(b, c). g b * h c when bc = b + c) when k = a + bc)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   564
        apply (subst Sum_any_right_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   565
        using fin_gh apply (simp add: split_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   566
        apply (subst Sum_any_when_independent [symmetric])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   567
        apply (simp add: when_when when_mult mult_when split_def ac_simps)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   568
        done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   569
      also from fin_f fin_g fin_h fin_gh''
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   570
      have "\<dots> = ?rhs k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   571
        by (simp add: prod_fun_unfold_prod)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   572
      finally show "?lhs k = ?rhs k" .
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   573
    qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   574
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   575
  show "(a + b) * c = a * c + b * c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   576
  proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   577
    fix f g h :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   578
    assume fin_f: "finite {k. f k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   579
    assume fin_g: "finite {k. g k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   580
    assume fin_h: "finite {k. h k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   581
    show "prod_fun (\<lambda>k. f k + g k) h = (\<lambda>k. prod_fun f h k + prod_fun g h k)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   582
      apply (rule ext)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   583
      apply (auto simp add: prod_fun_def algebra_simps)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   584
      apply (subst Sum_any.distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   585
      using fin_f fin_g apply (auto intro: finite_mult_not_eq_zero_rightI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   586
      done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   587
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   588
  show "a * (b + c) = a * b + a * c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   589
  proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   590
    fix f g h :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   591
    assume fin_f: "finite {k. f k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   592
    assume fin_g: "finite {k. g k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   593
    assume fin_h: "finite {k. h k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   594
    show "prod_fun f (\<lambda>k. g k + h k) = (\<lambda>k. prod_fun f g k + prod_fun f h k)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   595
      apply (rule ext)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   596
      apply (auto simp add: prod_fun_def Sum_any.distrib algebra_simps when_add_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   597
      apply (subst Sum_any.distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   598
      apply (simp_all add: algebra_simps)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   599
      apply (auto intro: fin_g fin_h)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   600
      apply (subst Sum_any.distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   601
      apply (simp_all add: algebra_simps)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   602
      using fin_f apply (rule finite_mult_not_eq_zero_rightI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   603
      using fin_f apply (rule finite_mult_not_eq_zero_rightI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   604
      done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   605
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   606
  show "0 * a = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   607
    by transfer (simp add: prod_fun_def [abs_def])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   608
  show "a * 0 = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   609
    by transfer (simp add: prod_fun_def [abs_def])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   610
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   611
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   612
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   613
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   614
lemma lookup_mult:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   615
  "lookup (f * g) k = (\<Sum>l. lookup f l * (\<Sum>q. lookup g q when k = l + q))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   616
  by transfer (simp add: prod_fun_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   617
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   618
instance poly_mapping :: (comm_monoid_add, comm_semiring_0) comm_semiring_0
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   619
proof
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   620
  fix a b c :: "'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   621
  show "a * b = b * a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   622
  proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   623
    fix f g :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   624
    assume fin_f: "finite {a. f a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   625
    assume fin_g: "finite {b. g b \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   626
    show "prod_fun f g = prod_fun g f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   627
    proof
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   628
      fix k
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   629
      have fin1: "\<And>l. finite {a. (f a when k = l + a) \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   630
        using fin_f by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   631
      have fin2: "\<And>l. finite {b. (g b when k = l + b) \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   632
        using fin_g by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   633
      from fin_f fin_g have "finite {(a, b). f a \<noteq> 0 \<and> g b \<noteq> 0}" (is "finite ?AB")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   634
        by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   635
      show "prod_fun f g k = prod_fun g f k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   636
        apply (simp add: prod_fun_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   637
        apply (subst Sum_any_right_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   638
        apply (rule fin2)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   639
        apply (subst Sum_any_right_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   640
         apply (rule fin1)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   641
        apply (subst Sum_any.swap [of ?AB])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   642
        apply (fact \<open>finite ?AB\<close>)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   643
        apply (auto simp add: mult_when ac_simps)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   644
        done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   645
    qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   646
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   647
  show "(a + b) * c = a * c + b * c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   648
  proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   649
    fix f g h :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   650
    assume fin_f: "finite {k. f k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   651
    assume fin_g: "finite {k. g k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   652
    assume fin_h: "finite {k. h k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   653
    show "prod_fun (\<lambda>k. f k + g k) h = (\<lambda>k. prod_fun f h k + prod_fun g h k)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   654
      apply (auto simp add: prod_fun_def fun_eq_iff algebra_simps)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   655
      apply (subst Sum_any.distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   656
      using fin_f apply (rule finite_mult_not_eq_zero_rightI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   657
      using fin_g apply (rule finite_mult_not_eq_zero_rightI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   658
      apply simp_all
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   659
      done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   660
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   661
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   662
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   663
instance poly_mapping :: (monoid_add, semiring_0_cancel) semiring_0_cancel
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   664
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   665
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   666
instance poly_mapping :: (comm_monoid_add, comm_semiring_0_cancel) comm_semiring_0_cancel
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   667
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   668
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   669
instance poly_mapping :: (monoid_add, semiring_1) semiring_1
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   670
proof
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   671
  fix a :: "'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   672
  show "1 * a = a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   673
    by transfer (simp add: prod_fun_def [abs_def] when_mult)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   674
  show "a * 1 = a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   675
    apply transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   676
    apply (simp add: prod_fun_def [abs_def] Sum_any_right_distrib Sum_any_left_distrib mult_when)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   677
    apply (subst when_commute)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   678
    apply simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   679
    done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   680
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   681
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   682
instance poly_mapping :: (comm_monoid_add, comm_semiring_1) comm_semiring_1
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   683
proof
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   684
  fix a :: "'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   685
  show "1 * a = a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   686
    by transfer (simp add: prod_fun_def [abs_def])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   687
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   688
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   689
instance poly_mapping :: (monoid_add, semiring_1_cancel) semiring_1_cancel
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   690
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   691
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   692
instance poly_mapping :: (monoid_add, ring) ring
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   693
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   694
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   695
instance poly_mapping :: (comm_monoid_add, comm_ring) comm_ring
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   696
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   697
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   698
instance poly_mapping :: (monoid_add, ring_1) ring_1
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   699
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   700
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   701
instance poly_mapping :: (comm_monoid_add, comm_ring_1) comm_ring_1
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   702
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   703
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   704
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   705
subsection \<open>Single-point mappings\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   706
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   707
lift_definition single :: "'a \<Rightarrow> 'b \<Rightarrow> 'a \<Rightarrow>\<^sub>0 'b::zero"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   708
  is "\<lambda>k v k'. (v when k = k')"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   709
  by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   710
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   711
lemma inj_single [iff]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   712
  "inj (single k)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   713
proof (rule injI, transfer)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   714
  fix k :: 'b and a b :: "'a::zero"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   715
  assume "(\<lambda>k'. a when k = k') = (\<lambda>k'. b when k = k')"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   716
  then have "(\<lambda>k'. a when k = k') k = (\<lambda>k'. b when k = k') k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   717
    by (rule arg_cong)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   718
  then show "a = b" by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   719
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   720
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   721
lemma lookup_single:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   722
  "lookup (single k v) k' = (v when k = k')"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   723
  by transfer rule
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   724
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   725
lemma lookup_single_eq [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   726
  "lookup (single k v) k = v"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   727
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   728
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   729
lemma lookup_single_not_eq:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   730
  "k \<noteq> k' \<Longrightarrow> lookup (single k v) k' = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   731
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   732
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   733
lemma single_zero [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   734
  "single k 0 = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   735
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   736
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   737
lemma single_one [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   738
  "single 0 1 = 1"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   739
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   740
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   741
lemma single_add:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   742
  "single k (a + b) = single k a + single k b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   743
  by transfer (simp add: fun_eq_iff when_add_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   744
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   745
lemma single_uminus:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   746
  "single k (- a) = - single k a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   747
  by transfer (simp add: fun_eq_iff when_uminus_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   748
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   749
lemma single_diff:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   750
  "single k (a - b) = single k a - single k b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   751
  by transfer (simp add: fun_eq_iff when_diff_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   752
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   753
lemma single_numeral [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   754
  "single 0 (numeral n) = numeral n"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   755
  by (induct n) (simp_all only: numeral.simps numeral_add single_zero single_one single_add)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   756
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   757
lemma lookup_numeral:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   758
  "lookup (numeral n) k = (numeral n when k = 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   759
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   760
  have "lookup (numeral n) k = lookup (single 0 (numeral n)) k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   761
    by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   762
  then show ?thesis unfolding lookup_single by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   763
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   764
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   765
lemma single_of_nat [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   766
  "single 0 (of_nat n) = of_nat n"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   767
  by (induct n) (simp_all add: single_add)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   768
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   769
lemma lookup_of_nat:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   770
  "lookup (of_nat n) k = (of_nat n when k = 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   771
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   772
  have "lookup (of_nat n) k = lookup (single 0 (of_nat n)) k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   773
    by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   774
  then show ?thesis unfolding lookup_single by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   775
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   776
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   777
lemma of_nat_single:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   778
  "of_nat = single 0 \<circ> of_nat"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   779
  by (simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   780
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   781
lemma mult_single:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   782
  "single k a * single l b = single (k + l) (a * b)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   783
proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   784
  fix k l :: 'a and a b :: 'b
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   785
  show "prod_fun (\<lambda>k'. a when k = k') (\<lambda>k'. b when l = k') = (\<lambda>k'. a * b when k + l = k')"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   786
  proof
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   787
    fix k'
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   788
    have "prod_fun (\<lambda>k'. a when k = k') (\<lambda>k'. b when l = k') k' = (\<Sum>n. a * b when l = n when k' = k + n)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   789
      by (simp add: prod_fun_def Sum_any_right_distrib mult_when when_mult)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   790
    also have "\<dots> = (\<Sum>n. a * b when k' = k + n when l = n)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   791
      by (simp add: when_when conj_commute)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   792
    also have "\<dots> = (a * b when k' = k + l)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   793
      by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   794
    also have "\<dots> = (a * b when k + l = k')"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   795
      by (simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   796
    finally show "prod_fun (\<lambda>k'. a when k = k') (\<lambda>k'. b when l = k') k' =
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   797
      (\<lambda>k'. a * b when k + l = k') k'" .
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   798
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   799
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   800
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   801
instance poly_mapping :: (monoid_add, semiring_char_0) semiring_char_0
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   802
  by intro_classes (auto intro: inj_compose inj_of_nat simp add: of_nat_single)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   803
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   804
instance poly_mapping :: (monoid_add, ring_char_0) ring_char_0
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   805
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   806
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   807
lemma single_of_int [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   808
  "single 0 (of_int k) = of_int k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   809
  by (cases k) (simp_all add: single_diff single_uminus)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   810
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   811
lemma lookup_of_int:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   812
  "lookup (of_int l) k = (of_int l when k = 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   813
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   814
  have "lookup (of_int l) k = lookup (single 0 (of_int l)) k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   815
    by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   816
  then show ?thesis unfolding lookup_single by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   817
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   818
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   819
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   820
subsection \<open>Integral domains\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   821
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   822
instance poly_mapping :: ("{ordered_cancel_comm_monoid_add, linorder}", semiring_no_zero_divisors) semiring_no_zero_divisors
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   823
  text \<open>The @{class "linorder"} constraint is a pragmatic device for the proof --- maybe it can be dropped\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   824
proof
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   825
  fix f g :: "'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   826
  assume "f \<noteq> 0" and "g \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   827
  then show "f * g \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   828
  proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   829
    fix f g :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   830
    define F where "F = {a. f a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   831
    moreover define G where "G = {a. g a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   832
    ultimately have [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   833
      "\<And>a. f a \<noteq> 0 \<longleftrightarrow> a \<in> F"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   834
      "\<And>b. g b \<noteq> 0 \<longleftrightarrow> b \<in> G"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   835
      by simp_all
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   836
    assume "finite {a. f a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   837
    then have [simp]: "finite F"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   838
      by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   839
    assume "finite {a. g a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   840
    then have [simp]: "finite G"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   841
      by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   842
    assume "f \<noteq> (\<lambda>a. 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   843
    then obtain a where "f a \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   844
      by (auto simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   845
    assume "g \<noteq> (\<lambda>b. 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   846
    then obtain b where "g b \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   847
      by (auto simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   848
    from \<open>f a \<noteq> 0\<close> and \<open>g b \<noteq> 0\<close> have "F \<noteq> {}" and "G \<noteq> {}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   849
      by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   850
    note Max_F = \<open>finite F\<close> \<open>F \<noteq> {}\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   851
    note Max_G = \<open>finite G\<close> \<open>G \<noteq> {}\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   852
    from Max_F and Max_G have [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   853
      "Max F \<in> F"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   854
      "Max G \<in> G"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   855
      by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   856
    from Max_F Max_G have [dest!]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   857
      "\<And>a. a \<in> F \<Longrightarrow> a \<le> Max F"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   858
      "\<And>b. b \<in> G \<Longrightarrow> b \<le> Max G"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   859
      by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   860
    define q where "q = Max F + Max G"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   861
    have "(\<Sum>(a, b). f a * g b when q = a + b) =
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   862
      (\<Sum>(a, b). f a * g b when q = a + b when a \<in> F \<and> b \<in> G)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   863
      by (rule Sum_any.cong) (auto simp add: split_def when_def q_def intro: ccontr)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   864
    also have "\<dots> =
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   865
      (\<Sum>(a, b). f a * g b when (Max F, Max G) = (a, b))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   866
    proof (rule Sum_any.cong)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   867
      fix ab :: "'a \<times> 'a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   868
      obtain a b where [simp]: "ab = (a, b)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   869
        by (cases ab) simp_all
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   870
      have [dest!]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   871
        "a \<le> Max F \<Longrightarrow> Max F \<noteq> a \<Longrightarrow> a < Max F"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   872
        "b \<le> Max G \<Longrightarrow> Max G \<noteq> b \<Longrightarrow> b < Max G"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   873
        by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   874
      show "(case ab of (a, b) \<Rightarrow> f a * g b when q = a + b when a \<in> F \<and> b \<in> G) =
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   875
         (case ab of (a, b) \<Rightarrow> f a * g b when (Max F, Max G) = (a, b))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   876
        by (auto simp add: split_def when_def q_def dest: add_strict_mono [of a "Max F" b "Max G"])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   877
    qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   878
    also have "\<dots> = (\<Sum>ab. (case ab of (a, b) \<Rightarrow> f a * g b) when
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   879
      (Max F, Max G) = ab)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   880
      unfolding split_def when_def by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   881
    also have "\<dots> \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   882
      by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   883
    finally have "prod_fun f g q \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   884
      by (simp add: prod_fun_unfold_prod)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   885
    then show "prod_fun f g \<noteq> (\<lambda>k. 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   886
      by (auto simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   887
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   888
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   889
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   890
instance poly_mapping :: ("{ordered_cancel_comm_monoid_add, linorder}", ring_no_zero_divisors) ring_no_zero_divisors
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   891
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   892
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   893
instance poly_mapping :: ("{ordered_cancel_comm_monoid_add, linorder}", ring_1_no_zero_divisors) ring_1_no_zero_divisors
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   894
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   895
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   896
instance poly_mapping :: ("{ordered_cancel_comm_monoid_add, linorder}", idom) idom
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   897
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   898
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   899
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   900
subsection \<open>Mapping order\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   901
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   902
instantiation poly_mapping :: (linorder, "{zero, linorder}") linorder
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   903
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   904
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   905
lift_definition less_poly_mapping :: "('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> ('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> bool"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   906
  is less_fun
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   907
  .
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   908
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   909
lift_definition less_eq_poly_mapping :: "('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> ('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> bool"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   910
  is "\<lambda>f g. less_fun f g \<or> f = g"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   911
  .
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   912
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   913
instance proof (rule class.Orderings.linorder.of_class.intro)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   914
  show "class.linorder (less_eq :: (_ \<Rightarrow>\<^sub>0 _) \<Rightarrow> _) less"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   915
  proof (rule linorder_strictI, rule order_strictI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   916
    fix f g h :: "'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   917
    show "f \<le> g \<longleftrightarrow> f < g \<or> f = g"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   918
      by transfer (rule refl)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   919
    show "\<not> f < f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   920
      by transfer (rule less_fun_irrefl)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   921
    show "f < g \<or> f = g \<or> g < f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   922
    proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   923
      fix f g :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   924
      assume "finite {k. f k \<noteq> 0}" and "finite {k. g k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   925
      then have "finite ({k. f k \<noteq> 0} \<union> {k. g k \<noteq> 0})"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   926
        by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   927
      moreover have "{k. f k \<noteq> g k} \<subseteq> {k. f k \<noteq> 0} \<union> {k. g k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   928
        by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   929
      ultimately have "finite {k. f k \<noteq> g k}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   930
        by (rule rev_finite_subset)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   931
      then show "less_fun f g \<or> f = g \<or> less_fun g f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   932
        by (rule less_fun_trichotomy)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   933
    qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   934
    assume "f < g" then show "\<not> g < f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   935
      by transfer (rule less_fun_asym)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   936
    note \<open>f < g\<close> moreover assume "g < h"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   937
      ultimately show "f < h"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   938
      by transfer (rule less_fun_trans)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   939
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   940
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   941
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   942
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   943
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   944
instance poly_mapping :: (linorder, "{ordered_comm_monoid_add, ordered_ab_semigroup_add_imp_le, linorder}") ordered_ab_semigroup_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   945
proof (intro_classes, transfer)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   946
  fix f g h :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   947
  assume *: "less_fun f g \<or> f = g"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   948
  { assume "less_fun f g"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   949
    then obtain k where "f k < g k" "(\<And>k'. k' < k \<Longrightarrow> f k' = g k')"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   950
      by (blast elim!: less_funE)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   951
    then have "h k + f k < h k + g k" "(\<And>k'. k' < k \<Longrightarrow> h k' + f k' = h k' + g k')"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   952
      by simp_all
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   953
    then have "less_fun (\<lambda>k. h k + f k) (\<lambda>k. h k + g k)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   954
      by (blast intro: less_funI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   955
  }
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   956
  with * show "less_fun (\<lambda>k. h k + f k) (\<lambda>k. h k + g k) \<or> (\<lambda>k. h k + f k) = (\<lambda>k. h k + g k)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   957
    by (auto simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   958
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   959
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   960
instance poly_mapping :: (linorder, "{ordered_comm_monoid_add, ordered_ab_semigroup_add_imp_le, cancel_comm_monoid_add, linorder}") linordered_cancel_ab_semigroup_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   961
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   962
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   963
instance poly_mapping :: (linorder, "{ordered_comm_monoid_add, ordered_ab_semigroup_add_imp_le, cancel_comm_monoid_add, linorder}") ordered_comm_monoid_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   964
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   965
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   966
instance poly_mapping :: (linorder, "{ordered_comm_monoid_add, ordered_ab_semigroup_add_imp_le, cancel_comm_monoid_add, linorder}") ordered_cancel_comm_monoid_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   967
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   968
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   969
instance poly_mapping :: (linorder, linordered_ab_group_add) linordered_ab_group_add
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   970
  ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   971
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   972
text \<open>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   973
  For pragmatism we leave out the final elements in the hierarchy:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   974
  @{class linordered_ring}, @{class linordered_ring_strict}, @{class linordered_idom};
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   975
  remember that the order instance is a mere technical device, not a deeper algebraic
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   976
  property.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   977
\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   978
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   979
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   980
subsection \<open>Fundamental mapping notions\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   981
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   982
lift_definition keys :: "('a \<Rightarrow>\<^sub>0 'b::zero) \<Rightarrow> 'a set"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   983
  is "\<lambda>f. {k. f k \<noteq> 0}" .
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   984
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   985
lift_definition range :: "('a \<Rightarrow>\<^sub>0 'b::zero) \<Rightarrow> 'b set"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   986
  is "\<lambda>f :: 'a \<Rightarrow> 'b. Set.range f - {0}" .
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   987
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   988
lemma finite_keys [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   989
  "finite (keys f)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   990
  by transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   991
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   992
lemma not_in_keys_iff_lookup_eq_zero:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   993
  "k \<notin> keys f \<longleftrightarrow> lookup f k = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   994
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   995
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   996
lemma lookup_not_eq_zero_eq_in_keys:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   997
  "lookup f k \<noteq> 0 \<longleftrightarrow> k \<in> keys f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   998
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
   999
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1000
lemma lookup_eq_zero_in_keys_contradict [dest]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1001
  "lookup f k = 0 \<Longrightarrow> \<not> k \<in> keys f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1002
  by (simp add: not_in_keys_iff_lookup_eq_zero)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1003
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1004
lemma finite_range [simp]: "finite (Poly_Mapping.range p)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1005
proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1006
  fix f :: "'b \<Rightarrow> 'a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1007
  assume *: "finite {x. f x \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1008
  have "Set.range f - {0} \<subseteq> f ` {x. f x \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1009
    by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1010
  thus "finite (Set.range f - {0})"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1011
    by(rule finite_subset)(rule finite_imageI[OF *])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1012
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1013
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1014
lemma in_keys_lookup_in_range [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1015
  "k \<in> keys f \<Longrightarrow> lookup f k \<in> range f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1016
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1017
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1018
lemma in_keys_iff: "x \<in> (keys s) = (lookup s x \<noteq> 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1019
  by (transfer, simp)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1020
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1021
lemma keys_zero [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1022
  "keys 0 = {}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1023
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1024
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1025
lemma range_zero [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1026
  "range 0 = {}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1027
  by transfer auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1028
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1029
lemma keys_add:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1030
  "keys (f + g) \<subseteq> keys f \<union> keys g"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1031
  by transfer auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1032
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1033
lemma keys_one [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1034
  "keys 1 = {0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1035
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1036
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1037
lemma range_one [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1038
  "range 1 = {1}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1039
  by transfer (auto simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1040
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1041
lemma keys_single [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1042
  "keys (single k v) = (if v = 0 then {} else {k})"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1043
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1044
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1045
lemma range_single [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1046
  "range (single k v) = (if v = 0 then {} else {v})"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1047
  by transfer (auto simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1048
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1049
lemma keys_mult:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1050
  "keys (f * g) \<subseteq> {a + b | a b. a \<in> keys f \<and> b \<in> keys g}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1051
  apply transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1052
  apply (auto simp add: prod_fun_def dest!: mult_not_zero elim!: Sum_any.not_neutral_obtains_not_neutral)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1053
  apply blast
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1054
  done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1055
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1056
lemma setsum_keys_plus_distrib:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1057
  assumes hom_0: "\<And>k. f k 0 = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1058
  and hom_plus: "\<And>k. k \<in> Poly_Mapping.keys p \<union> Poly_Mapping.keys q \<Longrightarrow> f k (Poly_Mapping.lookup p k + Poly_Mapping.lookup q k) = f k (Poly_Mapping.lookup p k) + f k (Poly_Mapping.lookup q k)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1059
  shows
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1060
  "(\<Sum>k\<in>Poly_Mapping.keys (p + q). f k (Poly_Mapping.lookup (p + q) k)) =
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1061
   (\<Sum>k\<in>Poly_Mapping.keys p. f k (Poly_Mapping.lookup p k)) +
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1062
   (\<Sum>k\<in>Poly_Mapping.keys q. f k (Poly_Mapping.lookup q k))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1063
  (is "?lhs = ?p + ?q")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1064
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1065
  let ?A = "Poly_Mapping.keys p \<union> Poly_Mapping.keys q"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1066
  have "?lhs = (\<Sum>k\<in>?A. f k (Poly_Mapping.lookup p k + Poly_Mapping.lookup q k))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1067
    apply(rule sum.mono_neutral_cong_left)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1068
       apply(simp_all add: Poly_Mapping.keys_add)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1069
     apply(transfer fixing: f)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1070
     apply(auto simp add: hom_0)[1]
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1071
    apply(transfer fixing: f)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1072
    apply(auto simp add: hom_0)[1]
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1073
    done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1074
  also have "\<dots> = (\<Sum>k\<in>?A. f k (Poly_Mapping.lookup p k) + f k (Poly_Mapping.lookup q k))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1075
    by(rule sum.cong)(simp_all add: hom_plus)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1076
  also have "\<dots> = (\<Sum>k\<in>?A. f k (Poly_Mapping.lookup p k)) + (\<Sum>k\<in>?A. f k (Poly_Mapping.lookup q k))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1077
    (is "_ = ?p' + ?q'")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1078
    by(simp add: sum.distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1079
  also have "?p' = ?p"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1080
    by (simp add: hom_0 in_keys_iff sum.mono_neutral_cong_right)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1081
  also have "?q' = ?q"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1082
    by (simp add: hom_0 in_keys_iff sum.mono_neutral_cong_right)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1083
  finally show ?thesis .
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1084
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1085
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1086
subsection \<open>Degree\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1087
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1088
definition degree :: "(nat \<Rightarrow>\<^sub>0 'a::zero) \<Rightarrow> nat"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1089
where
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1090
  "degree f = Max (insert 0 (Suc ` keys f))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1091
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1092
lemma degree_zero [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1093
  "degree 0 = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1094
  unfolding degree_def by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1095
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1096
lemma degree_one [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1097
  "degree 1 = 1"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1098
  unfolding degree_def by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1099
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1100
lemma degree_single_zero [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1101
  "degree (single k 0) = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1102
  unfolding degree_def by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1103
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1104
lemma degree_single_not_zero [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1105
  "v \<noteq> 0 \<Longrightarrow> degree (single k v) = Suc k"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1106
  unfolding degree_def by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1107
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1108
lemma degree_zero_iff [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1109
  "degree f = 0 \<longleftrightarrow> f = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1110
unfolding degree_def proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1111
  fix f :: "nat \<Rightarrow> 'a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1112
  assume "finite {n. f n \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1113
  then have fin: "finite (insert 0 (Suc ` {n. f n \<noteq> 0}))" by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1114
  show "Max (insert 0 (Suc ` {n. f n \<noteq> 0})) = 0 \<longleftrightarrow> f = (\<lambda>n. 0)" (is "?P \<longleftrightarrow> ?Q")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1115
  proof
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1116
    assume ?P
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1117
    have "{n. f n \<noteq> 0} = {}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1118
    proof (rule ccontr)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1119
      assume "{n. f n \<noteq> 0} \<noteq> {}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1120
      then obtain n where "n \<in> {n. f n \<noteq> 0}" by blast
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1121
      then have "{n. f n \<noteq> 0} = insert n {n. f n \<noteq> 0}" by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1122
      then have "Suc ` {n. f n \<noteq> 0} = insert (Suc n) (Suc ` {n. f n \<noteq> 0})" by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1123
      with \<open>?P\<close> have "Max (insert 0 (insert (Suc n) (Suc ` {n. f n \<noteq> 0}))) = 0" by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1124
      then have "Max (insert (Suc n) (insert 0 (Suc ` {n. f n \<noteq> 0}))) = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1125
        by (simp add: insert_commute)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1126
      with fin have "max (Suc n) (Max (insert 0 (Suc ` {n. f n \<noteq> 0}))) = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1127
        by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1128
      then show False by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1129
    qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1130
    then show ?Q by (simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1131
  next
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1132
    assume ?Q then show ?P by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1133
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1134
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1135
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1136
lemma degree_greater_zero_in_keys:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1137
  assumes "0 < degree f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1138
  shows "degree f - 1 \<in> keys f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1139
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1140
  from assms have "keys f \<noteq> {}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1141
    by (auto simp add: degree_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1142
  then show ?thesis unfolding degree_def
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1143
    by (simp add: mono_Max_commute [symmetric] mono_Suc)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1144
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1145
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1146
lemma in_keys_less_degree:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1147
  "n \<in> keys f \<Longrightarrow> n < degree f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1148
unfolding degree_def by transfer (auto simp add: Max_gr_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1149
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1150
lemma beyond_degree_lookup_zero:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1151
  "degree f \<le> n \<Longrightarrow> lookup f n = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1152
  unfolding degree_def by transfer auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1153
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1154
lemma degree_add:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1155
  "degree (f + g) \<le> max (degree f) (Poly_Mapping.degree g)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1156
unfolding degree_def proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1157
  fix f g :: "nat \<Rightarrow> 'a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1158
  assume f: "finite {x. f x \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1159
  assume g: "finite {x. g x \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1160
  let ?f = "Max (insert 0 (Suc ` {k. f k \<noteq> 0}))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1161
  let ?g = "Max (insert 0 (Suc ` {k. g k \<noteq> 0}))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1162
  have "Max (insert 0 (Suc ` {k. f k + g k \<noteq> 0})) \<le> Max (insert 0 (Suc ` ({k. f k \<noteq> 0} \<union> {k. g k \<noteq> 0})))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1163
    by (rule Max.subset_imp) (insert f g, auto)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1164
  also have "\<dots> = max ?f ?g"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1165
    using f g by (simp_all add: image_Un Max_Un [symmetric])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1166
  finally show "Max (insert 0 (Suc ` {k. f k + g k \<noteq> 0}))
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1167
    \<le> max (Max (insert 0 (Suc ` {k. f k \<noteq> 0}))) (Max (insert 0 (Suc ` {k. g k \<noteq> 0})))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1168
    .
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1169
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1170
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1171
lemma sorted_list_of_set_keys:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1172
  "sorted_list_of_set (keys f) = filter (\<lambda>k. k \<in> keys f) [0..<degree f]" (is "_ = ?r")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1173
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1174
  have "keys f = set ?r"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1175
    by (auto dest: in_keys_less_degree)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1176
  moreover have "sorted_list_of_set (set ?r) = ?r"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1177
    unfolding sorted_list_of_set_sort_remdups
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1178
    by (simp add: remdups_filter filter_sort [symmetric])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1179
  ultimately show ?thesis by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1180
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1181
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1182
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1183
subsection \<open>Inductive structure\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1184
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1185
lift_definition update :: "'a \<Rightarrow> 'b \<Rightarrow> ('a \<Rightarrow>\<^sub>0 'b::zero) \<Rightarrow> 'a \<Rightarrow>\<^sub>0 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1186
  is "\<lambda>k v f. f(k := v)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1187
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1188
  fix f :: "'a \<Rightarrow> 'b" and k' v
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1189
  assume "finite {k. f k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1190
  then have "finite (insert k' {k. f k \<noteq> 0})"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1191
    by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1192
  then show "finite {k. (f(k' := v)) k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1193
    by (rule rev_finite_subset) auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1194
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1195
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1196
lemma update_induct [case_names const update]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1197
  assumes const': "P 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1198
  assumes update': "\<And>f a b. a \<notin> keys f \<Longrightarrow> b \<noteq> 0 \<Longrightarrow> P f \<Longrightarrow> P (update a b f)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1199
  shows "P f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1200
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1201
  obtain g where "f = Abs_poly_mapping g" and "finite {a. g a \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1202
    by (cases f) simp_all
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1203
  define Q where "Q g = P (Abs_poly_mapping g)" for g
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1204
  from \<open>finite {a. g a \<noteq> 0}\<close> have "Q g"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1205
  proof (induct g rule: finite_update_induct)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1206
    case const with const' Q_def show ?case
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1207
      by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1208
  next
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1209
    case (update a b g)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1210
    from \<open>finite {a. g a \<noteq> 0}\<close> \<open>g a = 0\<close> have "a \<notin> keys (Abs_poly_mapping g)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1211
      by (simp add: Abs_poly_mapping_inverse keys.rep_eq)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1212
    moreover note \<open>b \<noteq> 0\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1213
    moreover from \<open>Q g\<close> have "P (Abs_poly_mapping g)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1214
      by (simp add: Q_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1215
    ultimately have "P (update a b (Abs_poly_mapping g))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1216
      by (rule update')
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1217
    also from \<open>finite {a. g a \<noteq> 0}\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1218
    have "update a b (Abs_poly_mapping g) = Abs_poly_mapping (g(a := b))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1219
      by (simp add: update.abs_eq eq_onp_same_args)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1220
    finally show ?case
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1221
      by (simp add: Q_def fun_upd_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1222
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1223
  then show ?thesis by (simp add: Q_def \<open>f = Abs_poly_mapping g\<close>)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1224
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1225
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1226
lemma lookup_update:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1227
  "lookup (update k v f) k' = (if k = k' then v else lookup f k')"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1228
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1229
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1230
lemma keys_update:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1231
  "keys (update k v f) = (if v = 0 then keys f - {k} else insert k (keys f))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1232
  by transfer auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1233
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1234
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1235
subsection \<open>Quasi-functorial structure\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1236
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1237
lift_definition map :: "('b::zero \<Rightarrow> 'c::zero)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1238
  \<Rightarrow> ('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> ('a \<Rightarrow>\<^sub>0 'c::zero)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1239
  is "\<lambda>g f k. g (f k) when f k \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1240
  by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1241
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1242
context
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1243
  fixes f :: "'b \<Rightarrow> 'a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1244
  assumes inj_f: "inj f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1245
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1246
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1247
lift_definition map_key :: "('a \<Rightarrow>\<^sub>0 'c::zero) \<Rightarrow> 'b \<Rightarrow>\<^sub>0 'c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1248
  is "\<lambda>p. p \<circ> f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1249
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1250
  fix g :: "'c \<Rightarrow> 'd" and p :: "'a \<Rightarrow> 'c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1251
  assume "finite {x. p x \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1252
  hence "finite (f ` {y. p (f y) \<noteq> 0})"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1253
    by(rule finite_subset[rotated]) auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1254
  thus "finite {x. (p \<circ> f) x \<noteq> 0}" unfolding o_def
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1255
    by(rule finite_imageD)(rule subset_inj_on[OF inj_f], simp)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1256
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1257
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1258
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1259
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1260
lemma map_key_compose:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1261
  assumes [transfer_rule]: "inj f" "inj g"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1262
  shows "map_key f (map_key g p) = map_key (g \<circ> f) p"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1263
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1264
  from assms have [transfer_rule]: "inj (g \<circ> f)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1265
    by(simp add: inj_compose)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1266
  show ?thesis by transfer(simp add: o_assoc)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1267
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1268
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1269
lemma map_key_id:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1270
  "map_key (\<lambda>x. x) p = p"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1271
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1272
  have [transfer_rule]: "inj (\<lambda>x. x)" by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1273
  show ?thesis by transfer(simp add: o_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1274
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1275
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1276
context
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1277
  fixes f :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1278
  assumes inj_f [transfer_rule]: "inj f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1279
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1280
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1281
lemma map_key_map:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1282
  "map_key f (map g p) = map g (map_key f p)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1283
  by transfer (simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1284
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1285
lemma map_key_plus:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1286
  "map_key f (p + q) = map_key f p + map_key f q"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1287
  by transfer (simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1288
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1289
lemma keys_map_key:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1290
  "keys (map_key f p) = f -` keys p"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1291
  by transfer auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1292
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1293
lemma map_key_zero [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1294
  "map_key f 0 = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1295
  by transfer (simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1296
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1297
lemma map_key_single [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1298
  "map_key f (single (f k) v) = single k v"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1299
  by transfer (simp add: fun_eq_iff inj_onD [OF inj_f] when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1300
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1301
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1302
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1303
lemma mult_map_scale_conv_mult: "map ((*) s) p = single 0 s * p"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1304
proof(transfer fixing: s)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1305
  fix p :: "'a \<Rightarrow> 'b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1306
  assume *: "finite {x. p x \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1307
  { fix x
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1308
    have "prod_fun (\<lambda>k'. s when 0 = k') p x =
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1309
          (\<Sum>l :: 'a. if l = 0 then s * (\<Sum>q. p q when x = q) else 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1310
      by(auto simp add: prod_fun_def when_def intro: Sum_any.cong simp del: Sum_any.delta)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1311
    also have "\<dots> = (\<lambda>k. s * p k when p k \<noteq> 0) x" by(simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1312
    also note calculation }
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1313
  then show "(\<lambda>k. s * p k when p k \<noteq> 0) = prod_fun (\<lambda>k'. s when 0 = k') p"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1314
    by(simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1315
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1316
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1317
lemma map_single [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1318
  "(c = 0 \<Longrightarrow> f 0 = 0) \<Longrightarrow> map f (single x c) = single x (f c)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1319
by transfer(auto simp add: fun_eq_iff when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1320
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1321
lemma map_eq_zero_iff: "map f p = 0 \<longleftrightarrow> (\<forall>k \<in> keys p. f (lookup p k) = 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1322
by transfer(auto simp add: fun_eq_iff when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1323
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1324
subsection \<open>Canonical dense representation of @{typ "nat \<Rightarrow>\<^sub>0 'a"}\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1325
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1326
abbreviation no_trailing_zeros :: "'a :: zero list \<Rightarrow> bool"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1327
where
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1328
  "no_trailing_zeros \<equiv> no_trailing ((=) 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1329
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1330
lift_definition "nth" :: "'a list \<Rightarrow> (nat \<Rightarrow>\<^sub>0 'a::zero)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1331
  is "nth_default 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1332
  by (fact finite_nth_default_neq_default)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1333
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1334
text \<open>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1335
  The opposite direction is directly specified on (later)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1336
  type \<open>nat_mapping\<close>.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1337
\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1338
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1339
lemma nth_Nil [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1340
  "nth [] = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1341
  by transfer (simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1342
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1343
lemma nth_singleton [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1344
  "nth [v] = single 0 v"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1345
proof (transfer, rule ext)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1346
  fix n :: nat and v :: 'a
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1347
  show "nth_default 0 [v] n = (v when 0 = n)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1348
    by (auto simp add: nth_default_def nth_append)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1349
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1350
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1351
lemma nth_replicate [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1352
  "nth (replicate n 0 @ [v]) = single n v"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1353
proof (transfer, rule ext)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1354
  fix m n :: nat and v :: 'a
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1355
  show "nth_default 0 (replicate n 0 @ [v]) m = (v when n = m)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1356
    by (auto simp add: nth_default_def nth_append)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1357
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1358
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1359
lemma nth_strip_while [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1360
  "nth (strip_while ((=) 0) xs) = nth xs"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1361
  by transfer (fact nth_default_strip_while_dflt)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1362
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1363
lemma nth_strip_while' [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1364
  "nth (strip_while (\<lambda>k. k = 0) xs) = nth xs"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1365
  by (subst eq_commute) (fact nth_strip_while)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1366
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1367
lemma nth_eq_iff:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1368
  "nth xs = nth ys \<longleftrightarrow> strip_while (HOL.eq 0) xs = strip_while (HOL.eq 0) ys"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1369
  by transfer (simp add: nth_default_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1370
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1371
lemma lookup_nth [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1372
  "lookup (nth xs) = nth_default 0 xs"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1373
  by (fact nth.rep_eq)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1374
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1375
lemma keys_nth [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1376
  "keys (nth xs) =  fst ` {(n, v) \<in> set (enumerate 0 xs). v \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1377
proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1378
  fix xs :: "'a list"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1379
  { fix n
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1380
    assume "nth_default 0 xs n \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1381
    then have "n < length xs" and "xs ! n \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1382
      by (auto simp add: nth_default_def split: if_splits)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1383
    then have "(n, xs ! n) \<in> {(n, v). (n, v) \<in> set (enumerate 0 xs) \<and> v \<noteq> 0}" (is "?x \<in> ?A")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1384
      by (auto simp add: in_set_conv_nth enumerate_eq_zip)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1385
    then have "fst ?x \<in> fst ` ?A"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1386
      by blast
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1387
    then have "n \<in> fst ` {(n, v). (n, v) \<in> set (enumerate 0 xs) \<and> v \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1388
      by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1389
  }
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1390
  then show "{k. nth_default 0 xs k \<noteq> 0} = fst ` {(n, v). (n, v) \<in> set (enumerate 0 xs) \<and> v \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1391
    by (auto simp add: in_enumerate_iff_nth_default_eq)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1392
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1393
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1394
lemma range_nth [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1395
  "range (nth xs) = set xs - {0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1396
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1397
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1398
lemma degree_nth:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1399
  "no_trailing_zeros xs \<Longrightarrow> degree (nth xs) = length xs"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1400
unfolding degree_def proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1401
  fix xs :: "'a list"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1402
  assume *: "no_trailing_zeros xs"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1403
  let ?A = "{n. nth_default 0 xs n \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1404
  let ?f = "nth_default 0 xs"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1405
  let ?bound = "Max (insert 0 (Suc ` {n. ?f n \<noteq> 0}))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1406
  show "?bound = length xs"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1407
  proof (cases "xs = []")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1408
    case False
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1409
    with * obtain n where n: "n < length xs" "xs ! n \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1410
      by (fastforce simp add: no_trailing_unfold last_conv_nth neq_Nil_conv)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1411
    then have "?bound = Max (Suc ` {k. (k < length xs \<longrightarrow> xs ! k \<noteq> (0::'a)) \<and> k < length xs})"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1412
      by (subst Max_insert) (auto simp add: nth_default_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1413
    also let ?A = "{k. k < length xs \<and> xs ! k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1414
    have "{k. (k < length xs \<longrightarrow> xs ! k \<noteq> (0::'a)) \<and> k < length xs} = ?A" by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1415
    also have "Max (Suc ` ?A) = Suc (Max ?A)" using n
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1416
      by (subst mono_Max_commute [where f = Suc, symmetric]) (auto simp add: mono_Suc)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1417
    also {
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1418
      have "Max ?A \<in> ?A" using n Max_in [of ?A] by fastforce
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1419
      hence "Suc (Max ?A) \<le> length xs" by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1420
      moreover from * False have "length xs - 1 \<in> ?A"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1421
        by(auto simp add: no_trailing_unfold last_conv_nth)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1422
      hence "length xs - 1 \<le> Max ?A" using Max_ge[of ?A "length xs - 1"] by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1423
      hence "length xs \<le> Suc (Max ?A)" by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1424
      ultimately have "Suc (Max ?A) = length xs" by simp }
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1425
    finally show ?thesis .
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1426
  qed simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1427
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1428
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1429
lemma nth_trailing_zeros [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1430
  "nth (xs @ replicate n 0) = nth xs"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1431
  by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1432
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1433
lemma nth_idem:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1434
  "nth (List.map (lookup f) [0..<degree f]) = f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1435
  unfolding degree_def by transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1436
    (auto simp add: nth_default_def fun_eq_iff not_less)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1437
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1438
lemma nth_idem_bound:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1439
  assumes "degree f \<le> n"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1440
  shows "nth (List.map (lookup f) [0..<n]) = f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1441
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1442
  from assms obtain m where "n = degree f + m"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1443
    by (blast dest: le_Suc_ex)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1444
  then have "[0..<n] = [0..<degree f] @ [degree f..<degree f + m]"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1445
    by (simp add: upt_add_eq_append [of 0])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1446
  moreover have "List.map (lookup f) [degree f..<degree f + m] = replicate m 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1447
    by (rule replicate_eqI) (auto simp add: beyond_degree_lookup_zero)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1448
  ultimately show ?thesis by (simp add: nth_idem)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1449
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1450
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1451
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1452
subsection \<open>Canonical sparse representation of @{typ "'a \<Rightarrow>\<^sub>0 'b"}\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1453
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1454
lift_definition the_value :: "('a \<times> 'b) list \<Rightarrow> 'a \<Rightarrow>\<^sub>0 'b::zero"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1455
  is "\<lambda>xs k. case map_of xs k of None \<Rightarrow> 0 | Some v \<Rightarrow> v"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1456
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1457
  fix xs :: "('a \<times> 'b) list"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1458
  have fin: "finite {k. \<exists>v. map_of xs k = Some v}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1459
    using finite_dom_map_of [of xs] unfolding dom_def by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1460
  then show "finite {k. (case map_of xs k of None \<Rightarrow> 0 | Some v \<Rightarrow> v) \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1461
    using fin by (simp split: option.split)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1462
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1463
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1464
definition items :: "('a::linorder \<Rightarrow>\<^sub>0 'b::zero) \<Rightarrow> ('a \<times> 'b) list"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1465
where
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1466
  "items f = List.map (\<lambda>k. (k, lookup f k)) (sorted_list_of_set (keys f))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1467
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1468
text \<open>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1469
  For the canonical sparse representation we provide both
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1470
  directions of morphisms since the specification of
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1471
  ordered association lists in theory \<open>OAList\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1472
  will support arbitrary linear orders @{class linorder}
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1473
  as keys, not just natural numbers @{typ nat}.
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1474
\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1475
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1476
lemma the_value_items [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1477
  "the_value (items f) = f"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1478
  unfolding items_def
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1479
  by transfer (simp add: fun_eq_iff map_of_map_restrict restrict_map_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1480
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1481
lemma lookup_the_value:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1482
  "lookup (the_value xs) k = (case map_of xs k of None \<Rightarrow> 0 | Some v \<Rightarrow> v)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1483
  by transfer rule
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1484
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1485
lemma items_the_value:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1486
  assumes "sorted (List.map fst xs)" and "distinct (List.map fst xs)" and "0 \<notin> snd ` set xs"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1487
  shows "items (the_value xs) = xs"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1488
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1489
  from assms have "sorted_list_of_set (set (List.map fst xs)) = List.map fst xs"
76484
defaa0b17424 generalized sorted_sort_id to sort_key_id_if_sorted
nipkow
parents: 75455
diff changeset
  1490
    unfolding sorted_list_of_set_sort_remdups by (simp add: distinct_remdups_id sort_key_id_if_sorted)
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1491
  moreover from assms have "keys (the_value xs) = fst ` set xs"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1492
    by transfer (auto simp add: image_def split: option.split dest: set_map_of_compr)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1493
  ultimately show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1494
    unfolding items_def using assms
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1495
    by (auto simp add: lookup_the_value intro: map_idI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1496
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1497
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1498
lemma the_value_Nil [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1499
  "the_value [] = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1500
  by transfer (simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1501
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1502
lemma the_value_Cons [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1503
  "the_value (x # xs) = update (fst x) (snd x) (the_value xs)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1504
  by transfer (simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1505
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1506
lemma items_zero [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1507
  "items 0 = []"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1508
  unfolding items_def by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1509
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1510
lemma items_one [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1511
  "items 1 = [(0, 1)]"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1512
  unfolding items_def by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1513
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1514
lemma items_single [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1515
  "items (single k v) = (if v = 0 then [] else [(k, v)])"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1516
  unfolding items_def by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1517
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1518
lemma in_set_items_iff [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1519
  "(k, v) \<in> set (items f) \<longleftrightarrow> k \<in> keys f \<and> lookup f k = v"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1520
  unfolding items_def by transfer auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1521
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1522
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1523
subsection \<open>Size estimation\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1524
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1525
context
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1526
  fixes f :: "'a \<Rightarrow> nat"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1527
  and g :: "'b :: zero \<Rightarrow> nat"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1528
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1529
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1530
definition poly_mapping_size :: "('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> nat"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1531
where
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1532
  "poly_mapping_size m = g 0 + (\<Sum>k \<in> keys m. Suc (f k + g (lookup m k)))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1533
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1534
lemma poly_mapping_size_0 [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1535
  "poly_mapping_size 0 = g 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1536
  by (simp add: poly_mapping_size_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1537
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1538
lemma poly_mapping_size_single [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1539
  "poly_mapping_size (single k v) = (if v = 0 then g 0 else g 0 + f k + g v + 1)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1540
  unfolding poly_mapping_size_def by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1541
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1542
lemma keys_less_poly_mapping_size:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1543
  "k \<in> keys m \<Longrightarrow> f k + g (lookup m k) < poly_mapping_size m"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1544
unfolding poly_mapping_size_def
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1545
proof transfer
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1546
  fix k :: 'a and m :: "'a \<Rightarrow> 'b" and f :: "'a \<Rightarrow> nat" and g
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1547
  let ?keys = "{k. m k \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1548
  assume *: "finite ?keys" "k \<in> ?keys"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1549
  then have "f k + g (m k) = (\<Sum>k' \<in> ?keys. f k' + g (m k') when k' = k)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1550
    by (simp add: sum.delta when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1551
  also have "\<dots> < (\<Sum>k' \<in> ?keys. Suc (f k' + g (m k')))" using *
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1552
    by (intro sum_strict_mono) (auto simp add: when_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1553
  also have "\<dots> \<le> g 0 + \<dots>" by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1554
  finally have "f k + g (m k) < \<dots>" .
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1555
  then show "f k + g (m k) < g 0 + (\<Sum>k | m k \<noteq> 0. Suc (f k + g (m k)))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1556
    by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1557
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1558
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1559
lemma lookup_le_poly_mapping_size:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1560
  "g (lookup m k) \<le> poly_mapping_size m"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1561
proof (cases "k \<in> keys m")
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1562
  case True
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1563
  with keys_less_poly_mapping_size [of k m]
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1564
  show ?thesis by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1565
next
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1566
  case False
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1567
  then show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1568
    by (simp add: Poly_Mapping.poly_mapping_size_def in_keys_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1569
qed 
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1570
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1571
lemma poly_mapping_size_estimation:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1572
  "k \<in> keys m \<Longrightarrow> y \<le> f k + g (lookup m k) \<Longrightarrow> y < poly_mapping_size m"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1573
  using keys_less_poly_mapping_size by (auto intro: le_less_trans)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1574
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1575
lemma poly_mapping_size_estimation2:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1576
  assumes "v \<in> range m" and "y \<le> g v"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1577
  shows "y < poly_mapping_size m"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1578
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1579
  from assms obtain k where *: "lookup m k = v" "v \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1580
    by transfer blast
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1581
  from * have "k \<in> keys m"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1582
    by (simp add: in_keys_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1583
  then show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1584
  proof (rule poly_mapping_size_estimation)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1585
    from assms * have "y \<le> g (lookup m k)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1586
      by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1587
    then show "y \<le> f k + g (lookup m k)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1588
      by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1589
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1590
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1591
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1592
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1593
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1594
lemma poly_mapping_size_one [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1595
  "poly_mapping_size f g 1 = g 0 + f 0 + g 1 + 1"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1596
  unfolding poly_mapping_size_def by transfer simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1597
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1598
lemma poly_mapping_size_cong [fundef_cong]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1599
  "m = m' \<Longrightarrow> g 0 = g' 0 \<Longrightarrow> (\<And>k. k \<in> keys m' \<Longrightarrow> f k = f' k)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1600
    \<Longrightarrow> (\<And>v. v \<in> range m' \<Longrightarrow> g v = g' v)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1601
    \<Longrightarrow> poly_mapping_size f g m = poly_mapping_size f' g' m'"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1602
  by (auto simp add: poly_mapping_size_def intro!: sum.cong)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1603
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1604
instantiation poly_mapping :: (type, zero) size
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1605
begin
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1606
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1607
definition "size = poly_mapping_size (\<lambda>_. 0) (\<lambda>_. 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1608
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1609
instance ..
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1610
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1611
end
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1612
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1613
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1614
subsection \<open>Further mapping operations and properties\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1615
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1616
text \<open>It is like in algebra: there are many definitions, some are also used\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1617
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1618
lift_definition mapp ::
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1619
  "('a \<Rightarrow> 'b :: zero \<Rightarrow> 'c :: zero) \<Rightarrow> ('a \<Rightarrow>\<^sub>0 'b) \<Rightarrow> ('a \<Rightarrow>\<^sub>0 'c)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1620
  is "\<lambda>f p k. (if k \<in> keys p then f k (lookup p k) else 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1621
  by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1622
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1623
lemma mapp_cong [fundef_cong]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1624
  "\<lbrakk> m = m'; \<And>k. k \<in> keys m' \<Longrightarrow> f k (lookup m' k) = f' k (lookup m' k) \<rbrakk>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1625
  \<Longrightarrow> mapp f m = mapp f' m'"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1626
  by transfer (auto simp add: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1627
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1628
lemma lookup_mapp:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1629
  "lookup (mapp f p) k = (f k (lookup p k) when k \<in> keys p)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1630
  by (simp add: mapp.rep_eq)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1631
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1632
lemma keys_mapp_subset: "keys (mapp f p) \<subseteq> keys p"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1633
  by (meson in_keys_iff mapp.rep_eq subsetI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1634
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1635
subsection\<open>Free Abelian Groups Over a Type\<close>
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1636
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1637
abbreviation frag_of :: "'a \<Rightarrow> 'a \<Rightarrow>\<^sub>0 int"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1638
  where "frag_of c \<equiv> Poly_Mapping.single c (1::int)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1639
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1640
lemma lookup_frag_of [simp]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1641
   "Poly_Mapping.lookup(frag_of c) = (\<lambda>x. if x = c then 1 else 0)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1642
  by (force simp add: lookup_single_not_eq)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1643
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1644
lemma frag_of_nonzero [simp]: "frag_of a \<noteq> 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1645
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1646
  let ?f = "\<lambda>x. if x = a then 1 else (0::int)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1647
  have "?f \<noteq> (\<lambda>x. 0::int)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1648
    by (auto simp: fun_eq_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1649
  then have "Poly_Mapping.lookup (Abs_poly_mapping ?f) \<noteq> Poly_Mapping.lookup (Abs_poly_mapping (\<lambda>x. 0))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1650
    by fastforce
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1651
  then show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1652
    by (metis lookup_single_eq lookup_zero)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1653
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1654
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1655
definition frag_cmul :: "int \<Rightarrow> ('a \<Rightarrow>\<^sub>0 int) \<Rightarrow> ('a \<Rightarrow>\<^sub>0 int)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1656
  where "frag_cmul c a = Abs_poly_mapping (\<lambda>x. c * Poly_Mapping.lookup a x)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1657
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1658
lemma frag_cmul_zero [simp]: "frag_cmul 0 x = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1659
  by (simp add: frag_cmul_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1660
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1661
lemma frag_cmul_zero2 [simp]: "frag_cmul c 0 = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1662
  by (simp add: frag_cmul_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1663
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1664
lemma frag_cmul_one [simp]: "frag_cmul 1 x = x"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1665
  by (auto simp: frag_cmul_def Poly_Mapping.poly_mapping.lookup_inverse)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1666
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1667
lemma frag_cmul_minus_one [simp]: "frag_cmul (-1) x = -x"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1668
  by (simp add: frag_cmul_def uminus_poly_mapping_def poly_mapping_eqI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1669
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1670
lemma frag_cmul_cmul [simp]: "frag_cmul c (frag_cmul d x) = frag_cmul (c*d) x"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1671
  by (simp add: frag_cmul_def mult_ac)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1672
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1673
lemma lookup_frag_cmul [simp]: "poly_mapping.lookup (frag_cmul c x) i = c * poly_mapping.lookup x i"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1674
  by (simp add: frag_cmul_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1675
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1676
lemma minus_frag_cmul [simp]: "- frag_cmul k x = frag_cmul (-k) x"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1677
  by (simp add: poly_mapping_eqI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1678
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1679
lemma keys_frag_of: "Poly_Mapping.keys(frag_of a) = {a}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1680
  by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1681
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1682
lemma finite_cmul_nonzero: "finite {x. c * Poly_Mapping.lookup a x \<noteq> (0::int)}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1683
  by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1684
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1685
lemma keys_cmul: "Poly_Mapping.keys(frag_cmul c a) \<subseteq> Poly_Mapping.keys a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1686
  using finite_cmul_nonzero [of c a]
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1687
  by (metis lookup_frag_cmul mult_zero_right not_in_keys_iff_lookup_eq_zero subsetI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1688
  
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1689
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1690
lemma keys_cmul_iff [iff]: "i \<in> Poly_Mapping.keys (frag_cmul c x) \<longleftrightarrow> i \<in> Poly_Mapping.keys x \<and> c \<noteq> 0"
75455
91c16c5ad3e9 tidied auto / simp with null arguments
paulson <lp15@cam.ac.uk>
parents: 73932
diff changeset
  1691
  apply auto
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1692
  apply (meson subsetD keys_cmul)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1693
  by (metis in_keys_iff lookup_frag_cmul mult_eq_0_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1694
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1695
lemma keys_minus [simp]: "Poly_Mapping.keys(-a) = Poly_Mapping.keys a"
73932
fd21b4a93043 added opaque_combs and renamed hide_lams to opaque_lifting
desharna
parents: 73655
diff changeset
  1696
  by (metis (no_types, opaque_lifting) in_keys_iff lookup_uminus neg_equal_0_iff_equal subsetI subset_antisym)
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1697
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1698
lemma keys_diff: 
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1699
  "Poly_Mapping.keys(a - b) \<subseteq> Poly_Mapping.keys a \<union> Poly_Mapping.keys b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1700
  by (auto simp add: in_keys_iff lookup_minus)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1701
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1702
lemma keys_eq_empty [simp]: "Poly_Mapping.keys c = {} \<longleftrightarrow> c = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1703
  by (metis in_keys_iff keys_zero lookup_zero poly_mapping_eqI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1704
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1705
lemma frag_cmul_eq_0_iff [simp]: "frag_cmul k c = 0 \<longleftrightarrow> k=0 \<or> c=0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1706
  by auto (metis subsetI subset_antisym keys_cmul_iff keys_eq_empty)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1707
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1708
lemma frag_of_eq: "frag_of x = frag_of y \<longleftrightarrow> x = y"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1709
  by (metis lookup_single_eq lookup_single_not_eq zero_neq_one)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1710
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1711
lemma frag_cmul_distrib: "frag_cmul (c+d) a = frag_cmul c a + frag_cmul d a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1712
  by (simp add: frag_cmul_def plus_poly_mapping_def int_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1713
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1714
lemma frag_cmul_distrib2: "frag_cmul c (a+b) = frag_cmul c a + frag_cmul c b"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1715
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1716
  have "finite {x. poly_mapping.lookup a x + poly_mapping.lookup b x \<noteq> 0}"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1717
    using keys_add [of a b]
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1718
    by (metis (no_types, lifting) finite_keys finite_subset keys.rep_eq lookup_add mem_Collect_eq subsetI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1719
  then show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1720
    by (simp add: frag_cmul_def plus_poly_mapping_def int_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1721
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1722
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1723
lemma frag_cmul_diff_distrib: "frag_cmul (a - b) c = frag_cmul a c - frag_cmul b c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1724
  by (auto simp: left_diff_distrib lookup_minus poly_mapping_eqI)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1725
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1726
lemma frag_cmul_sum:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1727
     "frag_cmul a (sum b I) = (\<Sum>i\<in>I. frag_cmul a (b i))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1728
proof (induction rule: infinite_finite_induct)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1729
  case (insert i I)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1730
  then show ?case
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1731
    by (auto simp: algebra_simps frag_cmul_distrib2)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1732
qed auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1733
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1734
lemma keys_sum: "Poly_Mapping.keys(sum b I) \<subseteq> (\<Union>i \<in>I. Poly_Mapping.keys(b i))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1735
proof (induction I rule: infinite_finite_induct)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1736
  case (insert i I)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1737
  then show ?case
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1738
    using keys_add [of "b i" "sum b I"] by auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1739
qed auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1740
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1741
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1742
definition frag_extend :: "('b \<Rightarrow> 'a \<Rightarrow>\<^sub>0 int) \<Rightarrow> ('b \<Rightarrow>\<^sub>0 int) \<Rightarrow> 'a \<Rightarrow>\<^sub>0 int"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1743
  where "frag_extend b x \<equiv> (\<Sum>i \<in> Poly_Mapping.keys x. frag_cmul (Poly_Mapping.lookup x i) (b i))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1744
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1745
lemma frag_extend_0 [simp]: "frag_extend b 0 = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1746
  by (simp add: frag_extend_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1747
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1748
lemma frag_extend_of [simp]: "frag_extend f (frag_of a) = f a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1749
  by (simp add: frag_extend_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1750
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1751
lemma frag_extend_cmul:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1752
   "frag_extend f (frag_cmul c x) = frag_cmul c (frag_extend f x)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1753
  by (auto simp: frag_extend_def frag_cmul_sum intro: sum.mono_neutral_cong_left)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1754
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1755
lemma frag_extend_minus:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1756
   "frag_extend f (- x) = - (frag_extend f x)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1757
  using frag_extend_cmul [of f "-1"] by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1758
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1759
lemma frag_extend_add:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1760
  "frag_extend f (a+b) = (frag_extend f a) + (frag_extend f b)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1761
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1762
  have *: "(\<Sum>i\<in>Poly_Mapping.keys a. frag_cmul (poly_mapping.lookup a i) (f i)) 
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1763
         = (\<Sum>i\<in>Poly_Mapping.keys a \<union> Poly_Mapping.keys b. frag_cmul (poly_mapping.lookup a i) (f i))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1764
          "(\<Sum>i\<in>Poly_Mapping.keys b. frag_cmul (poly_mapping.lookup b i) (f i)) 
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1765
         = (\<Sum>i\<in>Poly_Mapping.keys a \<union> Poly_Mapping.keys b. frag_cmul (poly_mapping.lookup b i) (f i))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1766
    by (auto simp: in_keys_iff intro: sum.mono_neutral_cong_left)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1767
  have "frag_extend f (a+b) = (\<Sum>i\<in>Poly_Mapping.keys (a + b).
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1768
       frag_cmul (poly_mapping.lookup a i) (f i) + frag_cmul (poly_mapping.lookup b i) (f i)) "
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1769
    by (auto simp: frag_extend_def Poly_Mapping.lookup_add frag_cmul_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1770
  also have "... = (\<Sum>i \<in> Poly_Mapping.keys a \<union> Poly_Mapping.keys b. frag_cmul (poly_mapping.lookup a i) (f i) 
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1771
                         + frag_cmul (poly_mapping.lookup b i) (f i))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1772
    apply (rule sum.mono_neutral_cong_left)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1773
    using keys_add [of a b]
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1774
     apply (auto simp add: in_keys_iff plus_poly_mapping.rep_eq frag_cmul_distrib [symmetric])
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1775
    done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1776
  also have "... = (frag_extend f a) + (frag_extend f b)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1777
    by (auto simp: * sum.distrib frag_extend_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1778
  finally show ?thesis .
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1779
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1780
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1781
lemma frag_extend_diff:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1782
   "frag_extend f (a-b) = (frag_extend f a) - (frag_extend f b)"
73932
fd21b4a93043 added opaque_combs and renamed hide_lams to opaque_lifting
desharna
parents: 73655
diff changeset
  1783
  by (metis (no_types, opaque_lifting) add_uminus_conv_diff frag_extend_add frag_extend_minus)
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1784
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1785
lemma frag_extend_sum:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1786
   "finite I \<Longrightarrow> frag_extend f (\<Sum>i\<in>I. g i) = sum (frag_extend f o g) I"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1787
  by (induction I rule: finite_induct) (simp_all add: frag_extend_add)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1788
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1789
lemma frag_extend_eq:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1790
   "(\<And>f. f \<in> Poly_Mapping.keys c \<Longrightarrow> g f = h f) \<Longrightarrow> frag_extend g c = frag_extend h c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1791
  by (simp add: frag_extend_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1792
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1793
lemma frag_extend_eq_0:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1794
   "(\<And>x. x \<in> Poly_Mapping.keys c \<Longrightarrow> f x = 0) \<Longrightarrow> frag_extend f c = 0"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1795
  by (simp add: frag_extend_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1796
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1797
lemma keys_frag_extend: "Poly_Mapping.keys(frag_extend f c) \<subseteq> (\<Union>x \<in> Poly_Mapping.keys c. Poly_Mapping.keys(f x))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1798
  unfolding frag_extend_def
73655
26a1d66b9077 tuned proofs --- avoid z3, which is absent on arm64-linux;
wenzelm
parents: 70045
diff changeset
  1799
  using keys_sum by fastforce
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1800
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1801
lemma frag_expansion: "a = frag_extend frag_of a"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1802
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1803
  have *: "finite I
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1804
        \<Longrightarrow> Poly_Mapping.lookup (\<Sum>i\<in>I. frag_cmul (Poly_Mapping.lookup a i) (frag_of i)) j =
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1805
            (if j \<in> I then Poly_Mapping.lookup a j else 0)" for I j
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1806
    by (induction I rule: finite_induct) (auto simp: lookup_single lookup_add)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1807
  show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1808
    unfolding frag_extend_def
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1809
    by (rule poly_mapping_eqI) (fastforce simp add: in_keys_iff *)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1810
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1811
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1812
lemma frag_closure_minus_cmul:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1813
  assumes "P 0" and P: "\<And>x y. \<lbrakk>P x; P y\<rbrakk> \<Longrightarrow> P(x - y)" "P c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1814
  shows "P(frag_cmul k c)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1815
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1816
  have "P (frag_cmul (int n) c)" for n
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1817
    apply (induction n)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1818
     apply (simp_all add: assms frag_cmul_distrib)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1819
    by (metis add.left_neutral add_diff_cancel_right' add_uminus_conv_diff P)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1820
  then show ?thesis
73932
fd21b4a93043 added opaque_combs and renamed hide_lams to opaque_lifting
desharna
parents: 73655
diff changeset
  1821
    by (metis (no_types, opaque_lifting) add_diff_eq assms(2) diff_add_cancel frag_cmul_distrib int_diff_cases)
70043
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1822
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1823
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1824
lemma frag_induction [consumes 1, case_names zero one diff]:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1825
  assumes supp: "Poly_Mapping.keys c \<subseteq> S"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1826
    and 0: "P 0" and sing: "\<And>x. x \<in> S \<Longrightarrow> P(frag_of x)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1827
    and diff: "\<And>a b. \<lbrakk>P a; P b\<rbrakk> \<Longrightarrow> P(a - b)"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1828
  shows "P c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1829
proof -
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1830
  have "P (\<Sum>i\<in>I. frag_cmul (poly_mapping.lookup c i) (frag_of i))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1831
    if "I \<subseteq> Poly_Mapping.keys c" for I
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1832
    using finite_subset [OF that finite_keys [of c]] that supp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1833
  proof (induction I arbitrary: c rule: finite_induct)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1834
    case empty
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1835
    then show ?case
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1836
      by (auto simp: 0)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1837
  next
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1838
    case (insert i I c)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1839
    have ab: "a+b = a - (0 - b)" for a b :: "'a \<Rightarrow>\<^sub>0 int"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1840
      by simp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1841
    have Pfrag: "P (frag_cmul (poly_mapping.lookup c i) (frag_of i))"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1842
      by (metis "0" diff frag_closure_minus_cmul insert.prems insert_subset sing subset_iff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1843
    show ?case
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1844
      apply (simp add: insert.hyps)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1845
      apply (subst ab)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1846
      using insert apply (blast intro: assms Pfrag)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1847
      done
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1848
  qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1849
  then show ?thesis
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1850
    by (subst frag_expansion) (auto simp add: frag_extend_def)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1851
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1852
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1853
lemma frag_extend_compose:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1854
  "frag_extend f (frag_extend (frag_of o g) c) = frag_extend (f o g) c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1855
  using subset_UNIV
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1856
  by (induction c rule: frag_induction) (auto simp: frag_extend_diff)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1857
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1858
lemma frag_split:
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1859
  fixes c :: "'a \<Rightarrow>\<^sub>0 int"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1860
  assumes "Poly_Mapping.keys c \<subseteq> S \<union> T"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1861
  obtains d e where "Poly_Mapping.keys d \<subseteq> S" "Poly_Mapping.keys e \<subseteq> T" "d + e = c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1862
proof 
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1863
  let ?d = "frag_extend (\<lambda>f. if f \<in> S then frag_of f else 0) c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1864
  let ?e = "frag_extend (\<lambda>f. if f \<in> S then 0 else frag_of f) c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1865
  show "Poly_Mapping.keys ?d \<subseteq> S" "Poly_Mapping.keys ?e \<subseteq> T"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1866
    using assms by (auto intro!: order_trans [OF keys_frag_extend] split: if_split_asm)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1867
  show "?d + ?e = c"
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1868
    using assms
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1869
  proof (induction c rule: frag_induction)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1870
    case (diff a b)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1871
    then show ?case
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1872
      by (metis (no_types, lifting) frag_extend_diff add_diff_eq diff_add_eq diff_add_eq_diff_diff_swap)
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1873
  qed auto
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1874
qed
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1875
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1876
hide_const (open) lookup single update keys range map map_key degree nth the_value items foldr mapp
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1877
350acd367028 theory Poly_Mapping
paulson <lp15@cam.ac.uk>
parents:
diff changeset
  1878
end