| author | blanchet | 
| Wed, 24 Feb 2010 11:35:39 +0100 | |
| changeset 35341 | c6bbfa9c4eca | 
| parent 35032 | 7efe662e41b4 | 
| child 35416 | d8d7d1b785af | 
| permissions | -rw-r--r-- | 
| 14593 | 1 | (* Title: HOL/Matrix/Matrix.thy | 
| 2 | Author: Steven Obua | |
| 3 | *) | |
| 4 | ||
| 17915 | 5 | theory Matrix | 
| 35032 
7efe662e41b4
separate library theory for type classes combining lattices with various algebraic structures
 haftmann parents: 
35028diff
changeset | 6 | imports Main Lattice_Algebras | 
| 17915 | 7 | begin | 
| 14940 | 8 | |
| 27484 | 9 | types 'a infmatrix = "nat \<Rightarrow> nat \<Rightarrow> 'a" | 
| 10 | ||
| 11 | definition nonzero_positions :: "(nat \<Rightarrow> nat \<Rightarrow> 'a::zero) \<Rightarrow> nat \<times> nat \<Rightarrow> bool" where | |
| 12 |   "nonzero_positions A = {pos. A (fst pos) (snd pos) ~= 0}"
 | |
| 13 | ||
| 14 | typedef 'a matrix = "{(f::(nat \<Rightarrow> nat \<Rightarrow> 'a::zero)). finite (nonzero_positions f)}"
 | |
| 15 | proof - | |
| 16 |   have "(\<lambda>j i. 0) \<in> {(f::(nat \<Rightarrow> nat \<Rightarrow> 'a::zero)). finite (nonzero_positions f)}"
 | |
| 17 | by (simp add: nonzero_positions_def) | |
| 18 | then show ?thesis by auto | |
| 19 | qed | |
| 20 | ||
| 21 | declare Rep_matrix_inverse[simp] | |
| 22 | ||
| 23 | lemma finite_nonzero_positions : "finite (nonzero_positions (Rep_matrix A))" | |
| 24 | apply (rule Abs_matrix_induct) | |
| 25 | by (simp add: Abs_matrix_inverse matrix_def) | |
| 26 | ||
| 27 | constdefs | |
| 28 |   nrows :: "('a::zero) matrix \<Rightarrow> nat"
 | |
| 29 |   "nrows A == if nonzero_positions(Rep_matrix A) = {} then 0 else Suc(Max ((image fst) (nonzero_positions (Rep_matrix A))))"
 | |
| 30 |   ncols :: "('a::zero) matrix \<Rightarrow> nat"
 | |
| 31 |   "ncols A == if nonzero_positions(Rep_matrix A) = {} then 0 else Suc(Max ((image snd) (nonzero_positions (Rep_matrix A))))"
 | |
| 32 | ||
| 33 | lemma nrows: | |
| 34 | assumes hyp: "nrows A \<le> m" | |
| 35 | shows "(Rep_matrix A m n) = 0" (is ?concl) | |
| 36 | proof cases | |
| 37 |   assume "nonzero_positions(Rep_matrix A) = {}"
 | |
| 38 | then show "(Rep_matrix A m n) = 0" by (simp add: nonzero_positions_def) | |
| 39 | next | |
| 40 |   assume a: "nonzero_positions(Rep_matrix A) \<noteq> {}"
 | |
| 41 | let ?S = "fst`(nonzero_positions(Rep_matrix A))" | |
| 42 | have c: "finite (?S)" by (simp add: finite_nonzero_positions) | |
| 43 | from hyp have d: "Max (?S) < m" by (simp add: a nrows_def) | |
| 44 | have "m \<notin> ?S" | |
| 45 | proof - | |
| 46 | have "m \<in> ?S \<Longrightarrow> m <= Max(?S)" by (simp add: Max_ge [OF c]) | |
| 47 | moreover from d have "~(m <= Max ?S)" by (simp) | |
| 48 | ultimately show "m \<notin> ?S" by (auto) | |
| 49 | qed | |
| 50 | thus "Rep_matrix A m n = 0" by (simp add: nonzero_positions_def image_Collect) | |
| 51 | qed | |
| 52 | ||
| 53 | constdefs | |
| 54 | transpose_infmatrix :: "'a infmatrix \<Rightarrow> 'a infmatrix" | |
| 55 | "transpose_infmatrix A j i == A i j" | |
| 56 |   transpose_matrix :: "('a::zero) matrix \<Rightarrow> 'a matrix"
 | |
| 57 | "transpose_matrix == Abs_matrix o transpose_infmatrix o Rep_matrix" | |
| 58 | ||
| 59 | declare transpose_infmatrix_def[simp] | |
| 60 | ||
| 61 | lemma transpose_infmatrix_twice[simp]: "transpose_infmatrix (transpose_infmatrix A) = A" | |
| 62 | by ((rule ext)+, simp) | |
| 63 | ||
| 64 | lemma transpose_infmatrix: "transpose_infmatrix (% j i. P j i) = (% j i. P i j)" | |
| 65 | apply (rule ext)+ | |
| 66 | by (simp add: transpose_infmatrix_def) | |
| 67 | ||
| 68 | lemma transpose_infmatrix_closed[simp]: "Rep_matrix (Abs_matrix (transpose_infmatrix (Rep_matrix x))) = transpose_infmatrix (Rep_matrix x)" | |
| 69 | apply (rule Abs_matrix_inverse) | |
| 70 | apply (simp add: matrix_def nonzero_positions_def image_def) | |
| 71 | proof - | |
| 72 |   let ?A = "{pos. Rep_matrix x (snd pos) (fst pos) \<noteq> 0}"
 | |
| 73 | let ?swap = "% pos. (snd pos, fst pos)" | |
| 74 |   let ?B = "{pos. Rep_matrix x (fst pos) (snd pos) \<noteq> 0}"
 | |
| 75 | have swap_image: "?swap`?A = ?B" | |
| 76 | apply (simp add: image_def) | |
| 77 | apply (rule set_ext) | |
| 78 | apply (simp) | |
| 79 | proof | |
| 80 | fix y | |
| 81 | assume hyp: "\<exists>a b. Rep_matrix x b a \<noteq> 0 \<and> y = (b, a)" | |
| 82 | thus "Rep_matrix x (fst y) (snd y) \<noteq> 0" | |
| 83 | proof - | |
| 84 | from hyp obtain a b where "(Rep_matrix x b a \<noteq> 0 & y = (b,a))" by blast | |
| 85 | then show "Rep_matrix x (fst y) (snd y) \<noteq> 0" by (simp) | |
| 86 | qed | |
| 87 | next | |
| 88 | fix y | |
| 89 | assume hyp: "Rep_matrix x (fst y) (snd y) \<noteq> 0" | |
| 90 | show "\<exists> a b. (Rep_matrix x b a \<noteq> 0 & y = (b,a))" | |
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32491diff
changeset | 91 | by (rule exI[of _ "snd y"], rule exI[of _ "fst y"]) (simp add: hyp) | 
| 27484 | 92 | qed | 
| 93 | then have "finite (?swap`?A)" | |
| 94 | proof - | |
| 95 | have "finite (nonzero_positions (Rep_matrix x))" by (simp add: finite_nonzero_positions) | |
| 96 | then have "finite ?B" by (simp add: nonzero_positions_def) | |
| 97 | with swap_image show "finite (?swap`?A)" by (simp) | |
| 98 | qed | |
| 99 | moreover | |
| 100 | have "inj_on ?swap ?A" by (simp add: inj_on_def) | |
| 101 | ultimately show "finite ?A"by (rule finite_imageD[of ?swap ?A]) | |
| 102 | qed | |
| 103 | ||
| 104 | lemma infmatrixforward: "(x::'a infmatrix) = y \<Longrightarrow> \<forall> a b. x a b = y a b" by auto | |
| 105 | ||
| 106 | lemma transpose_infmatrix_inject: "(transpose_infmatrix A = transpose_infmatrix B) = (A = B)" | |
| 107 | apply (auto) | |
| 108 | apply (rule ext)+ | |
| 109 | apply (simp add: transpose_infmatrix) | |
| 110 | apply (drule infmatrixforward) | |
| 111 | apply (simp) | |
| 112 | done | |
| 113 | ||
| 114 | lemma transpose_matrix_inject: "(transpose_matrix A = transpose_matrix B) = (A = B)" | |
| 115 | apply (simp add: transpose_matrix_def) | |
| 116 | apply (subst Rep_matrix_inject[THEN sym])+ | |
| 117 | apply (simp only: transpose_infmatrix_closed transpose_infmatrix_inject) | |
| 118 | done | |
| 119 | ||
| 120 | lemma transpose_matrix[simp]: "Rep_matrix(transpose_matrix A) j i = Rep_matrix A i j" | |
| 121 | by (simp add: transpose_matrix_def) | |
| 122 | ||
| 123 | lemma transpose_transpose_id[simp]: "transpose_matrix (transpose_matrix A) = A" | |
| 124 | by (simp add: transpose_matrix_def) | |
| 125 | ||
| 126 | lemma nrows_transpose[simp]: "nrows (transpose_matrix A) = ncols A" | |
| 127 | by (simp add: nrows_def ncols_def nonzero_positions_def transpose_matrix_def image_def) | |
| 128 | ||
| 129 | lemma ncols_transpose[simp]: "ncols (transpose_matrix A) = nrows A" | |
| 130 | by (simp add: nrows_def ncols_def nonzero_positions_def transpose_matrix_def image_def) | |
| 131 | ||
| 132 | lemma ncols: "ncols A <= n \<Longrightarrow> Rep_matrix A m n = 0" | |
| 133 | proof - | |
| 134 | assume "ncols A <= n" | |
| 135 | then have "nrows (transpose_matrix A) <= n" by (simp) | |
| 136 | then have "Rep_matrix (transpose_matrix A) n m = 0" by (rule nrows) | |
| 137 | thus "Rep_matrix A m n = 0" by (simp add: transpose_matrix_def) | |
| 138 | qed | |
| 139 | ||
| 140 | lemma ncols_le: "(ncols A <= n) = (! j i. n <= i \<longrightarrow> (Rep_matrix A j i) = 0)" (is "_ = ?st") | |
| 141 | apply (auto) | |
| 142 | apply (simp add: ncols) | |
| 143 | proof (simp add: ncols_def, auto) | |
| 144 | let ?P = "nonzero_positions (Rep_matrix A)" | |
| 145 | let ?p = "snd`?P" | |
| 146 | have a:"finite ?p" by (simp add: finite_nonzero_positions) | |
| 147 | let ?m = "Max ?p" | |
| 148 | assume "~(Suc (?m) <= n)" | |
| 149 | then have b:"n <= ?m" by (simp) | |
| 150 | fix a b | |
| 151 | assume "(a,b) \<in> ?P" | |
| 152 |   then have "?p \<noteq> {}" by (auto)
 | |
| 153 | with a have "?m \<in> ?p" by (simp) | |
| 154 | moreover have "!x. (x \<in> ?p \<longrightarrow> (? y. (Rep_matrix A y x) \<noteq> 0))" by (simp add: nonzero_positions_def image_def) | |
| 155 | ultimately have "? y. (Rep_matrix A y ?m) \<noteq> 0" by (simp) | |
| 156 | moreover assume ?st | |
| 157 | ultimately show "False" using b by (simp) | |
| 158 | qed | |
| 159 | ||
| 160 | lemma less_ncols: "(n < ncols A) = (? j i. n <= i & (Rep_matrix A j i) \<noteq> 0)" (is ?concl) | |
| 161 | proof - | |
| 162 | have a: "!! (a::nat) b. (a < b) = (~(b <= a))" by arith | |
| 163 | show ?concl by (simp add: a ncols_le) | |
| 164 | qed | |
| 165 | ||
| 166 | lemma le_ncols: "(n <= ncols A) = (\<forall> m. (\<forall> j i. m <= i \<longrightarrow> (Rep_matrix A j i) = 0) \<longrightarrow> n <= m)" (is ?concl) | |
| 167 | apply (auto) | |
| 168 | apply (subgoal_tac "ncols A <= m") | |
| 169 | apply (simp) | |
| 170 | apply (simp add: ncols_le) | |
| 171 | apply (drule_tac x="ncols A" in spec) | |
| 172 | by (simp add: ncols) | |
| 173 | ||
| 174 | lemma nrows_le: "(nrows A <= n) = (! j i. n <= j \<longrightarrow> (Rep_matrix A j i) = 0)" (is ?s) | |
| 175 | proof - | |
| 176 | have "(nrows A <= n) = (ncols (transpose_matrix A) <= n)" by (simp) | |
| 177 | also have "\<dots> = (! j i. n <= i \<longrightarrow> (Rep_matrix (transpose_matrix A) j i = 0))" by (rule ncols_le) | |
| 178 | also have "\<dots> = (! j i. n <= i \<longrightarrow> (Rep_matrix A i j) = 0)" by (simp) | |
| 179 | finally show "(nrows A <= n) = (! j i. n <= j \<longrightarrow> (Rep_matrix A j i) = 0)" by (auto) | |
| 180 | qed | |
| 181 | ||
| 182 | lemma less_nrows: "(m < nrows A) = (? j i. m <= j & (Rep_matrix A j i) \<noteq> 0)" (is ?concl) | |
| 183 | proof - | |
| 184 | have a: "!! (a::nat) b. (a < b) = (~(b <= a))" by arith | |
| 185 | show ?concl by (simp add: a nrows_le) | |
| 186 | qed | |
| 187 | ||
| 188 | lemma le_nrows: "(n <= nrows A) = (\<forall> m. (\<forall> j i. m <= j \<longrightarrow> (Rep_matrix A j i) = 0) \<longrightarrow> n <= m)" (is ?concl) | |
| 189 | apply (auto) | |
| 190 | apply (subgoal_tac "nrows A <= m") | |
| 191 | apply (simp) | |
| 192 | apply (simp add: nrows_le) | |
| 193 | apply (drule_tac x="nrows A" in spec) | |
| 194 | by (simp add: nrows) | |
| 195 | ||
| 196 | lemma nrows_notzero: "Rep_matrix A m n \<noteq> 0 \<Longrightarrow> m < nrows A" | |
| 197 | apply (case_tac "nrows A <= m") | |
| 198 | apply (simp_all add: nrows) | |
| 199 | done | |
| 200 | ||
| 201 | lemma ncols_notzero: "Rep_matrix A m n \<noteq> 0 \<Longrightarrow> n < ncols A" | |
| 202 | apply (case_tac "ncols A <= n") | |
| 203 | apply (simp_all add: ncols) | |
| 204 | done | |
| 205 | ||
| 206 | lemma finite_natarray1: "finite {x. x < (n::nat)}"
 | |
| 207 | apply (induct n) | |
| 208 | apply (simp) | |
| 209 | proof - | |
| 210 | fix n | |
| 211 |   have "{x. x < Suc n} = insert n {x. x < n}"  by (rule set_ext, simp, arith)
 | |
| 212 |   moreover assume "finite {x. x < n}"
 | |
| 213 |   ultimately show "finite {x. x < Suc n}" by (simp)
 | |
| 214 | qed | |
| 215 | ||
| 216 | lemma finite_natarray2: "finite {pos. (fst pos) < (m::nat) & (snd pos) < (n::nat)}"
 | |
| 217 | apply (induct m) | |
| 218 | apply (simp+) | |
| 219 | proof - | |
| 220 | fix m::nat | |
| 221 |     let ?s0 = "{pos. fst pos < m & snd pos < n}"
 | |
| 222 |     let ?s1 = "{pos. fst pos < (Suc m) & snd pos < n}"
 | |
| 223 |     let ?sd = "{pos. fst pos = m & snd pos < n}"
 | |
| 224 | assume f0: "finite ?s0" | |
| 225 | have f1: "finite ?sd" | |
| 226 | proof - | |
| 227 | let ?f = "% x. (m, x)" | |
| 228 |       have "{pos. fst pos = m & snd pos < n} = ?f ` {x. x < n}" by (rule set_ext, simp add: image_def, auto)
 | |
| 229 |       moreover have "finite {x. x < n}" by (simp add: finite_natarray1)
 | |
| 230 |       ultimately show "finite {pos. fst pos = m & snd pos < n}" by (simp)
 | |
| 231 | qed | |
| 232 | have su: "?s0 \<union> ?sd = ?s1" by (rule set_ext, simp, arith) | |
| 233 | from f0 f1 have "finite (?s0 \<union> ?sd)" by (rule finite_UnI) | |
| 234 | with su show "finite ?s1" by (simp) | |
| 235 | qed | |
| 236 | ||
| 237 | lemma RepAbs_matrix: | |
| 238 | assumes aem: "? m. ! j i. m <= j \<longrightarrow> x j i = 0" (is ?em) and aen:"? n. ! j i. (n <= i \<longrightarrow> x j i = 0)" (is ?en) | |
| 239 | shows "(Rep_matrix (Abs_matrix x)) = x" | |
| 240 | apply (rule Abs_matrix_inverse) | |
| 241 | apply (simp add: matrix_def nonzero_positions_def) | |
| 242 | proof - | |
| 243 | from aem obtain m where a: "! j i. m <= j \<longrightarrow> x j i = 0" by (blast) | |
| 244 | from aen obtain n where b: "! j i. n <= i \<longrightarrow> x j i = 0" by (blast) | |
| 245 |   let ?u = "{pos. x (fst pos) (snd pos) \<noteq> 0}"
 | |
| 246 |   let ?v = "{pos. fst pos < m & snd pos < n}"
 | |
| 247 | have c: "!! (m::nat) a. ~(m <= a) \<Longrightarrow> a < m" by (arith) | |
| 248 |   from a b have "(?u \<inter> (-?v)) = {}"
 | |
| 249 | apply (simp) | |
| 250 | apply (rule set_ext) | |
| 251 | apply (simp) | |
| 252 | apply auto | |
| 253 | by (rule c, auto)+ | |
| 254 | then have d: "?u \<subseteq> ?v" by blast | |
| 255 | moreover have "finite ?v" by (simp add: finite_natarray2) | |
| 256 | ultimately show "finite ?u" by (rule finite_subset) | |
| 257 | qed | |
| 258 | ||
| 259 | constdefs | |
| 260 |   apply_infmatrix :: "('a \<Rightarrow> 'b) \<Rightarrow> 'a infmatrix \<Rightarrow> 'b infmatrix"
 | |
| 261 | "apply_infmatrix f == % A. (% j i. f (A j i))" | |
| 262 |   apply_matrix :: "('a \<Rightarrow> 'b) \<Rightarrow> ('a::zero) matrix \<Rightarrow> ('b::zero) matrix"
 | |
| 263 | "apply_matrix f == % A. Abs_matrix (apply_infmatrix f (Rep_matrix A))" | |
| 264 |   combine_infmatrix :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> 'a infmatrix \<Rightarrow> 'b infmatrix \<Rightarrow> 'c infmatrix"
 | |
| 265 | "combine_infmatrix f == % A B. (% j i. f (A j i) (B j i))" | |
| 266 |   combine_matrix :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> ('a::zero) matrix \<Rightarrow> ('b::zero) matrix \<Rightarrow> ('c::zero) matrix"
 | |
| 267 | "combine_matrix f == % A B. Abs_matrix (combine_infmatrix f (Rep_matrix A) (Rep_matrix B))" | |
| 268 | ||
| 269 | lemma expand_apply_infmatrix[simp]: "apply_infmatrix f A j i = f (A j i)" | |
| 270 | by (simp add: apply_infmatrix_def) | |
| 271 | ||
| 272 | lemma expand_combine_infmatrix[simp]: "combine_infmatrix f A B j i = f (A j i) (B j i)" | |
| 273 | by (simp add: combine_infmatrix_def) | |
| 274 | ||
| 275 | constdefs | |
| 276 | commutative :: "('a \<Rightarrow> 'a \<Rightarrow> 'b) \<Rightarrow> bool"
 | |
| 277 | "commutative f == ! x y. f x y = f y x" | |
| 278 | associative :: "('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> bool"
 | |
| 279 | "associative f == ! x y z. f (f x y) z = f x (f y z)" | |
| 280 | ||
| 281 | text{*
 | |
| 282 | To reason about associativity and commutativity of operations on matrices, | |
| 283 | let's take a step back and look at the general situtation: Assume that we have | |
| 284 | sets $A$ and $B$ with $B \subset A$ and an abstraction $u: A \rightarrow B$. This abstraction has to fulfill $u(b) = b$ for all $b \in B$, but is arbitrary otherwise. | |
| 285 | Each function $f: A \times A \rightarrow A$ now induces a function $f': B \times B \rightarrow B$ by $f' = u \circ f$. | |
| 286 | It is obvious that commutativity of $f$ implies commutativity of $f'$: $f' x y = u (f x y) = u (f y x) = f' y x.$ | |
| 287 | *} | |
| 288 | ||
| 289 | lemma combine_infmatrix_commute: | |
| 290 | "commutative f \<Longrightarrow> commutative (combine_infmatrix f)" | |
| 291 | by (simp add: commutative_def combine_infmatrix_def) | |
| 292 | ||
| 293 | lemma combine_matrix_commute: | |
| 294 | "commutative f \<Longrightarrow> commutative (combine_matrix f)" | |
| 295 | by (simp add: combine_matrix_def commutative_def combine_infmatrix_def) | |
| 296 | ||
| 297 | text{*
 | |
| 298 | On the contrary, given an associative function $f$ we cannot expect $f'$ to be associative. A counterexample is given by $A=\ganz$, $B=\{-1, 0, 1\}$,
 | |
| 299 | as $f$ we take addition on $\ganz$, which is clearly associative. The abstraction is given by $u(a) = 0$ for $a \notin B$. Then we have | |
| 300 | \[ f' (f' 1 1) -1 = u(f (u (f 1 1)) -1) = u(f (u 2) -1) = u (f 0 -1) = -1, \] | |
| 301 | but on the other hand we have | |
| 302 | \[ f' 1 (f' 1 -1) = u (f 1 (u (f 1 -1))) = u (f 1 0) = 1.\] | |
| 303 | A way out of this problem is to assume that $f(A\times A)\subset A$ holds, and this is what we are going to do: | |
| 304 | *} | |
| 305 | ||
| 306 | lemma nonzero_positions_combine_infmatrix[simp]: "f 0 0 = 0 \<Longrightarrow> nonzero_positions (combine_infmatrix f A B) \<subseteq> (nonzero_positions A) \<union> (nonzero_positions B)" | |
| 307 | by (rule subsetI, simp add: nonzero_positions_def combine_infmatrix_def, auto) | |
| 308 | ||
| 309 | lemma finite_nonzero_positions_Rep[simp]: "finite (nonzero_positions (Rep_matrix A))" | |
| 310 | by (insert Rep_matrix [of A], simp add: matrix_def) | |
| 311 | ||
| 312 | lemma combine_infmatrix_closed [simp]: | |
| 313 | "f 0 0 = 0 \<Longrightarrow> Rep_matrix (Abs_matrix (combine_infmatrix f (Rep_matrix A) (Rep_matrix B))) = combine_infmatrix f (Rep_matrix A) (Rep_matrix B)" | |
| 314 | apply (rule Abs_matrix_inverse) | |
| 315 | apply (simp add: matrix_def) | |
| 316 | apply (rule finite_subset[of _ "(nonzero_positions (Rep_matrix A)) \<union> (nonzero_positions (Rep_matrix B))"]) | |
| 317 | by (simp_all) | |
| 318 | ||
| 319 | text {* We need the next two lemmas only later, but it is analog to the above one, so we prove them now: *}
 | |
| 320 | lemma nonzero_positions_apply_infmatrix[simp]: "f 0 = 0 \<Longrightarrow> nonzero_positions (apply_infmatrix f A) \<subseteq> nonzero_positions A" | |
| 321 | by (rule subsetI, simp add: nonzero_positions_def apply_infmatrix_def, auto) | |
| 322 | ||
| 323 | lemma apply_infmatrix_closed [simp]: | |
| 324 | "f 0 = 0 \<Longrightarrow> Rep_matrix (Abs_matrix (apply_infmatrix f (Rep_matrix A))) = apply_infmatrix f (Rep_matrix A)" | |
| 325 | apply (rule Abs_matrix_inverse) | |
| 326 | apply (simp add: matrix_def) | |
| 327 | apply (rule finite_subset[of _ "nonzero_positions (Rep_matrix A)"]) | |
| 328 | by (simp_all) | |
| 329 | ||
| 330 | lemma combine_infmatrix_assoc[simp]: "f 0 0 = 0 \<Longrightarrow> associative f \<Longrightarrow> associative (combine_infmatrix f)" | |
| 331 | by (simp add: associative_def combine_infmatrix_def) | |
| 332 | ||
| 333 | lemma comb: "f = g \<Longrightarrow> x = y \<Longrightarrow> f x = g y" | |
| 334 | by (auto) | |
| 335 | ||
| 336 | lemma combine_matrix_assoc: "f 0 0 = 0 \<Longrightarrow> associative f \<Longrightarrow> associative (combine_matrix f)" | |
| 337 | apply (simp(no_asm) add: associative_def combine_matrix_def, auto) | |
| 338 | apply (rule comb [of Abs_matrix Abs_matrix]) | |
| 339 | by (auto, insert combine_infmatrix_assoc[of f], simp add: associative_def) | |
| 340 | ||
| 341 | lemma Rep_apply_matrix[simp]: "f 0 = 0 \<Longrightarrow> Rep_matrix (apply_matrix f A) j i = f (Rep_matrix A j i)" | |
| 342 | by (simp add: apply_matrix_def) | |
| 343 | ||
| 344 | lemma Rep_combine_matrix[simp]: "f 0 0 = 0 \<Longrightarrow> Rep_matrix (combine_matrix f A B) j i = f (Rep_matrix A j i) (Rep_matrix B j i)" | |
| 345 | by(simp add: combine_matrix_def) | |
| 346 | ||
| 347 | lemma combine_nrows_max: "f 0 0 = 0 \<Longrightarrow> nrows (combine_matrix f A B) <= max (nrows A) (nrows B)" | |
| 348 | by (simp add: nrows_le) | |
| 349 | ||
| 350 | lemma combine_ncols_max: "f 0 0 = 0 \<Longrightarrow> ncols (combine_matrix f A B) <= max (ncols A) (ncols B)" | |
| 351 | by (simp add: ncols_le) | |
| 352 | ||
| 353 | lemma combine_nrows: "f 0 0 = 0 \<Longrightarrow> nrows A <= q \<Longrightarrow> nrows B <= q \<Longrightarrow> nrows(combine_matrix f A B) <= q" | |
| 354 | by (simp add: nrows_le) | |
| 355 | ||
| 356 | lemma combine_ncols: "f 0 0 = 0 \<Longrightarrow> ncols A <= q \<Longrightarrow> ncols B <= q \<Longrightarrow> ncols(combine_matrix f A B) <= q" | |
| 357 | by (simp add: ncols_le) | |
| 358 | ||
| 359 | constdefs | |
| 360 |   zero_r_neutral :: "('a \<Rightarrow> 'b::zero \<Rightarrow> 'a) \<Rightarrow> bool"
 | |
| 361 | "zero_r_neutral f == ! a. f a 0 = a" | |
| 362 |   zero_l_neutral :: "('a::zero \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> bool"
 | |
| 363 | "zero_l_neutral f == ! a. f 0 a = a" | |
| 364 |   zero_closed :: "(('a::zero) \<Rightarrow> ('b::zero) \<Rightarrow> ('c::zero)) \<Rightarrow> bool"
 | |
| 365 | "zero_closed f == (!x. f x 0 = 0) & (!y. f 0 y = 0)" | |
| 366 | ||
| 367 | consts foldseq :: "('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> (nat \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> 'a"
 | |
| 368 | primrec | |
| 369 | "foldseq f s 0 = s 0" | |
| 370 | "foldseq f s (Suc n) = f (s 0) (foldseq f (% k. s(Suc k)) n)" | |
| 371 | ||
| 372 | consts foldseq_transposed ::  "('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> (nat \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> 'a"
 | |
| 373 | primrec | |
| 374 | "foldseq_transposed f s 0 = s 0" | |
| 375 | "foldseq_transposed f s (Suc n) = f (foldseq_transposed f s n) (s (Suc n))" | |
| 376 | ||
| 377 | lemma foldseq_assoc : "associative f \<Longrightarrow> foldseq f = foldseq_transposed f" | |
| 378 | proof - | |
| 379 | assume a:"associative f" | |
| 380 | then have sublemma: "!! n. ! N s. N <= n \<longrightarrow> foldseq f s N = foldseq_transposed f s N" | |
| 381 | proof - | |
| 382 | fix n | |
| 383 | show "!N s. N <= n \<longrightarrow> foldseq f s N = foldseq_transposed f s N" | |
| 384 | proof (induct n) | |
| 385 | show "!N s. N <= 0 \<longrightarrow> foldseq f s N = foldseq_transposed f s N" by simp | |
| 386 | next | |
| 387 | fix n | |
| 388 | assume b:"! N s. N <= n \<longrightarrow> foldseq f s N = foldseq_transposed f s N" | |
| 389 | have c:"!!N s. N <= n \<Longrightarrow> foldseq f s N = foldseq_transposed f s N" by (simp add: b) | |
| 390 | show "! N t. N <= Suc n \<longrightarrow> foldseq f t N = foldseq_transposed f t N" | |
| 391 | proof (auto) | |
| 392 | fix N t | |
| 393 | assume Nsuc: "N <= Suc n" | |
| 394 | show "foldseq f t N = foldseq_transposed f t N" | |
| 395 | proof cases | |
| 396 | assume "N <= n" | |
| 397 | then show "foldseq f t N = foldseq_transposed f t N" by (simp add: b) | |
| 398 | next | |
| 399 | assume "~(N <= n)" | |
| 400 | with Nsuc have Nsuceq: "N = Suc n" by simp | |
| 401 | have neqz: "n \<noteq> 0 \<Longrightarrow> ? m. n = Suc m & Suc m <= n" by arith | |
| 402 | have assocf: "!! x y z. f x (f y z) = f (f x y) z" by (insert a, simp add: associative_def) | |
| 403 | show "foldseq f t N = foldseq_transposed f t N" | |
| 404 | apply (simp add: Nsuceq) | |
| 405 | apply (subst c) | |
| 406 | apply (simp) | |
| 407 | apply (case_tac "n = 0") | |
| 408 | apply (simp) | |
| 409 | apply (drule neqz) | |
| 410 | apply (erule exE) | |
| 411 | apply (simp) | |
| 412 | apply (subst assocf) | |
| 413 | proof - | |
| 414 | fix m | |
| 415 | assume "n = Suc m & Suc m <= n" | |
| 416 | then have mless: "Suc m <= n" by arith | |
| 417 | then have step1: "foldseq_transposed f (% k. t (Suc k)) m = foldseq f (% k. t (Suc k)) m" (is "?T1 = ?T2") | |
| 418 | apply (subst c) | |
| 419 | by simp+ | |
| 420 | have step2: "f (t 0) ?T2 = foldseq f t (Suc m)" (is "_ = ?T3") by simp | |
| 421 | have step3: "?T3 = foldseq_transposed f t (Suc m)" (is "_ = ?T4") | |
| 422 | apply (subst c) | |
| 423 | by (simp add: mless)+ | |
| 424 | have step4: "?T4 = f (foldseq_transposed f t m) (t (Suc m))" (is "_=?T5") by simp | |
| 425 | from step1 step2 step3 step4 show sowhat: "f (f (t 0) ?T1) (t (Suc (Suc m))) = f ?T5 (t (Suc (Suc m)))" by simp | |
| 426 | qed | |
| 427 | qed | |
| 428 | qed | |
| 429 | qed | |
| 430 | qed | |
| 431 | show "foldseq f = foldseq_transposed f" by ((rule ext)+, insert sublemma, auto) | |
| 432 | qed | |
| 433 | ||
| 434 | lemma foldseq_distr: "\<lbrakk>associative f; commutative f\<rbrakk> \<Longrightarrow> foldseq f (% k. f (u k) (v k)) n = f (foldseq f u n) (foldseq f v n)" | |
| 435 | proof - | |
| 436 | assume assoc: "associative f" | |
| 437 | assume comm: "commutative f" | |
| 438 | from assoc have a:"!! x y z. f (f x y) z = f x (f y z)" by (simp add: associative_def) | |
| 439 | from comm have b: "!! x y. f x y = f y x" by (simp add: commutative_def) | |
| 440 | from assoc comm have c: "!! x y z. f x (f y z) = f y (f x z)" by (simp add: commutative_def associative_def) | |
| 441 | have "!! n. (! u v. foldseq f (%k. f (u k) (v k)) n = f (foldseq f u n) (foldseq f v n))" | |
| 442 | apply (induct_tac n) | |
| 443 | apply (simp+, auto) | |
| 444 | by (simp add: a b c) | |
| 445 | then show "foldseq f (% k. f (u k) (v k)) n = f (foldseq f u n) (foldseq f v n)" by simp | |
| 446 | qed | |
| 447 | ||
| 448 | theorem "\<lbrakk>associative f; associative g; \<forall>a b c d. g (f a b) (f c d) = f (g a c) (g b d); ? x y. (f x) \<noteq> (f y); ? x y. (g x) \<noteq> (g y); f x x = x; g x x = x\<rbrakk> \<Longrightarrow> f=g | (! y. f y x = y) | (! y. g y x = y)" | |
| 449 | oops | |
| 450 | (* Model found | |
| 451 | ||
| 452 | Trying to find a model that refutes: \<lbrakk>associative f; associative g; | |
| 453 | \<forall>a b c d. g (f a b) (f c d) = f (g a c) (g b d); \<exists>x y. f x \<noteq> f y; | |
| 454 | \<exists>x y. g x \<noteq> g y; f x x = x; g x x = x\<rbrakk> | |
| 455 | \<Longrightarrow> f = g \<or> (\<forall>y. f y x = y) \<or> (\<forall>y. g y x = y) | |
| 456 | Searching for a model of size 1, translating term... invoking SAT solver... no model found. | |
| 457 | Searching for a model of size 2, translating term... invoking SAT solver... no model found. | |
| 458 | Searching for a model of size 3, translating term... invoking SAT solver... | |
| 459 | Model found: | |
| 460 | Size of types: 'a: 3 | |
| 461 | x: a1 | |
| 462 | g: (a0\<mapsto>(a0\<mapsto>a1, a1\<mapsto>a0, a2\<mapsto>a1), a1\<mapsto>(a0\<mapsto>a0, a1\<mapsto>a1, a2\<mapsto>a0), a2\<mapsto>(a0\<mapsto>a1, a1\<mapsto>a0, a2\<mapsto>a1)) | |
| 463 | f: (a0\<mapsto>(a0\<mapsto>a0, a1\<mapsto>a0, a2\<mapsto>a0), a1\<mapsto>(a0\<mapsto>a1, a1\<mapsto>a1, a2\<mapsto>a1), a2\<mapsto>(a0\<mapsto>a0, a1\<mapsto>a0, a2\<mapsto>a0)) | |
| 464 | *) | |
| 465 | ||
| 466 | lemma foldseq_zero: | |
| 467 | assumes fz: "f 0 0 = 0" and sz: "! i. i <= n \<longrightarrow> s i = 0" | |
| 468 | shows "foldseq f s n = 0" | |
| 469 | proof - | |
| 470 | have "!! n. ! s. (! i. i <= n \<longrightarrow> s i = 0) \<longrightarrow> foldseq f s n = 0" | |
| 471 | apply (induct_tac n) | |
| 472 | apply (simp) | |
| 473 | by (simp add: fz) | |
| 474 | then show "foldseq f s n = 0" by (simp add: sz) | |
| 475 | qed | |
| 476 | ||
| 477 | lemma foldseq_significant_positions: | |
| 478 | assumes p: "! i. i <= N \<longrightarrow> S i = T i" | |
| 479 | shows "foldseq f S N = foldseq f T N" (is ?concl) | |
| 480 | proof - | |
| 481 | have "!! m . ! s t. (! i. i<=m \<longrightarrow> s i = t i) \<longrightarrow> foldseq f s m = foldseq f t m" | |
| 482 | apply (induct_tac m) | |
| 483 | apply (simp) | |
| 484 | apply (simp) | |
| 485 | apply (auto) | |
| 486 | proof - | |
| 487 | fix n | |
| 488 | fix s::"nat\<Rightarrow>'a" | |
| 489 | fix t::"nat\<Rightarrow>'a" | |
| 490 | assume a: "\<forall>s t. (\<forall>i\<le>n. s i = t i) \<longrightarrow> foldseq f s n = foldseq f t n" | |
| 491 | assume b: "\<forall>i\<le>Suc n. s i = t i" | |
| 492 | have c:"!! a b. a = b \<Longrightarrow> f (t 0) a = f (t 0) b" by blast | |
| 493 | have d:"!! s t. (\<forall>i\<le>n. s i = t i) \<Longrightarrow> foldseq f s n = foldseq f t n" by (simp add: a) | |
| 494 | show "f (t 0) (foldseq f (\<lambda>k. s (Suc k)) n) = f (t 0) (foldseq f (\<lambda>k. t (Suc k)) n)" by (rule c, simp add: d b) | |
| 495 | qed | |
| 496 | with p show ?concl by simp | |
| 497 | qed | |
| 498 | ||
| 499 | lemma foldseq_tail: "M <= N \<Longrightarrow> foldseq f S N = foldseq f (% k. (if k < M then (S k) else (foldseq f (% k. S(k+M)) (N-M)))) M" (is "?p \<Longrightarrow> ?concl") | |
| 500 | proof - | |
| 501 | have suc: "!! a b. \<lbrakk>a <= Suc b; a \<noteq> Suc b\<rbrakk> \<Longrightarrow> a <= b" by arith | |
| 502 | have a:"!! a b c . a = b \<Longrightarrow> f c a = f c b" by blast | |
| 503 | have "!! n. ! m s. m <= n \<longrightarrow> foldseq f s n = foldseq f (% k. (if k < m then (s k) else (foldseq f (% k. s(k+m)) (n-m)))) m" | |
| 504 | apply (induct_tac n) | |
| 505 | apply (simp) | |
| 506 | apply (simp) | |
| 507 | apply (auto) | |
| 508 | apply (case_tac "m = Suc na") | |
| 509 | apply (simp) | |
| 510 | apply (rule a) | |
| 511 | apply (rule foldseq_significant_positions) | |
| 512 | apply (auto) | |
| 513 | apply (drule suc, simp+) | |
| 514 | proof - | |
| 515 | fix na m s | |
| 516 | assume suba:"\<forall>m\<le>na. \<forall>s. foldseq f s na = foldseq f (\<lambda>k. if k < m then s k else foldseq f (\<lambda>k. s (k + m)) (na - m))m" | |
| 517 | assume subb:"m <= na" | |
| 518 | from suba have subc:"!! m s. m <= na \<Longrightarrow>foldseq f s na = foldseq f (\<lambda>k. if k < m then s k else foldseq f (\<lambda>k. s (k + m)) (na - m))m" by simp | |
| 519 | have subd: "foldseq f (\<lambda>k. if k < m then s (Suc k) else foldseq f (\<lambda>k. s (Suc (k + m))) (na - m)) m = | |
| 520 | foldseq f (% k. s(Suc k)) na" | |
| 521 | by (rule subc[of m "% k. s(Suc k)", THEN sym], simp add: subb) | |
| 522 | from subb have sube: "m \<noteq> 0 \<Longrightarrow> ? mm. m = Suc mm & mm <= na" by arith | |
| 523 | show "f (s 0) (foldseq f (\<lambda>k. if k < m then s (Suc k) else foldseq f (\<lambda>k. s (Suc (k + m))) (na - m)) m) = | |
| 524 | foldseq f (\<lambda>k. if k < m then s k else foldseq f (\<lambda>k. s (k + m)) (Suc na - m)) m" | |
| 525 | apply (simp add: subd) | |
| 526 | apply (case_tac "m=0") | |
| 527 | apply (simp) | |
| 528 | apply (drule sube) | |
| 529 | apply (auto) | |
| 530 | apply (rule a) | |
| 531 | by (simp add: subc if_def) | |
| 532 | qed | |
| 533 | then show "?p \<Longrightarrow> ?concl" by simp | |
| 534 | qed | |
| 535 | ||
| 536 | lemma foldseq_zerotail: | |
| 537 | assumes | |
| 538 | fz: "f 0 0 = 0" | |
| 539 | and sz: "! i. n <= i \<longrightarrow> s i = 0" | |
| 540 | and nm: "n <= m" | |
| 541 | shows | |
| 542 | "foldseq f s n = foldseq f s m" | |
| 543 | proof - | |
| 544 | show "foldseq f s n = foldseq f s m" | |
| 545 | apply (simp add: foldseq_tail[OF nm, of f s]) | |
| 546 | apply (rule foldseq_significant_positions) | |
| 547 | apply (auto) | |
| 548 | apply (subst foldseq_zero) | |
| 549 | by (simp add: fz sz)+ | |
| 550 | qed | |
| 551 | ||
| 552 | lemma foldseq_zerotail2: | |
| 553 | assumes "! x. f x 0 = x" | |
| 554 | and "! i. n < i \<longrightarrow> s i = 0" | |
| 555 | and nm: "n <= m" | |
| 556 | shows | |
| 557 | "foldseq f s n = foldseq f s m" (is ?concl) | |
| 558 | proof - | |
| 559 | have "f 0 0 = 0" by (simp add: prems) | |
| 560 | have b:"!! m n. n <= m \<Longrightarrow> m \<noteq> n \<Longrightarrow> ? k. m-n = Suc k" by arith | |
| 561 | have c: "0 <= m" by simp | |
| 562 | have d: "!! k. k \<noteq> 0 \<Longrightarrow> ? l. k = Suc l" by arith | |
| 563 | show ?concl | |
| 564 | apply (subst foldseq_tail[OF nm]) | |
| 565 | apply (rule foldseq_significant_positions) | |
| 566 | apply (auto) | |
| 567 | apply (case_tac "m=n") | |
| 568 | apply (simp+) | |
| 569 | apply (drule b[OF nm]) | |
| 570 | apply (auto) | |
| 571 | apply (case_tac "k=0") | |
| 572 | apply (simp add: prems) | |
| 573 | apply (drule d) | |
| 574 | apply (auto) | |
| 575 | by (simp add: prems foldseq_zero) | |
| 576 | qed | |
| 577 | ||
| 578 | lemma foldseq_zerostart: | |
| 579 | "! x. f 0 (f 0 x) = f 0 x \<Longrightarrow> ! i. i <= n \<longrightarrow> s i = 0 \<Longrightarrow> foldseq f s (Suc n) = f 0 (s (Suc n))" | |
| 580 | proof - | |
| 581 | assume f00x: "! x. f 0 (f 0 x) = f 0 x" | |
| 582 | have "! s. (! i. i<=n \<longrightarrow> s i = 0) \<longrightarrow> foldseq f s (Suc n) = f 0 (s (Suc n))" | |
| 583 | apply (induct n) | |
| 584 | apply (simp) | |
| 585 | apply (rule allI, rule impI) | |
| 586 | proof - | |
| 587 | fix n | |
| 588 | fix s | |
| 589 | have a:"foldseq f s (Suc (Suc n)) = f (s 0) (foldseq f (% k. s(Suc k)) (Suc n))" by simp | |
| 590 | assume b: "! s. ((\<forall>i\<le>n. s i = 0) \<longrightarrow> foldseq f s (Suc n) = f 0 (s (Suc n)))" | |
| 591 | from b have c:"!! s. (\<forall>i\<le>n. s i = 0) \<Longrightarrow> foldseq f s (Suc n) = f 0 (s (Suc n))" by simp | |
| 592 | assume d: "! i. i <= Suc n \<longrightarrow> s i = 0" | |
| 593 | show "foldseq f s (Suc (Suc n)) = f 0 (s (Suc (Suc n)))" | |
| 594 | apply (subst a) | |
| 595 | apply (subst c) | |
| 596 | by (simp add: d f00x)+ | |
| 597 | qed | |
| 598 | then show "! i. i <= n \<longrightarrow> s i = 0 \<Longrightarrow> foldseq f s (Suc n) = f 0 (s (Suc n))" by simp | |
| 599 | qed | |
| 600 | ||
| 601 | lemma foldseq_zerostart2: | |
| 602 | "! x. f 0 x = x \<Longrightarrow> ! i. i < n \<longrightarrow> s i = 0 \<Longrightarrow> foldseq f s n = s n" | |
| 603 | proof - | |
| 604 | assume a:"! i. i<n \<longrightarrow> s i = 0" | |
| 605 | assume x:"! x. f 0 x = x" | |
| 606 | from x have f00x: "! x. f 0 (f 0 x) = f 0 x" by blast | |
| 607 | have b: "!! i l. i < Suc l = (i <= l)" by arith | |
| 608 | have d: "!! k. k \<noteq> 0 \<Longrightarrow> ? l. k = Suc l" by arith | |
| 609 | show "foldseq f s n = s n" | |
| 610 | apply (case_tac "n=0") | |
| 611 | apply (simp) | |
| 612 | apply (insert a) | |
| 613 | apply (drule d) | |
| 614 | apply (auto) | |
| 615 | apply (simp add: b) | |
| 616 | apply (insert f00x) | |
| 617 | apply (drule foldseq_zerostart) | |
| 618 | by (simp add: x)+ | |
| 619 | qed | |
| 620 | ||
| 621 | lemma foldseq_almostzero: | |
| 622 | assumes f0x:"! x. f 0 x = x" and fx0: "! x. f x 0 = x" and s0:"! i. i \<noteq> j \<longrightarrow> s i = 0" | |
| 623 | shows "foldseq f s n = (if (j <= n) then (s j) else 0)" (is ?concl) | |
| 624 | proof - | |
| 625 | from s0 have a: "! i. i < j \<longrightarrow> s i = 0" by simp | |
| 626 | from s0 have b: "! i. j < i \<longrightarrow> s i = 0" by simp | |
| 627 | show ?concl | |
| 628 | apply auto | |
| 629 | apply (subst foldseq_zerotail2[of f, OF fx0, of j, OF b, of n, THEN sym]) | |
| 630 | apply simp | |
| 631 | apply (subst foldseq_zerostart2) | |
| 632 | apply (simp add: f0x a)+ | |
| 633 | apply (subst foldseq_zero) | |
| 634 | by (simp add: s0 f0x)+ | |
| 635 | qed | |
| 636 | ||
| 637 | lemma foldseq_distr_unary: | |
| 638 | assumes "!! a b. g (f a b) = f (g a) (g b)" | |
| 639 | shows "g(foldseq f s n) = foldseq f (% x. g(s x)) n" (is ?concl) | |
| 640 | proof - | |
| 641 | have "! s. g(foldseq f s n) = foldseq f (% x. g(s x)) n" | |
| 642 | apply (induct_tac n) | |
| 643 | apply (simp) | |
| 644 | apply (simp) | |
| 645 | apply (auto) | |
| 646 | apply (drule_tac x="% k. s (Suc k)" in spec) | |
| 647 | by (simp add: prems) | |
| 648 | then show ?concl by simp | |
| 649 | qed | |
| 650 | ||
| 651 | constdefs | |
| 652 |   mult_matrix_n :: "nat \<Rightarrow> (('a::zero) \<Rightarrow> ('b::zero) \<Rightarrow> ('c::zero)) \<Rightarrow> ('c \<Rightarrow> 'c \<Rightarrow> 'c) \<Rightarrow> 'a matrix \<Rightarrow> 'b matrix \<Rightarrow> 'c matrix"
 | |
| 653 | "mult_matrix_n n fmul fadd A B == Abs_matrix(% j i. foldseq fadd (% k. fmul (Rep_matrix A j k) (Rep_matrix B k i)) n)" | |
| 654 |   mult_matrix :: "(('a::zero) \<Rightarrow> ('b::zero) \<Rightarrow> ('c::zero)) \<Rightarrow> ('c \<Rightarrow> 'c \<Rightarrow> 'c) \<Rightarrow> 'a matrix \<Rightarrow> 'b matrix \<Rightarrow> 'c matrix"
 | |
| 655 | "mult_matrix fmul fadd A B == mult_matrix_n (max (ncols A) (nrows B)) fmul fadd A B" | |
| 656 | ||
| 657 | lemma mult_matrix_n: | |
| 658 | assumes prems: "ncols A \<le> n" (is ?An) "nrows B \<le> n" (is ?Bn) "fadd 0 0 = 0" "fmul 0 0 = 0" | |
| 659 | shows c:"mult_matrix fmul fadd A B = mult_matrix_n n fmul fadd A B" (is ?concl) | |
| 660 | proof - | |
| 661 | show ?concl using prems | |
| 662 | apply (simp add: mult_matrix_def mult_matrix_n_def) | |
| 663 | apply (rule comb[of "Abs_matrix" "Abs_matrix"], simp, (rule ext)+) | |
| 664 | by (rule foldseq_zerotail, simp_all add: nrows_le ncols_le prems) | |
| 665 | qed | |
| 666 | ||
| 667 | lemma mult_matrix_nm: | |
| 668 | assumes prems: "ncols A <= n" "nrows B <= n" "ncols A <= m" "nrows B <= m" "fadd 0 0 = 0" "fmul 0 0 = 0" | |
| 669 | shows "mult_matrix_n n fmul fadd A B = mult_matrix_n m fmul fadd A B" | |
| 670 | proof - | |
| 671 | from prems have "mult_matrix_n n fmul fadd A B = mult_matrix fmul fadd A B" by (simp add: mult_matrix_n) | |
| 672 | also from prems have "\<dots> = mult_matrix_n m fmul fadd A B" by (simp add: mult_matrix_n[THEN sym]) | |
| 673 | finally show "mult_matrix_n n fmul fadd A B = mult_matrix_n m fmul fadd A B" by simp | |
| 674 | qed | |
| 675 | ||
| 676 | constdefs | |
| 677 |   r_distributive :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('b \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> bool"
 | |
| 678 | "r_distributive fmul fadd == ! a u v. fmul a (fadd u v) = fadd (fmul a u) (fmul a v)" | |
| 679 |   l_distributive :: "('a \<Rightarrow> 'b \<Rightarrow> 'a) \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> bool"
 | |
| 680 | "l_distributive fmul fadd == ! a u v. fmul (fadd u v) a = fadd (fmul u a) (fmul v a)" | |
| 681 |   distributive :: "('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> bool"
 | |
| 682 | "distributive fmul fadd == l_distributive fmul fadd & r_distributive fmul fadd" | |
| 683 | ||
| 684 | lemma max1: "!! a x y. (a::nat) <= x \<Longrightarrow> a <= max x y" by (arith) | |
| 685 | lemma max2: "!! b x y. (b::nat) <= y \<Longrightarrow> b <= max x y" by (arith) | |
| 686 | ||
| 687 | lemma r_distributive_matrix: | |
| 688 | assumes prems: | |
| 689 | "r_distributive fmul fadd" | |
| 690 | "associative fadd" | |
| 691 | "commutative fadd" | |
| 692 | "fadd 0 0 = 0" | |
| 693 | "! a. fmul a 0 = 0" | |
| 694 | "! a. fmul 0 a = 0" | |
| 695 | shows "r_distributive (mult_matrix fmul fadd) (combine_matrix fadd)" (is ?concl) | |
| 696 | proof - | |
| 697 | from prems show ?concl | |
| 698 | apply (simp add: r_distributive_def mult_matrix_def, auto) | |
| 699 | proof - | |
| 700 | fix a::"'a matrix" | |
| 701 | fix u::"'b matrix" | |
| 702 | fix v::"'b matrix" | |
| 703 | let ?mx = "max (ncols a) (max (nrows u) (nrows v))" | |
| 704 | from prems show "mult_matrix_n (max (ncols a) (nrows (combine_matrix fadd u v))) fmul fadd a (combine_matrix fadd u v) = | |
| 705 | combine_matrix fadd (mult_matrix_n (max (ncols a) (nrows u)) fmul fadd a u) (mult_matrix_n (max (ncols a) (nrows v)) fmul fadd a v)" | |
| 706 | apply (subst mult_matrix_nm[of _ _ _ ?mx fadd fmul]) | |
| 707 | apply (simp add: max1 max2 combine_nrows combine_ncols)+ | |
| 708 | apply (subst mult_matrix_nm[of _ _ v ?mx fadd fmul]) | |
| 709 | apply (simp add: max1 max2 combine_nrows combine_ncols)+ | |
| 710 | apply (subst mult_matrix_nm[of _ _ u ?mx fadd fmul]) | |
| 711 | apply (simp add: max1 max2 combine_nrows combine_ncols)+ | |
| 712 | apply (simp add: mult_matrix_n_def r_distributive_def foldseq_distr[of fadd]) | |
| 713 | apply (simp add: combine_matrix_def combine_infmatrix_def) | |
| 714 | apply (rule comb[of "Abs_matrix" "Abs_matrix"], simp, (rule ext)+) | |
| 715 | apply (simplesubst RepAbs_matrix) | |
| 716 | apply (simp, auto) | |
| 717 | apply (rule exI[of _ "nrows a"], simp add: nrows_le foldseq_zero) | |
| 718 | apply (rule exI[of _ "ncols v"], simp add: ncols_le foldseq_zero) | |
| 719 | apply (subst RepAbs_matrix) | |
| 720 | apply (simp, auto) | |
| 721 | apply (rule exI[of _ "nrows a"], simp add: nrows_le foldseq_zero) | |
| 722 | apply (rule exI[of _ "ncols u"], simp add: ncols_le foldseq_zero) | |
| 723 | done | |
| 724 | qed | |
| 725 | qed | |
| 726 | ||
| 727 | lemma l_distributive_matrix: | |
| 728 | assumes prems: | |
| 729 | "l_distributive fmul fadd" | |
| 730 | "associative fadd" | |
| 731 | "commutative fadd" | |
| 732 | "fadd 0 0 = 0" | |
| 733 | "! a. fmul a 0 = 0" | |
| 734 | "! a. fmul 0 a = 0" | |
| 735 | shows "l_distributive (mult_matrix fmul fadd) (combine_matrix fadd)" (is ?concl) | |
| 736 | proof - | |
| 737 | from prems show ?concl | |
| 738 | apply (simp add: l_distributive_def mult_matrix_def, auto) | |
| 739 | proof - | |
| 740 | fix a::"'b matrix" | |
| 741 | fix u::"'a matrix" | |
| 742 | fix v::"'a matrix" | |
| 743 | let ?mx = "max (nrows a) (max (ncols u) (ncols v))" | |
| 744 | from prems show "mult_matrix_n (max (ncols (combine_matrix fadd u v)) (nrows a)) fmul fadd (combine_matrix fadd u v) a = | |
| 745 | combine_matrix fadd (mult_matrix_n (max (ncols u) (nrows a)) fmul fadd u a) (mult_matrix_n (max (ncols v) (nrows a)) fmul fadd v a)" | |
| 746 | apply (subst mult_matrix_nm[of v _ _ ?mx fadd fmul]) | |
| 747 | apply (simp add: max1 max2 combine_nrows combine_ncols)+ | |
| 748 | apply (subst mult_matrix_nm[of u _ _ ?mx fadd fmul]) | |
| 749 | apply (simp add: max1 max2 combine_nrows combine_ncols)+ | |
| 750 | apply (subst mult_matrix_nm[of _ _ _ ?mx fadd fmul]) | |
| 751 | apply (simp add: max1 max2 combine_nrows combine_ncols)+ | |
| 752 | apply (simp add: mult_matrix_n_def l_distributive_def foldseq_distr[of fadd]) | |
| 753 | apply (simp add: combine_matrix_def combine_infmatrix_def) | |
| 754 | apply (rule comb[of "Abs_matrix" "Abs_matrix"], simp, (rule ext)+) | |
| 755 | apply (simplesubst RepAbs_matrix) | |
| 756 | apply (simp, auto) | |
| 757 | apply (rule exI[of _ "nrows v"], simp add: nrows_le foldseq_zero) | |
| 758 | apply (rule exI[of _ "ncols a"], simp add: ncols_le foldseq_zero) | |
| 759 | apply (subst RepAbs_matrix) | |
| 760 | apply (simp, auto) | |
| 761 | apply (rule exI[of _ "nrows u"], simp add: nrows_le foldseq_zero) | |
| 762 | apply (rule exI[of _ "ncols a"], simp add: ncols_le foldseq_zero) | |
| 763 | done | |
| 764 | qed | |
| 765 | qed | |
| 766 | ||
| 767 | instantiation matrix :: (zero) zero | |
| 768 | begin | |
| 769 | ||
| 28562 | 770 | definition zero_matrix_def [code del]: "0 = Abs_matrix (\<lambda>j i. 0)" | 
| 27484 | 771 | |
| 772 | instance .. | |
| 773 | ||
| 774 | end | |
| 775 | ||
| 776 | lemma Rep_zero_matrix_def[simp]: "Rep_matrix 0 j i = 0" | |
| 777 | apply (simp add: zero_matrix_def) | |
| 778 | apply (subst RepAbs_matrix) | |
| 779 | by (auto) | |
| 780 | ||
| 781 | lemma zero_matrix_def_nrows[simp]: "nrows 0 = 0" | |
| 782 | proof - | |
| 783 | have a:"!! (x::nat). x <= 0 \<Longrightarrow> x = 0" by (arith) | |
| 784 | show "nrows 0 = 0" by (rule a, subst nrows_le, simp) | |
| 785 | qed | |
| 786 | ||
| 787 | lemma zero_matrix_def_ncols[simp]: "ncols 0 = 0" | |
| 788 | proof - | |
| 789 | have a:"!! (x::nat). x <= 0 \<Longrightarrow> x = 0" by (arith) | |
| 790 | show "ncols 0 = 0" by (rule a, subst ncols_le, simp) | |
| 791 | qed | |
| 792 | ||
| 793 | lemma combine_matrix_zero_l_neutral: "zero_l_neutral f \<Longrightarrow> zero_l_neutral (combine_matrix f)" | |
| 794 | by (simp add: zero_l_neutral_def combine_matrix_def combine_infmatrix_def) | |
| 795 | ||
| 796 | lemma combine_matrix_zero_r_neutral: "zero_r_neutral f \<Longrightarrow> zero_r_neutral (combine_matrix f)" | |
| 797 | by (simp add: zero_r_neutral_def combine_matrix_def combine_infmatrix_def) | |
| 798 | ||
| 799 | lemma mult_matrix_zero_closed: "\<lbrakk>fadd 0 0 = 0; zero_closed fmul\<rbrakk> \<Longrightarrow> zero_closed (mult_matrix fmul fadd)" | |
| 800 | apply (simp add: zero_closed_def mult_matrix_def mult_matrix_n_def) | |
| 801 | apply (auto) | |
| 802 | by (subst foldseq_zero, (simp add: zero_matrix_def)+)+ | |
| 803 | ||
| 804 | lemma mult_matrix_n_zero_right[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul a 0 = 0\<rbrakk> \<Longrightarrow> mult_matrix_n n fmul fadd A 0 = 0" | |
| 805 | apply (simp add: mult_matrix_n_def) | |
| 806 | apply (subst foldseq_zero) | |
| 807 | by (simp_all add: zero_matrix_def) | |
| 808 | ||
| 809 | lemma mult_matrix_n_zero_left[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul 0 a = 0\<rbrakk> \<Longrightarrow> mult_matrix_n n fmul fadd 0 A = 0" | |
| 810 | apply (simp add: mult_matrix_n_def) | |
| 811 | apply (subst foldseq_zero) | |
| 812 | by (simp_all add: zero_matrix_def) | |
| 813 | ||
| 814 | lemma mult_matrix_zero_left[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul 0 a = 0\<rbrakk> \<Longrightarrow> mult_matrix fmul fadd 0 A = 0" | |
| 815 | by (simp add: mult_matrix_def) | |
| 816 | ||
| 817 | lemma mult_matrix_zero_right[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul a 0 = 0\<rbrakk> \<Longrightarrow> mult_matrix fmul fadd A 0 = 0" | |
| 818 | by (simp add: mult_matrix_def) | |
| 819 | ||
| 820 | lemma apply_matrix_zero[simp]: "f 0 = 0 \<Longrightarrow> apply_matrix f 0 = 0" | |
| 821 | apply (simp add: apply_matrix_def apply_infmatrix_def) | |
| 822 | by (simp add: zero_matrix_def) | |
| 823 | ||
| 824 | lemma combine_matrix_zero: "f 0 0 = 0 \<Longrightarrow> combine_matrix f 0 0 = 0" | |
| 825 | apply (simp add: combine_matrix_def combine_infmatrix_def) | |
| 826 | by (simp add: zero_matrix_def) | |
| 827 | ||
| 828 | lemma transpose_matrix_zero[simp]: "transpose_matrix 0 = 0" | |
| 829 | apply (simp add: transpose_matrix_def transpose_infmatrix_def zero_matrix_def RepAbs_matrix) | |
| 830 | apply (subst Rep_matrix_inject[symmetric], (rule ext)+) | |
| 831 | apply (simp add: RepAbs_matrix) | |
| 832 | done | |
| 833 | ||
| 834 | lemma apply_zero_matrix_def[simp]: "apply_matrix (% x. 0) A = 0" | |
| 835 | apply (simp add: apply_matrix_def apply_infmatrix_def) | |
| 836 | by (simp add: zero_matrix_def) | |
| 837 | ||
| 838 | constdefs | |
| 839 |   singleton_matrix :: "nat \<Rightarrow> nat \<Rightarrow> ('a::zero) \<Rightarrow> 'a matrix"
 | |
| 840 | "singleton_matrix j i a == Abs_matrix(% m n. if j = m & i = n then a else 0)" | |
| 841 |   move_matrix :: "('a::zero) matrix \<Rightarrow> int \<Rightarrow> int \<Rightarrow> 'a matrix"
 | |
| 842 | "move_matrix A y x == Abs_matrix(% j i. if (neg ((int j)-y)) | (neg ((int i)-x)) then 0 else Rep_matrix A (nat ((int j)-y)) (nat ((int i)-x)))" | |
| 843 |   take_rows :: "('a::zero) matrix \<Rightarrow> nat \<Rightarrow> 'a matrix"
 | |
| 844 | "take_rows A r == Abs_matrix(% j i. if (j < r) then (Rep_matrix A j i) else 0)" | |
| 845 |   take_columns :: "('a::zero) matrix \<Rightarrow> nat \<Rightarrow> 'a matrix"
 | |
| 846 | "take_columns A c == Abs_matrix(% j i. if (i < c) then (Rep_matrix A j i) else 0)" | |
| 847 | ||
| 848 | constdefs | |
| 849 |   column_of_matrix :: "('a::zero) matrix \<Rightarrow> nat \<Rightarrow> 'a matrix"
 | |
| 850 | "column_of_matrix A n == take_columns (move_matrix A 0 (- int n)) 1" | |
| 851 |   row_of_matrix :: "('a::zero) matrix \<Rightarrow> nat \<Rightarrow> 'a matrix"
 | |
| 852 | "row_of_matrix A m == take_rows (move_matrix A (- int m) 0) 1" | |
| 853 | ||
| 854 | lemma Rep_singleton_matrix[simp]: "Rep_matrix (singleton_matrix j i e) m n = (if j = m & i = n then e else 0)" | |
| 855 | apply (simp add: singleton_matrix_def) | |
| 856 | apply (auto) | |
| 857 | apply (subst RepAbs_matrix) | |
| 858 | apply (rule exI[of _ "Suc m"], simp) | |
| 859 | apply (rule exI[of _ "Suc n"], simp+) | |
| 860 | by (subst RepAbs_matrix, rule exI[of _ "Suc j"], simp, rule exI[of _ "Suc i"], simp+)+ | |
| 861 | ||
| 862 | lemma apply_singleton_matrix[simp]: "f 0 = 0 \<Longrightarrow> apply_matrix f (singleton_matrix j i x) = (singleton_matrix j i (f x))" | |
| 863 | apply (subst Rep_matrix_inject[symmetric]) | |
| 864 | apply (rule ext)+ | |
| 865 | apply (simp) | |
| 866 | done | |
| 867 | ||
| 868 | lemma singleton_matrix_zero[simp]: "singleton_matrix j i 0 = 0" | |
| 869 | by (simp add: singleton_matrix_def zero_matrix_def) | |
| 870 | ||
| 871 | lemma nrows_singleton[simp]: "nrows(singleton_matrix j i e) = (if e = 0 then 0 else Suc j)" | |
| 872 | proof- | |
| 873 | have th: "\<not> (\<forall>m. m \<le> j)" "\<exists>n. \<not> n \<le> i" by arith+ | |
| 874 | from th show ?thesis | |
| 875 | apply (auto) | |
| 33657 | 876 | apply (rule le_antisym) | 
| 27484 | 877 | apply (subst nrows_le) | 
| 878 | apply (simp add: singleton_matrix_def, auto) | |
| 879 | apply (subst RepAbs_matrix) | |
| 880 | apply auto | |
| 881 | apply (simp add: Suc_le_eq) | |
| 882 | apply (rule not_leE) | |
| 883 | apply (subst nrows_le) | |
| 884 | by simp | |
| 885 | qed | |
| 886 | ||
| 887 | lemma ncols_singleton[simp]: "ncols(singleton_matrix j i e) = (if e = 0 then 0 else Suc i)" | |
| 888 | proof- | |
| 889 | have th: "\<not> (\<forall>m. m \<le> j)" "\<exists>n. \<not> n \<le> i" by arith+ | |
| 890 | from th show ?thesis | |
| 891 | apply (auto) | |
| 33657 | 892 | apply (rule le_antisym) | 
| 27484 | 893 | apply (subst ncols_le) | 
| 894 | apply (simp add: singleton_matrix_def, auto) | |
| 895 | apply (subst RepAbs_matrix) | |
| 896 | apply auto | |
| 897 | apply (simp add: Suc_le_eq) | |
| 898 | apply (rule not_leE) | |
| 899 | apply (subst ncols_le) | |
| 900 | by simp | |
| 901 | qed | |
| 902 | ||
| 903 | lemma combine_singleton: "f 0 0 = 0 \<Longrightarrow> combine_matrix f (singleton_matrix j i a) (singleton_matrix j i b) = singleton_matrix j i (f a b)" | |
| 904 | apply (simp add: singleton_matrix_def combine_matrix_def combine_infmatrix_def) | |
| 905 | apply (subst RepAbs_matrix) | |
| 906 | apply (rule exI[of _ "Suc j"], simp) | |
| 907 | apply (rule exI[of _ "Suc i"], simp) | |
| 908 | apply (rule comb[of "Abs_matrix" "Abs_matrix"], simp, (rule ext)+) | |
| 909 | apply (subst RepAbs_matrix) | |
| 910 | apply (rule exI[of _ "Suc j"], simp) | |
| 911 | apply (rule exI[of _ "Suc i"], simp) | |
| 912 | by simp | |
| 913 | ||
| 914 | lemma transpose_singleton[simp]: "transpose_matrix (singleton_matrix j i a) = singleton_matrix i j a" | |
| 915 | apply (subst Rep_matrix_inject[symmetric], (rule ext)+) | |
| 916 | apply (simp) | |
| 917 | done | |
| 918 | ||
| 919 | lemma Rep_move_matrix[simp]: | |
| 920 | "Rep_matrix (move_matrix A y x) j i = | |
| 921 | (if (neg ((int j)-y)) | (neg ((int i)-x)) then 0 else Rep_matrix A (nat((int j)-y)) (nat((int i)-x)))" | |
| 922 | apply (simp add: move_matrix_def) | |
| 923 | apply (auto) | |
| 924 | by (subst RepAbs_matrix, | |
| 925 | rule exI[of _ "(nrows A)+(nat (abs y))"], auto, rule nrows, arith, | |
| 926 | rule exI[of _ "(ncols A)+(nat (abs x))"], auto, rule ncols, arith)+ | |
| 927 | ||
| 928 | lemma move_matrix_0_0[simp]: "move_matrix A 0 0 = A" | |
| 929 | by (simp add: move_matrix_def) | |
| 930 | ||
| 931 | lemma move_matrix_ortho: "move_matrix A j i = move_matrix (move_matrix A j 0) 0 i" | |
| 932 | apply (subst Rep_matrix_inject[symmetric]) | |
| 933 | apply (rule ext)+ | |
| 934 | apply (simp) | |
| 935 | done | |
| 936 | ||
| 937 | lemma transpose_move_matrix[simp]: | |
| 938 | "transpose_matrix (move_matrix A x y) = move_matrix (transpose_matrix A) y x" | |
| 939 | apply (subst Rep_matrix_inject[symmetric], (rule ext)+) | |
| 940 | apply (simp) | |
| 941 | done | |
| 942 | ||
| 943 | lemma move_matrix_singleton[simp]: "move_matrix (singleton_matrix u v x) j i = | |
| 944 | (if (j + int u < 0) | (i + int v < 0) then 0 else (singleton_matrix (nat (j + int u)) (nat (i + int v)) x))" | |
| 945 | apply (subst Rep_matrix_inject[symmetric]) | |
| 946 | apply (rule ext)+ | |
| 947 | apply (case_tac "j + int u < 0") | |
| 948 | apply (simp, arith) | |
| 949 | apply (case_tac "i + int v < 0") | |
| 950 | apply (simp add: neg_def, arith) | |
| 951 | apply (simp add: neg_def) | |
| 952 | apply arith | |
| 953 | done | |
| 954 | ||
| 955 | lemma Rep_take_columns[simp]: | |
| 956 | "Rep_matrix (take_columns A c) j i = | |
| 957 | (if i < c then (Rep_matrix A j i) else 0)" | |
| 958 | apply (simp add: take_columns_def) | |
| 959 | apply (simplesubst RepAbs_matrix) | |
| 960 | apply (rule exI[of _ "nrows A"], auto, simp add: nrows_le) | |
| 961 | apply (rule exI[of _ "ncols A"], auto, simp add: ncols_le) | |
| 962 | done | |
| 963 | ||
| 964 | lemma Rep_take_rows[simp]: | |
| 965 | "Rep_matrix (take_rows A r) j i = | |
| 966 | (if j < r then (Rep_matrix A j i) else 0)" | |
| 967 | apply (simp add: take_rows_def) | |
| 968 | apply (simplesubst RepAbs_matrix) | |
| 969 | apply (rule exI[of _ "nrows A"], auto, simp add: nrows_le) | |
| 970 | apply (rule exI[of _ "ncols A"], auto, simp add: ncols_le) | |
| 971 | done | |
| 972 | ||
| 973 | lemma Rep_column_of_matrix[simp]: | |
| 974 | "Rep_matrix (column_of_matrix A c) j i = (if i = 0 then (Rep_matrix A j c) else 0)" | |
| 975 | by (simp add: column_of_matrix_def) | |
| 976 | ||
| 977 | lemma Rep_row_of_matrix[simp]: | |
| 978 | "Rep_matrix (row_of_matrix A r) j i = (if j = 0 then (Rep_matrix A r i) else 0)" | |
| 979 | by (simp add: row_of_matrix_def) | |
| 980 | ||
| 981 | lemma column_of_matrix: "ncols A <= n \<Longrightarrow> column_of_matrix A n = 0" | |
| 982 | apply (subst Rep_matrix_inject[THEN sym]) | |
| 983 | apply (rule ext)+ | |
| 984 | by (simp add: ncols) | |
| 985 | ||
| 986 | lemma row_of_matrix: "nrows A <= n \<Longrightarrow> row_of_matrix A n = 0" | |
| 987 | apply (subst Rep_matrix_inject[THEN sym]) | |
| 988 | apply (rule ext)+ | |
| 989 | by (simp add: nrows) | |
| 990 | ||
| 991 | lemma mult_matrix_singleton_right[simp]: | |
| 992 | assumes prems: | |
| 993 | "! x. fmul x 0 = 0" | |
| 994 | "! x. fmul 0 x = 0" | |
| 995 | "! x. fadd 0 x = x" | |
| 996 | "! x. fadd x 0 = x" | |
| 997 | shows "(mult_matrix fmul fadd A (singleton_matrix j i e)) = apply_matrix (% x. fmul x e) (move_matrix (column_of_matrix A j) 0 (int i))" | |
| 998 | apply (simp add: mult_matrix_def) | |
| 999 | apply (subst mult_matrix_nm[of _ _ _ "max (ncols A) (Suc j)"]) | |
| 1000 | apply (auto) | |
| 1001 | apply (simp add: prems)+ | |
| 1002 | apply (simp add: mult_matrix_n_def apply_matrix_def apply_infmatrix_def) | |
| 1003 | apply (rule comb[of "Abs_matrix" "Abs_matrix"], auto, (rule ext)+) | |
| 1004 | apply (subst foldseq_almostzero[of _ j]) | |
| 1005 | apply (simp add: prems)+ | |
| 1006 | apply (auto) | |
| 33657 | 1007 | apply (metis comm_monoid_add.mult_1 le_antisym le_diff_eq not_neg_nat zero_le_imp_of_nat zle_int) | 
| 29700 | 1008 | done | 
| 27484 | 1009 | |
| 1010 | lemma mult_matrix_ext: | |
| 1011 | assumes | |
| 1012 | eprem: | |
| 1013 | "? e. (! a b. a \<noteq> b \<longrightarrow> fmul a e \<noteq> fmul b e)" | |
| 1014 | and fprems: | |
| 1015 | "! a. fmul 0 a = 0" | |
| 1016 | "! a. fmul a 0 = 0" | |
| 1017 | "! a. fadd a 0 = a" | |
| 1018 | "! a. fadd 0 a = a" | |
| 1019 | and contraprems: | |
| 1020 | "mult_matrix fmul fadd A = mult_matrix fmul fadd B" | |
| 1021 | shows | |
| 1022 | "A = B" | |
| 1023 | proof(rule contrapos_np[of "False"], simp) | |
| 1024 | assume a: "A \<noteq> B" | |
| 1025 | have b: "!! f g. (! x y. f x y = g x y) \<Longrightarrow> f = g" by ((rule ext)+, auto) | |
| 1026 | have "? j i. (Rep_matrix A j i) \<noteq> (Rep_matrix B j i)" | |
| 1027 | apply (rule contrapos_np[of "False"], simp+) | |
| 1028 | apply (insert b[of "Rep_matrix A" "Rep_matrix B"], simp) | |
| 1029 | by (simp add: Rep_matrix_inject a) | |
| 1030 | then obtain J I where c:"(Rep_matrix A J I) \<noteq> (Rep_matrix B J I)" by blast | |
| 1031 | from eprem obtain e where eprops:"(! a b. a \<noteq> b \<longrightarrow> fmul a e \<noteq> fmul b e)" by blast | |
| 1032 | let ?S = "singleton_matrix I 0 e" | |
| 1033 | let ?comp = "mult_matrix fmul fadd" | |
| 1034 | have d: "!!x f g. f = g \<Longrightarrow> f x = g x" by blast | |
| 1035 | have e: "(% x. fmul x e) 0 = 0" by (simp add: prems) | |
| 1036 | have "~(?comp A ?S = ?comp B ?S)" | |
| 1037 | apply (rule notI) | |
| 1038 | apply (simp add: fprems eprops) | |
| 1039 | apply (simp add: Rep_matrix_inject[THEN sym]) | |
| 1040 | apply (drule d[of _ _ "J"], drule d[of _ _ "0"]) | |
| 1041 | by (simp add: e c eprops) | |
| 1042 | with contraprems show "False" by simp | |
| 1043 | qed | |
| 1044 | ||
| 1045 | constdefs | |
| 1046 |   foldmatrix :: "('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> ('a infmatrix) \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> 'a"
 | |
| 1047 | "foldmatrix f g A m n == foldseq_transposed g (% j. foldseq f (A j) n) m" | |
| 1048 |   foldmatrix_transposed :: "('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> ('a infmatrix) \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> 'a"
 | |
| 1049 | "foldmatrix_transposed f g A m n == foldseq g (% j. foldseq_transposed f (A j) n) m" | |
| 1050 | ||
| 1051 | lemma foldmatrix_transpose: | |
| 1052 | assumes | |
| 1053 | "! a b c d. g(f a b) (f c d) = f (g a c) (g b d)" | |
| 1054 | shows | |
| 1055 | "foldmatrix f g A m n = foldmatrix_transposed g f (transpose_infmatrix A) n m" (is ?concl) | |
| 1056 | proof - | |
| 1057 | have forall:"!! P x. (! x. P x) \<Longrightarrow> P x" by auto | |
| 1058 | have tworows:"! A. foldmatrix f g A 1 n = foldmatrix_transposed g f (transpose_infmatrix A) n 1" | |
| 1059 | apply (induct n) | |
| 1060 | apply (simp add: foldmatrix_def foldmatrix_transposed_def prems)+ | |
| 1061 | apply (auto) | |
| 1062 | by (drule_tac x="(% j i. A j (Suc i))" in forall, simp) | |
| 1063 | show "foldmatrix f g A m n = foldmatrix_transposed g f (transpose_infmatrix A) n m" | |
| 1064 | apply (simp add: foldmatrix_def foldmatrix_transposed_def) | |
| 1065 | apply (induct m, simp) | |
| 1066 | apply (simp) | |
| 1067 | apply (insert tworows) | |
| 1068 | apply (drule_tac x="% j i. (if j = 0 then (foldseq_transposed g (\<lambda>u. A u i) m) else (A (Suc m) i))" in spec) | |
| 1069 | by (simp add: foldmatrix_def foldmatrix_transposed_def) | |
| 1070 | qed | |
| 1071 | ||
| 1072 | lemma foldseq_foldseq: | |
| 1073 | assumes | |
| 1074 | "associative f" | |
| 1075 | "associative g" | |
| 1076 | "! a b c d. g(f a b) (f c d) = f (g a c) (g b d)" | |
| 1077 | shows | |
| 1078 | "foldseq g (% j. foldseq f (A j) n) m = foldseq f (% j. foldseq g ((transpose_infmatrix A) j) m) n" | |
| 1079 | apply (insert foldmatrix_transpose[of g f A m n]) | |
| 1080 | by (simp add: foldmatrix_def foldmatrix_transposed_def foldseq_assoc[THEN sym] prems) | |
| 1081 | ||
| 1082 | lemma mult_n_nrows: | |
| 1083 | assumes | |
| 1084 | "! a. fmul 0 a = 0" | |
| 1085 | "! a. fmul a 0 = 0" | |
| 1086 | "fadd 0 0 = 0" | |
| 1087 | shows "nrows (mult_matrix_n n fmul fadd A B) \<le> nrows A" | |
| 1088 | apply (subst nrows_le) | |
| 1089 | apply (simp add: mult_matrix_n_def) | |
| 1090 | apply (subst RepAbs_matrix) | |
| 1091 | apply (rule_tac x="nrows A" in exI) | |
| 1092 | apply (simp add: nrows prems foldseq_zero) | |
| 1093 | apply (rule_tac x="ncols B" in exI) | |
| 1094 | apply (simp add: ncols prems foldseq_zero) | |
| 1095 | by (simp add: nrows prems foldseq_zero) | |
| 1096 | ||
| 1097 | lemma mult_n_ncols: | |
| 1098 | assumes | |
| 1099 | "! a. fmul 0 a = 0" | |
| 1100 | "! a. fmul a 0 = 0" | |
| 1101 | "fadd 0 0 = 0" | |
| 1102 | shows "ncols (mult_matrix_n n fmul fadd A B) \<le> ncols B" | |
| 1103 | apply (subst ncols_le) | |
| 1104 | apply (simp add: mult_matrix_n_def) | |
| 1105 | apply (subst RepAbs_matrix) | |
| 1106 | apply (rule_tac x="nrows A" in exI) | |
| 1107 | apply (simp add: nrows prems foldseq_zero) | |
| 1108 | apply (rule_tac x="ncols B" in exI) | |
| 1109 | apply (simp add: ncols prems foldseq_zero) | |
| 1110 | by (simp add: ncols prems foldseq_zero) | |
| 1111 | ||
| 1112 | lemma mult_nrows: | |
| 1113 | assumes | |
| 1114 | "! a. fmul 0 a = 0" | |
| 1115 | "! a. fmul a 0 = 0" | |
| 1116 | "fadd 0 0 = 0" | |
| 1117 | shows "nrows (mult_matrix fmul fadd A B) \<le> nrows A" | |
| 1118 | by (simp add: mult_matrix_def mult_n_nrows prems) | |
| 1119 | ||
| 1120 | lemma mult_ncols: | |
| 1121 | assumes | |
| 1122 | "! a. fmul 0 a = 0" | |
| 1123 | "! a. fmul a 0 = 0" | |
| 1124 | "fadd 0 0 = 0" | |
| 1125 | shows "ncols (mult_matrix fmul fadd A B) \<le> ncols B" | |
| 1126 | by (simp add: mult_matrix_def mult_n_ncols prems) | |
| 1127 | ||
| 1128 | lemma nrows_move_matrix_le: "nrows (move_matrix A j i) <= nat((int (nrows A)) + j)" | |
| 1129 | apply (auto simp add: nrows_le) | |
| 1130 | apply (rule nrows) | |
| 1131 | apply (arith) | |
| 1132 | done | |
| 1133 | ||
| 1134 | lemma ncols_move_matrix_le: "ncols (move_matrix A j i) <= nat((int (ncols A)) + i)" | |
| 1135 | apply (auto simp add: ncols_le) | |
| 1136 | apply (rule ncols) | |
| 1137 | apply (arith) | |
| 1138 | done | |
| 1139 | ||
| 1140 | lemma mult_matrix_assoc: | |
| 1141 | assumes prems: | |
| 1142 | "! a. fmul1 0 a = 0" | |
| 1143 | "! a. fmul1 a 0 = 0" | |
| 1144 | "! a. fmul2 0 a = 0" | |
| 1145 | "! a. fmul2 a 0 = 0" | |
| 1146 | "fadd1 0 0 = 0" | |
| 1147 | "fadd2 0 0 = 0" | |
| 1148 | "! a b c d. fadd2 (fadd1 a b) (fadd1 c d) = fadd1 (fadd2 a c) (fadd2 b d)" | |
| 1149 | "associative fadd1" | |
| 1150 | "associative fadd2" | |
| 1151 | "! a b c. fmul2 (fmul1 a b) c = fmul1 a (fmul2 b c)" | |
| 1152 | "! a b c. fmul2 (fadd1 a b) c = fadd1 (fmul2 a c) (fmul2 b c)" | |
| 1153 | "! a b c. fmul1 c (fadd2 a b) = fadd2 (fmul1 c a) (fmul1 c b)" | |
| 1154 | shows "mult_matrix fmul2 fadd2 (mult_matrix fmul1 fadd1 A B) C = mult_matrix fmul1 fadd1 A (mult_matrix fmul2 fadd2 B C)" (is ?concl) | |
| 1155 | proof - | |
| 1156 | have comb_left: "!! A B x y. A = B \<Longrightarrow> (Rep_matrix (Abs_matrix A)) x y = (Rep_matrix(Abs_matrix B)) x y" by blast | |
| 1157 | have fmul2fadd1fold: "!! x s n. fmul2 (foldseq fadd1 s n) x = foldseq fadd1 (% k. fmul2 (s k) x) n" | |
| 1158 | by (rule_tac g1 = "% y. fmul2 y x" in ssubst [OF foldseq_distr_unary], simp_all!) | |
| 1159 | have fmul1fadd2fold: "!! x s n. fmul1 x (foldseq fadd2 s n) = foldseq fadd2 (% k. fmul1 x (s k)) n" | |
| 1160 | by (rule_tac g1 = "% y. fmul1 x y" in ssubst [OF foldseq_distr_unary], simp_all!) | |
| 1161 | let ?N = "max (ncols A) (max (ncols B) (max (nrows B) (nrows C)))" | |
| 1162 | show ?concl | |
| 1163 | apply (simp add: Rep_matrix_inject[THEN sym]) | |
| 1164 | apply (rule ext)+ | |
| 1165 | apply (simp add: mult_matrix_def) | |
| 1166 | apply (simplesubst mult_matrix_nm[of _ "max (ncols (mult_matrix_n (max (ncols A) (nrows B)) fmul1 fadd1 A B)) (nrows C)" _ "max (ncols B) (nrows C)"]) | |
| 1167 | apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+ | |
| 1168 | apply (simplesubst mult_matrix_nm[of _ "max (ncols A) (nrows (mult_matrix_n (max (ncols B) (nrows C)) fmul2 fadd2 B C))" _ "max (ncols A) (nrows B)"]) apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+ | |
| 1169 | apply (simplesubst mult_matrix_nm[of _ _ _ "?N"]) | |
| 1170 | apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+ | |
| 1171 | apply (simplesubst mult_matrix_nm[of _ _ _ "?N"]) | |
| 1172 | apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+ | |
| 1173 | apply (simplesubst mult_matrix_nm[of _ _ _ "?N"]) | |
| 1174 | apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+ | |
| 1175 | apply (simplesubst mult_matrix_nm[of _ _ _ "?N"]) | |
| 1176 | apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+ | |
| 1177 | apply (simp add: mult_matrix_n_def) | |
| 1178 | apply (rule comb_left) | |
| 1179 | apply ((rule ext)+, simp) | |
| 1180 | apply (simplesubst RepAbs_matrix) | |
| 1181 | apply (rule exI[of _ "nrows B"]) | |
| 1182 | apply (simp add: nrows prems foldseq_zero) | |
| 1183 | apply (rule exI[of _ "ncols C"]) | |
| 1184 | apply (simp add: prems ncols foldseq_zero) | |
| 1185 | apply (subst RepAbs_matrix) | |
| 1186 | apply (rule exI[of _ "nrows A"]) | |
| 1187 | apply (simp add: nrows prems foldseq_zero) | |
| 1188 | apply (rule exI[of _ "ncols B"]) | |
| 1189 | apply (simp add: prems ncols foldseq_zero) | |
| 1190 | apply (simp add: fmul2fadd1fold fmul1fadd2fold prems) | |
| 1191 | apply (subst foldseq_foldseq) | |
| 1192 | apply (simp add: prems)+ | |
| 1193 | by (simp add: transpose_infmatrix) | |
| 1194 | qed | |
| 1195 | ||
| 1196 | lemma | |
| 1197 | assumes prems: | |
| 1198 | "! a. fmul1 0 a = 0" | |
| 1199 | "! a. fmul1 a 0 = 0" | |
| 1200 | "! a. fmul2 0 a = 0" | |
| 1201 | "! a. fmul2 a 0 = 0" | |
| 1202 | "fadd1 0 0 = 0" | |
| 1203 | "fadd2 0 0 = 0" | |
| 1204 | "! a b c d. fadd2 (fadd1 a b) (fadd1 c d) = fadd1 (fadd2 a c) (fadd2 b d)" | |
| 1205 | "associative fadd1" | |
| 1206 | "associative fadd2" | |
| 1207 | "! a b c. fmul2 (fmul1 a b) c = fmul1 a (fmul2 b c)" | |
| 1208 | "! a b c. fmul2 (fadd1 a b) c = fadd1 (fmul2 a c) (fmul2 b c)" | |
| 1209 | "! a b c. fmul1 c (fadd2 a b) = fadd2 (fmul1 c a) (fmul1 c b)" | |
| 1210 | shows | |
| 1211 | "(mult_matrix fmul1 fadd1 A) o (mult_matrix fmul2 fadd2 B) = mult_matrix fmul2 fadd2 (mult_matrix fmul1 fadd1 A B)" | |
| 1212 | apply (rule ext)+ | |
| 1213 | apply (simp add: comp_def ) | |
| 1214 | by (simp add: mult_matrix_assoc prems) | |
| 1215 | ||
| 1216 | lemma mult_matrix_assoc_simple: | |
| 1217 | assumes prems: | |
| 1218 | "! a. fmul 0 a = 0" | |
| 1219 | "! a. fmul a 0 = 0" | |
| 1220 | "fadd 0 0 = 0" | |
| 1221 | "associative fadd" | |
| 1222 | "commutative fadd" | |
| 1223 | "associative fmul" | |
| 1224 | "distributive fmul fadd" | |
| 1225 | shows "mult_matrix fmul fadd (mult_matrix fmul fadd A B) C = mult_matrix fmul fadd A (mult_matrix fmul fadd B C)" (is ?concl) | |
| 1226 | proof - | |
| 1227 | have "!! a b c d. fadd (fadd a b) (fadd c d) = fadd (fadd a c) (fadd b d)" | |
| 1228 | by (simp! add: associative_def commutative_def) | |
| 1229 | then show ?concl | |
| 1230 | apply (subst mult_matrix_assoc) | |
| 1231 | apply (simp_all!) | |
| 1232 | by (simp add: associative_def distributive_def l_distributive_def r_distributive_def)+ | |
| 1233 | qed | |
| 1234 | ||
| 1235 | lemma transpose_apply_matrix: "f 0 = 0 \<Longrightarrow> transpose_matrix (apply_matrix f A) = apply_matrix f (transpose_matrix A)" | |
| 1236 | apply (simp add: Rep_matrix_inject[THEN sym]) | |
| 1237 | apply (rule ext)+ | |
| 1238 | by simp | |
| 1239 | ||
| 1240 | lemma transpose_combine_matrix: "f 0 0 = 0 \<Longrightarrow> transpose_matrix (combine_matrix f A B) = combine_matrix f (transpose_matrix A) (transpose_matrix B)" | |
| 1241 | apply (simp add: Rep_matrix_inject[THEN sym]) | |
| 1242 | apply (rule ext)+ | |
| 1243 | by simp | |
| 1244 | ||
| 1245 | lemma Rep_mult_matrix: | |
| 1246 | assumes | |
| 1247 | "! a. fmul 0 a = 0" | |
| 1248 | "! a. fmul a 0 = 0" | |
| 1249 | "fadd 0 0 = 0" | |
| 1250 | shows | |
| 1251 | "Rep_matrix(mult_matrix fmul fadd A B) j i = | |
| 1252 | foldseq fadd (% k. fmul (Rep_matrix A j k) (Rep_matrix B k i)) (max (ncols A) (nrows B))" | |
| 1253 | apply (simp add: mult_matrix_def mult_matrix_n_def) | |
| 1254 | apply (subst RepAbs_matrix) | |
| 1255 | apply (rule exI[of _ "nrows A"], simp! add: nrows foldseq_zero) | |
| 1256 | apply (rule exI[of _ "ncols B"], simp! add: ncols foldseq_zero) | |
| 1257 | by simp | |
| 1258 | ||
| 1259 | lemma transpose_mult_matrix: | |
| 1260 | assumes | |
| 1261 | "! a. fmul 0 a = 0" | |
| 1262 | "! a. fmul a 0 = 0" | |
| 1263 | "fadd 0 0 = 0" | |
| 1264 | "! x y. fmul y x = fmul x y" | |
| 1265 | shows | |
| 1266 | "transpose_matrix (mult_matrix fmul fadd A B) = mult_matrix fmul fadd (transpose_matrix B) (transpose_matrix A)" | |
| 1267 | apply (simp add: Rep_matrix_inject[THEN sym]) | |
| 1268 | apply (rule ext)+ | |
| 1269 | by (simp! add: Rep_mult_matrix max_ac) | |
| 1270 | ||
| 1271 | lemma column_transpose_matrix: "column_of_matrix (transpose_matrix A) n = transpose_matrix (row_of_matrix A n)" | |
| 1272 | apply (simp add: Rep_matrix_inject[THEN sym]) | |
| 1273 | apply (rule ext)+ | |
| 1274 | by simp | |
| 1275 | ||
| 1276 | lemma take_columns_transpose_matrix: "take_columns (transpose_matrix A) n = transpose_matrix (take_rows A n)" | |
| 1277 | apply (simp add: Rep_matrix_inject[THEN sym]) | |
| 1278 | apply (rule ext)+ | |
| 1279 | by simp | |
| 1280 | ||
| 27580 | 1281 | instantiation matrix :: ("{zero, ord}") ord
 | 
| 27484 | 1282 | begin | 
| 1283 | ||
| 1284 | definition | |
| 1285 | le_matrix_def: "A \<le> B \<longleftrightarrow> (\<forall>j i. Rep_matrix A j i \<le> Rep_matrix B j i)" | |
| 1286 | ||
| 1287 | definition | |
| 28637 | 1288 | less_def: "A < (B\<Colon>'a matrix) \<longleftrightarrow> A \<le> B \<and> \<not> B \<le> A" | 
| 27484 | 1289 | |
| 1290 | instance .. | |
| 1291 | ||
| 1292 | end | |
| 1293 | ||
| 27580 | 1294 | instance matrix :: ("{zero, order}") order
 | 
| 27484 | 1295 | apply intro_classes | 
| 1296 | apply (simp_all add: le_matrix_def less_def) | |
| 1297 | apply (auto) | |
| 1298 | apply (drule_tac x=j in spec, drule_tac x=j in spec) | |
| 1299 | apply (drule_tac x=i in spec, drule_tac x=i in spec) | |
| 1300 | apply (simp) | |
| 1301 | apply (simp add: Rep_matrix_inject[THEN sym]) | |
| 1302 | apply (rule ext)+ | |
| 1303 | apply (drule_tac x=xa in spec, drule_tac x=xa in spec) | |
| 1304 | apply (drule_tac x=xb in spec, drule_tac x=xb in spec) | |
| 28637 | 1305 | apply simp | 
| 1306 | done | |
| 27484 | 1307 | |
| 1308 | lemma le_apply_matrix: | |
| 1309 | assumes | |
| 1310 | "f 0 = 0" | |
| 1311 | "! x y. x <= y \<longrightarrow> f x <= f y" | |
| 1312 |   "(a::('a::{ord, zero}) matrix) <= b"
 | |
| 1313 | shows | |
| 1314 | "apply_matrix f a <= apply_matrix f b" | |
| 1315 | by (simp! add: le_matrix_def) | |
| 1316 | ||
| 1317 | lemma le_combine_matrix: | |
| 1318 | assumes | |
| 1319 | "f 0 0 = 0" | |
| 1320 | "! a b c d. a <= b & c <= d \<longrightarrow> f a c <= f b d" | |
| 1321 | "A <= B" | |
| 1322 | "C <= D" | |
| 1323 | shows | |
| 1324 | "combine_matrix f A C <= combine_matrix f B D" | |
| 1325 | by (simp! add: le_matrix_def) | |
| 1326 | ||
| 1327 | lemma le_left_combine_matrix: | |
| 1328 | assumes | |
| 1329 | "f 0 0 = 0" | |
| 1330 | "! a b c. a <= b \<longrightarrow> f c a <= f c b" | |
| 1331 | "A <= B" | |
| 1332 | shows | |
| 1333 | "combine_matrix f C A <= combine_matrix f C B" | |
| 1334 | by (simp! add: le_matrix_def) | |
| 1335 | ||
| 1336 | lemma le_right_combine_matrix: | |
| 1337 | assumes | |
| 1338 | "f 0 0 = 0" | |
| 1339 | "! a b c. a <= b \<longrightarrow> f a c <= f b c" | |
| 1340 | "A <= B" | |
| 1341 | shows | |
| 1342 | "combine_matrix f A C <= combine_matrix f B C" | |
| 1343 | by (simp! add: le_matrix_def) | |
| 1344 | ||
| 1345 | lemma le_transpose_matrix: "(A <= B) = (transpose_matrix A <= transpose_matrix B)" | |
| 1346 | by (simp add: le_matrix_def, auto) | |
| 1347 | ||
| 1348 | lemma le_foldseq: | |
| 1349 | assumes | |
| 1350 | "! a b c d . a <= b & c <= d \<longrightarrow> f a c <= f b d" | |
| 1351 | "! i. i <= n \<longrightarrow> s i <= t i" | |
| 1352 | shows | |
| 1353 | "foldseq f s n <= foldseq f t n" | |
| 1354 | proof - | |
| 1355 | have "! s t. (! i. i<=n \<longrightarrow> s i <= t i) \<longrightarrow> foldseq f s n <= foldseq f t n" by (induct_tac n, simp_all!) | |
| 1356 | then show "foldseq f s n <= foldseq f t n" by (simp!) | |
| 1357 | qed | |
| 1358 | ||
| 1359 | lemma le_left_mult: | |
| 1360 | assumes | |
| 1361 | "! a b c d. a <= b & c <= d \<longrightarrow> fadd a c <= fadd b d" | |
| 1362 | "! c a b. 0 <= c & a <= b \<longrightarrow> fmul c a <= fmul c b" | |
| 1363 | "! a. fmul 0 a = 0" | |
| 1364 | "! a. fmul a 0 = 0" | |
| 1365 | "fadd 0 0 = 0" | |
| 1366 | "0 <= C" | |
| 1367 | "A <= B" | |
| 1368 | shows | |
| 1369 | "mult_matrix fmul fadd C A <= mult_matrix fmul fadd C B" | |
| 1370 | apply (simp! add: le_matrix_def Rep_mult_matrix) | |
| 1371 | apply (auto) | |
| 1372 | apply (simplesubst foldseq_zerotail[of _ _ _ "max (ncols C) (max (nrows A) (nrows B))"], simp_all add: nrows ncols max1 max2)+ | |
| 1373 | apply (rule le_foldseq) | |
| 1374 | by (auto) | |
| 1375 | ||
| 1376 | lemma le_right_mult: | |
| 1377 | assumes | |
| 1378 | "! a b c d. a <= b & c <= d \<longrightarrow> fadd a c <= fadd b d" | |
| 1379 | "! c a b. 0 <= c & a <= b \<longrightarrow> fmul a c <= fmul b c" | |
| 1380 | "! a. fmul 0 a = 0" | |
| 1381 | "! a. fmul a 0 = 0" | |
| 1382 | "fadd 0 0 = 0" | |
| 1383 | "0 <= C" | |
| 1384 | "A <= B" | |
| 1385 | shows | |
| 1386 | "mult_matrix fmul fadd A C <= mult_matrix fmul fadd B C" | |
| 1387 | apply (simp! add: le_matrix_def Rep_mult_matrix) | |
| 1388 | apply (auto) | |
| 1389 | apply (simplesubst foldseq_zerotail[of _ _ _ "max (nrows C) (max (ncols A) (ncols B))"], simp_all add: nrows ncols max1 max2)+ | |
| 1390 | apply (rule le_foldseq) | |
| 1391 | by (auto) | |
| 1392 | ||
| 1393 | lemma spec2: "! j i. P j i \<Longrightarrow> P j i" by blast | |
| 1394 | lemma neg_imp: "(\<not> Q \<longrightarrow> \<not> P) \<Longrightarrow> P \<longrightarrow> Q" by blast | |
| 1395 | ||
| 1396 | lemma singleton_matrix_le[simp]: "(singleton_matrix j i a <= singleton_matrix j i b) = (a <= (b::_::order))" | |
| 1397 | by (auto simp add: le_matrix_def) | |
| 1398 | ||
| 1399 | lemma singleton_le_zero[simp]: "(singleton_matrix j i x <= 0) = (x <= (0::'a::{order,zero}))"
 | |
| 1400 | apply (auto) | |
| 1401 | apply (simp add: le_matrix_def) | |
| 1402 | apply (drule_tac j=j and i=i in spec2) | |
| 1403 | apply (simp) | |
| 1404 | apply (simp add: le_matrix_def) | |
| 1405 | done | |
| 1406 | ||
| 1407 | lemma singleton_ge_zero[simp]: "(0 <= singleton_matrix j i x) = ((0::'a::{order,zero}) <= x)"
 | |
| 1408 | apply (auto) | |
| 1409 | apply (simp add: le_matrix_def) | |
| 1410 | apply (drule_tac j=j and i=i in spec2) | |
| 1411 | apply (simp) | |
| 1412 | apply (simp add: le_matrix_def) | |
| 1413 | done | |
| 1414 | ||
| 1415 | lemma move_matrix_le_zero[simp]: "0 <= j \<Longrightarrow> 0 <= i \<Longrightarrow> (move_matrix A j i <= 0) = (A <= (0::('a::{order,zero}) matrix))"
 | |
| 1416 | apply (auto simp add: le_matrix_def neg_def) | |
| 1417 | apply (drule_tac j="ja+(nat j)" and i="ia+(nat i)" in spec2) | |
| 1418 | apply (auto) | |
| 1419 | done | |
| 1420 | ||
| 1421 | lemma move_matrix_zero_le[simp]: "0 <= j \<Longrightarrow> 0 <= i \<Longrightarrow> (0 <= move_matrix A j i) = ((0::('a::{order,zero}) matrix) <= A)"
 | |
| 1422 | apply (auto simp add: le_matrix_def neg_def) | |
| 1423 | apply (drule_tac j="ja+(nat j)" and i="ia+(nat i)" in spec2) | |
| 1424 | apply (auto) | |
| 1425 | done | |
| 1426 | ||
| 1427 | lemma move_matrix_le_move_matrix_iff[simp]: "0 <= j \<Longrightarrow> 0 <= i \<Longrightarrow> (move_matrix A j i <= move_matrix B j i) = (A <= (B::('a::{order,zero}) matrix))"
 | |
| 1428 | apply (auto simp add: le_matrix_def neg_def) | |
| 1429 | apply (drule_tac j="ja+(nat j)" and i="ia+(nat i)" in spec2) | |
| 1430 | apply (auto) | |
| 1431 | done | |
| 1432 | ||
| 27580 | 1433 | instantiation matrix :: ("{lattice, zero}") lattice
 | 
| 25764 | 1434 | begin | 
| 1435 | ||
| 28562 | 1436 | definition [code del]: "inf = combine_matrix inf" | 
| 25764 | 1437 | |
| 28562 | 1438 | definition [code del]: "sup = combine_matrix sup" | 
| 25764 | 1439 | |
| 1440 | instance | |
| 22452 
8a86fd2a1bf0
adjusted to new lattice theory developement in Lattices.thy / FixedPoint.thy
 haftmann parents: 
22422diff
changeset | 1441 | by default (auto simp add: inf_le1 inf_le2 le_infI le_matrix_def inf_matrix_def sup_matrix_def) | 
| 
8a86fd2a1bf0
adjusted to new lattice theory developement in Lattices.thy / FixedPoint.thy
 haftmann parents: 
22422diff
changeset | 1442 | |
| 25764 | 1443 | end | 
| 1444 | ||
| 1445 | instantiation matrix :: ("{plus, zero}") plus
 | |
| 1446 | begin | |
| 1447 | ||
| 1448 | definition | |
| 28562 | 1449 | plus_matrix_def [code del]: "A + B = combine_matrix (op +) A B" | 
| 25764 | 1450 | |
| 1451 | instance .. | |
| 1452 | ||
| 1453 | end | |
| 1454 | ||
| 1455 | instantiation matrix :: ("{uminus, zero}") uminus
 | |
| 1456 | begin | |
| 1457 | ||
| 1458 | definition | |
| 28562 | 1459 | minus_matrix_def [code del]: "- A = apply_matrix uminus A" | 
| 25764 | 1460 | |
| 1461 | instance .. | |
| 1462 | ||
| 1463 | end | |
| 1464 | ||
| 1465 | instantiation matrix :: ("{minus, zero}") minus
 | |
| 1466 | begin | |
| 14593 | 1467 | |
| 25764 | 1468 | definition | 
| 28562 | 1469 | diff_matrix_def [code del]: "A - B = combine_matrix (op -) A B" | 
| 25764 | 1470 | |
| 1471 | instance .. | |
| 1472 | ||
| 1473 | end | |
| 1474 | ||
| 1475 | instantiation matrix :: ("{plus, times, zero}") times
 | |
| 1476 | begin | |
| 1477 | ||
| 1478 | definition | |
| 28562 | 1479 | times_matrix_def [code del]: "A * B = mult_matrix (op *) (op +) A B" | 
| 14940 | 1480 | |
| 25764 | 1481 | instance .. | 
| 1482 | ||
| 1483 | end | |
| 1484 | ||
| 27653 | 1485 | instantiation matrix :: ("{lattice, uminus, zero}") abs
 | 
| 25764 | 1486 | begin | 
| 14940 | 1487 | |
| 25764 | 1488 | definition | 
| 28562 | 1489 | abs_matrix_def [code del]: "abs (A \<Colon> 'a matrix) = sup A (- A)" | 
| 25764 | 1490 | |
| 1491 | instance .. | |
| 1492 | ||
| 1493 | end | |
| 23879 | 1494 | |
| 27653 | 1495 | instance matrix :: (monoid_add) monoid_add | 
| 1496 | proof | |
| 1497 | fix A B C :: "'a matrix" | |
| 14940 | 1498 | show "A + B + C = A + (B + C)" | 
| 1499 | apply (simp add: plus_matrix_def) | |
| 1500 | apply (rule combine_matrix_assoc[simplified associative_def, THEN spec, THEN spec, THEN spec]) | |
| 1501 | apply (simp_all add: add_assoc) | |
| 1502 | done | |
| 27653 | 1503 | show "0 + A = A" | 
| 1504 | apply (simp add: plus_matrix_def) | |
| 1505 | apply (rule combine_matrix_zero_l_neutral[simplified zero_l_neutral_def, THEN spec]) | |
| 1506 | apply (simp) | |
| 1507 | done | |
| 1508 | show "A + 0 = A" | |
| 1509 | apply (simp add: plus_matrix_def) | |
| 1510 | apply (rule combine_matrix_zero_r_neutral [simplified zero_r_neutral_def, THEN spec]) | |
| 1511 | apply (simp) | |
| 1512 | done | |
| 1513 | qed | |
| 1514 | ||
| 1515 | instance matrix :: (comm_monoid_add) comm_monoid_add | |
| 1516 | proof | |
| 1517 | fix A B :: "'a matrix" | |
| 14940 | 1518 | show "A + B = B + A" | 
| 1519 | apply (simp add: plus_matrix_def) | |
| 1520 | apply (rule combine_matrix_commute[simplified commutative_def, THEN spec, THEN spec]) | |
| 1521 | apply (simp_all add: add_commute) | |
| 1522 | done | |
| 1523 | show "0 + A = A" | |
| 1524 | apply (simp add: plus_matrix_def) | |
| 1525 | apply (rule combine_matrix_zero_l_neutral[simplified zero_l_neutral_def, THEN spec]) | |
| 1526 | apply (simp) | |
| 1527 | done | |
| 27653 | 1528 | qed | 
| 1529 | ||
| 1530 | instance matrix :: (group_add) group_add | |
| 1531 | proof | |
| 1532 | fix A B :: "'a matrix" | |
| 1533 | show "- A + A = 0" | |
| 1534 | by (simp add: plus_matrix_def minus_matrix_def Rep_matrix_inject[symmetric] ext) | |
| 1535 | show "A - B = A + - B" | |
| 1536 | by (simp add: plus_matrix_def diff_matrix_def minus_matrix_def Rep_matrix_inject [symmetric] ext diff_minus) | |
| 1537 | qed | |
| 1538 | ||
| 1539 | instance matrix :: (ab_group_add) ab_group_add | |
| 1540 | proof | |
| 1541 | fix A B :: "'a matrix" | |
| 14940 | 1542 | show "- A + A = 0" | 
| 1543 | by (simp add: plus_matrix_def minus_matrix_def Rep_matrix_inject[symmetric] ext) | |
| 1544 | show "A - B = A + - B" | |
| 1545 | by (simp add: plus_matrix_def diff_matrix_def minus_matrix_def Rep_matrix_inject[symmetric] ext) | |
| 27653 | 1546 | qed | 
| 1547 | ||
| 35028 
108662d50512
more consistent naming of type classes involving orderings (and lattices) -- c.f. NEWS
 haftmann parents: 
34872diff
changeset | 1548 | instance matrix :: (ordered_ab_group_add) ordered_ab_group_add | 
| 27653 | 1549 | proof | 
| 1550 | fix A B C :: "'a matrix" | |
| 14940 | 1551 | assume "A <= B" | 
| 1552 | then show "C + A <= C + B" | |
| 1553 | apply (simp add: plus_matrix_def) | |
| 1554 | apply (rule le_left_combine_matrix) | |
| 1555 | apply (simp_all) | |
| 1556 | done | |
| 1557 | qed | |
| 27653 | 1558 | |
| 35028 
108662d50512
more consistent naming of type classes involving orderings (and lattices) -- c.f. NEWS
 haftmann parents: 
34872diff
changeset | 1559 | instance matrix :: (lattice_ab_group_add) semilattice_inf_ab_group_add .. | 
| 
108662d50512
more consistent naming of type classes involving orderings (and lattices) -- c.f. NEWS
 haftmann parents: 
34872diff
changeset | 1560 | instance matrix :: (lattice_ab_group_add) semilattice_sup_ab_group_add .. | 
| 14593 | 1561 | |
| 34872 | 1562 | instance matrix :: (semiring_0) semiring_0 | 
| 14940 | 1563 | proof | 
| 27653 | 1564 | fix A B C :: "'a matrix" | 
| 14940 | 1565 | show "A * B * C = A * (B * C)" | 
| 1566 | apply (simp add: times_matrix_def) | |
| 1567 | apply (rule mult_matrix_assoc) | |
| 29667 | 1568 | apply (simp_all add: associative_def algebra_simps) | 
| 14940 | 1569 | done | 
| 1570 | show "(A + B) * C = A * C + B * C" | |
| 1571 | apply (simp add: times_matrix_def plus_matrix_def) | |
| 1572 | apply (rule l_distributive_matrix[simplified l_distributive_def, THEN spec, THEN spec, THEN spec]) | |
| 29667 | 1573 | apply (simp_all add: associative_def commutative_def algebra_simps) | 
| 14940 | 1574 | done | 
| 1575 | show "A * (B + C) = A * B + A * C" | |
| 1576 | apply (simp add: times_matrix_def plus_matrix_def) | |
| 1577 | apply (rule r_distributive_matrix[simplified r_distributive_def, THEN spec, THEN spec, THEN spec]) | |
| 29667 | 1578 | apply (simp_all add: associative_def commutative_def algebra_simps) | 
| 27653 | 1579 | done | 
| 34872 | 1580 | show "0 * A = 0" by (simp add: times_matrix_def) | 
| 1581 | show "A * 0 = 0" by (simp add: times_matrix_def) | |
| 1582 | qed | |
| 1583 | ||
| 1584 | instance matrix :: (ring) ring .. | |
| 27653 | 1585 | |
| 35028 
108662d50512
more consistent naming of type classes involving orderings (and lattices) -- c.f. NEWS
 haftmann parents: 
34872diff
changeset | 1586 | instance matrix :: (ordered_ring) ordered_ring | 
| 27653 | 1587 | proof | 
| 1588 | fix A B C :: "'a matrix" | |
| 14940 | 1589 | assume a: "A \<le> B" | 
| 1590 | assume b: "0 \<le> C" | |
| 1591 | from a b show "C * A \<le> C * B" | |
| 1592 | apply (simp add: times_matrix_def) | |
| 1593 | apply (rule le_left_mult) | |
| 1594 | apply (simp_all add: add_mono mult_left_mono) | |
| 1595 | done | |
| 1596 | from a b show "A * C \<le> B * C" | |
| 1597 | apply (simp add: times_matrix_def) | |
| 1598 | apply (rule le_right_mult) | |
| 1599 | apply (simp_all add: add_mono mult_right_mono) | |
| 1600 | done | |
| 27653 | 1601 | qed | 
| 1602 | ||
| 35028 
108662d50512
more consistent naming of type classes involving orderings (and lattices) -- c.f. NEWS
 haftmann parents: 
34872diff
changeset | 1603 | instance matrix :: (lattice_ring) lattice_ring | 
| 27653 | 1604 | proof | 
| 35028 
108662d50512
more consistent naming of type classes involving orderings (and lattices) -- c.f. NEWS
 haftmann parents: 
34872diff
changeset | 1605 |   fix A B C :: "('a :: lattice_ring) matrix"
 | 
| 27653 | 1606 | show "abs A = sup A (-A)" | 
| 1607 | by (simp add: abs_matrix_def) | |
| 1608 | qed | |
| 14593 | 1609 | |
| 25303 
0699e20feabd
renamed lordered_*_* to lordered_*_add_*; further localization
 haftmann parents: 
23879diff
changeset | 1610 | lemma Rep_matrix_add[simp]: | 
| 27653 | 1611 |   "Rep_matrix ((a::('a::monoid_add)matrix)+b) j i  = (Rep_matrix a j i) + (Rep_matrix b j i)"
 | 
| 1612 | by (simp add: plus_matrix_def) | |
| 14593 | 1613 | |
| 34872 | 1614 | lemma Rep_matrix_mult: "Rep_matrix ((a::('a::semiring_0) matrix) * b) j i = 
 | 
| 14940 | 1615 | foldseq (op +) (% k. (Rep_matrix a j k) * (Rep_matrix b k i)) (max (ncols a) (nrows b))" | 
| 1616 | apply (simp add: times_matrix_def) | |
| 1617 | apply (simp add: Rep_mult_matrix) | |
| 1618 | done | |
| 14593 | 1619 | |
| 27653 | 1620 | lemma apply_matrix_add: "! x y. f (x+y) = (f x) + (f y) \<Longrightarrow> f 0 = (0::'a) | 
| 1621 |   \<Longrightarrow> apply_matrix f ((a::('a::monoid_add) matrix) + b) = (apply_matrix f a) + (apply_matrix f b)"
 | |
| 14940 | 1622 | apply (subst Rep_matrix_inject[symmetric]) | 
| 14593 | 1623 | apply (rule ext)+ | 
| 14940 | 1624 | apply (simp) | 
| 1625 | done | |
| 14593 | 1626 | |
| 27653 | 1627 | lemma singleton_matrix_add: "singleton_matrix j i ((a::_::monoid_add)+b) = (singleton_matrix j i a) + (singleton_matrix j i b)" | 
| 14940 | 1628 | apply (subst Rep_matrix_inject[symmetric]) | 
| 1629 | apply (rule ext)+ | |
| 1630 | apply (simp) | |
| 1631 | done | |
| 14593 | 1632 | |
| 34872 | 1633 | lemma nrows_mult: "nrows ((A::('a::semiring_0) matrix) * B) <= nrows A"
 | 
| 14593 | 1634 | by (simp add: times_matrix_def mult_nrows) | 
| 1635 | ||
| 34872 | 1636 | lemma ncols_mult: "ncols ((A::('a::semiring_0) matrix) * B) <= ncols B"
 | 
| 14593 | 1637 | by (simp add: times_matrix_def mult_ncols) | 
| 1638 | ||
| 22422 
ee19cdb07528
stepping towards uniform lattice theory development in HOL
 haftmann parents: 
21312diff
changeset | 1639 | definition | 
| 
ee19cdb07528
stepping towards uniform lattice theory development in HOL
 haftmann parents: 
21312diff
changeset | 1640 |   one_matrix :: "nat \<Rightarrow> ('a::{zero,one}) matrix" where
 | 
| 
ee19cdb07528
stepping towards uniform lattice theory development in HOL
 haftmann parents: 
21312diff
changeset | 1641 | "one_matrix n = Abs_matrix (% j i. if j = i & j < n then 1 else 0)" | 
| 14593 | 1642 | |
| 1643 | lemma Rep_one_matrix[simp]: "Rep_matrix (one_matrix n) j i = (if (j = i & j < n) then 1 else 0)" | |
| 1644 | apply (simp add: one_matrix_def) | |
| 15481 | 1645 | apply (simplesubst RepAbs_matrix) | 
| 14593 | 1646 | apply (rule exI[of _ n], simp add: split_if)+ | 
| 16733 
236dfafbeb63
linear arithmetic now takes "&" in assumptions apart.
 nipkow parents: 
15481diff
changeset | 1647 | by (simp add: split_if) | 
| 14593 | 1648 | |
| 20633 | 1649 | lemma nrows_one_matrix[simp]: "nrows ((one_matrix n) :: ('a::zero_neq_one)matrix) = n" (is "?r = _")
 | 
| 14593 | 1650 | proof - | 
| 1651 | have "?r <= n" by (simp add: nrows_le) | |
| 14940 | 1652 | moreover have "n <= ?r" by (simp add:le_nrows, arith) | 
| 14593 | 1653 | ultimately show "?r = n" by simp | 
| 1654 | qed | |
| 1655 | ||
| 20633 | 1656 | lemma ncols_one_matrix[simp]: "ncols ((one_matrix n) :: ('a::zero_neq_one)matrix) = n" (is "?r = _")
 | 
| 14593 | 1657 | proof - | 
| 1658 | have "?r <= n" by (simp add: ncols_le) | |
| 1659 | moreover have "n <= ?r" by (simp add: le_ncols, arith) | |
| 1660 | ultimately show "?r = n" by simp | |
| 1661 | qed | |
| 1662 | ||
| 34872 | 1663 | lemma one_matrix_mult_right[simp]: "ncols A <= n \<Longrightarrow> (A::('a::{semiring_1}) matrix) * (one_matrix n) = A"
 | 
| 14593 | 1664 | apply (subst Rep_matrix_inject[THEN sym]) | 
| 1665 | apply (rule ext)+ | |
| 1666 | apply (simp add: times_matrix_def Rep_mult_matrix) | |
| 1667 | apply (rule_tac j1="xa" in ssubst[OF foldseq_almostzero]) | |
| 1668 | apply (simp_all) | |
| 32440 | 1669 | by (simp add: ncols) | 
| 14593 | 1670 | |
| 34872 | 1671 | lemma one_matrix_mult_left[simp]: "nrows A <= n \<Longrightarrow> (one_matrix n) * A = (A::('a::semiring_1) matrix)"
 | 
| 14593 | 1672 | apply (subst Rep_matrix_inject[THEN sym]) | 
| 1673 | apply (rule ext)+ | |
| 1674 | apply (simp add: times_matrix_def Rep_mult_matrix) | |
| 1675 | apply (rule_tac j1="x" in ssubst[OF foldseq_almostzero]) | |
| 1676 | apply (simp_all) | |
| 32440 | 1677 | by (simp add: nrows) | 
| 14593 | 1678 | |
| 27653 | 1679 | lemma transpose_matrix_mult: "transpose_matrix ((A::('a::comm_ring) matrix)*B) = (transpose_matrix B) * (transpose_matrix A)"
 | 
| 14940 | 1680 | apply (simp add: times_matrix_def) | 
| 1681 | apply (subst transpose_mult_matrix) | |
| 1682 | apply (simp_all add: mult_commute) | |
| 1683 | done | |
| 1684 | ||
| 27653 | 1685 | lemma transpose_matrix_add: "transpose_matrix ((A::('a::monoid_add) matrix)+B) = transpose_matrix A + transpose_matrix B"
 | 
| 14940 | 1686 | by (simp add: plus_matrix_def transpose_combine_matrix) | 
| 1687 | ||
| 27653 | 1688 | lemma transpose_matrix_diff: "transpose_matrix ((A::('a::group_add) matrix)-B) = transpose_matrix A - transpose_matrix B"
 | 
| 14940 | 1689 | by (simp add: diff_matrix_def transpose_combine_matrix) | 
| 1690 | ||
| 27653 | 1691 | lemma transpose_matrix_minus: "transpose_matrix (-(A::('a::group_add) matrix)) = - transpose_matrix (A::'a matrix)"
 | 
| 14940 | 1692 | by (simp add: minus_matrix_def transpose_apply_matrix) | 
| 1693 | ||
| 1694 | constdefs | |
| 27653 | 1695 |   right_inverse_matrix :: "('a::{ring_1}) matrix \<Rightarrow> 'a matrix \<Rightarrow> bool"
 | 
| 14940 | 1696 | "right_inverse_matrix A X == (A * X = one_matrix (max (nrows A) (ncols X))) \<and> nrows X \<le> ncols A" | 
| 27653 | 1697 |   left_inverse_matrix :: "('a::{ring_1}) matrix \<Rightarrow> 'a matrix \<Rightarrow> bool"
 | 
| 14940 | 1698 | "left_inverse_matrix A X == (X * A = one_matrix (max(nrows X) (ncols A))) \<and> ncols X \<le> nrows A" | 
| 27653 | 1699 |   inverse_matrix :: "('a::{ring_1}) matrix \<Rightarrow> 'a matrix \<Rightarrow> bool"
 | 
| 14940 | 1700 | "inverse_matrix A X == (right_inverse_matrix A X) \<and> (left_inverse_matrix A X)" | 
| 14593 | 1701 | |
| 1702 | lemma right_inverse_matrix_dim: "right_inverse_matrix A X \<Longrightarrow> nrows A = ncols X" | |
| 1703 | apply (insert ncols_mult[of A X], insert nrows_mult[of A X]) | |
| 1704 | by (simp add: right_inverse_matrix_def) | |
| 1705 | ||
| 14940 | 1706 | lemma left_inverse_matrix_dim: "left_inverse_matrix A Y \<Longrightarrow> ncols A = nrows Y" | 
| 1707 | apply (insert ncols_mult[of Y A], insert nrows_mult[of Y A]) | |
| 1708 | by (simp add: left_inverse_matrix_def) | |
| 1709 | ||
| 1710 | lemma left_right_inverse_matrix_unique: | |
| 1711 | assumes "left_inverse_matrix A Y" "right_inverse_matrix A X" | |
| 1712 | shows "X = Y" | |
| 1713 | proof - | |
| 1714 | have "Y = Y * one_matrix (nrows A)" | |
| 1715 | apply (subst one_matrix_mult_right) | |
| 1716 | apply (insert prems) | |
| 1717 | by (simp_all add: left_inverse_matrix_def) | |
| 1718 | also have "\<dots> = Y * (A * X)" | |
| 1719 | apply (insert prems) | |
| 1720 | apply (frule right_inverse_matrix_dim) | |
| 1721 | by (simp add: right_inverse_matrix_def) | |
| 1722 | also have "\<dots> = (Y * A) * X" by (simp add: mult_assoc) | |
| 1723 | also have "\<dots> = X" | |
| 1724 | apply (insert prems) | |
| 1725 | apply (frule left_inverse_matrix_dim) | |
| 1726 | apply (simp_all add: left_inverse_matrix_def right_inverse_matrix_def one_matrix_mult_left) | |
| 1727 | done | |
| 1728 | ultimately show "X = Y" by (simp) | |
| 1729 | qed | |
| 1730 | ||
| 1731 | lemma inverse_matrix_inject: "\<lbrakk> inverse_matrix A X; inverse_matrix A Y \<rbrakk> \<Longrightarrow> X = Y" | |
| 1732 | by (auto simp add: inverse_matrix_def left_right_inverse_matrix_unique) | |
| 1733 | ||
| 1734 | lemma one_matrix_inverse: "inverse_matrix (one_matrix n) (one_matrix n)" | |
| 1735 | by (simp add: inverse_matrix_def left_inverse_matrix_def right_inverse_matrix_def) | |
| 1736 | ||
| 34872 | 1737 | lemma zero_imp_mult_zero: "(a::'a::semiring_0) = 0 | b = 0 \<Longrightarrow> a * b = 0" | 
| 14940 | 1738 | by auto | 
| 1739 | ||
| 1740 | lemma Rep_matrix_zero_imp_mult_zero: | |
| 35028 
108662d50512
more consistent naming of type classes involving orderings (and lattices) -- c.f. NEWS
 haftmann parents: 
34872diff
changeset | 1741 |   "! j i k. (Rep_matrix A j k = 0) | (Rep_matrix B k i) = 0  \<Longrightarrow> A * B = (0::('a::lattice_ring) matrix)"
 | 
| 14940 | 1742 | apply (subst Rep_matrix_inject[symmetric]) | 
| 1743 | apply (rule ext)+ | |
| 1744 | apply (auto simp add: Rep_matrix_mult foldseq_zero zero_imp_mult_zero) | |
| 1745 | done | |
| 1746 | ||
| 27653 | 1747 | lemma add_nrows: "nrows (A::('a::monoid_add) matrix) <= u \<Longrightarrow> nrows B <= u \<Longrightarrow> nrows (A + B) <= u"
 | 
| 14940 | 1748 | apply (simp add: plus_matrix_def) | 
| 1749 | apply (rule combine_nrows) | |
| 1750 | apply (simp_all) | |
| 1751 | done | |
| 1752 | ||
| 34872 | 1753 | lemma move_matrix_row_mult: "move_matrix ((A::('a::semiring_0) matrix) * B) j 0 = (move_matrix A j 0) * B"
 | 
| 14940 | 1754 | apply (subst Rep_matrix_inject[symmetric]) | 
| 1755 | apply (rule ext)+ | |
| 1756 | apply (auto simp add: Rep_matrix_mult foldseq_zero) | |
| 1757 | apply (rule_tac foldseq_zerotail[symmetric]) | |
| 1758 | apply (auto simp add: nrows zero_imp_mult_zero max2) | |
| 1759 | apply (rule order_trans) | |
| 1760 | apply (rule ncols_move_matrix_le) | |
| 1761 | apply (simp add: max1) | |
| 1762 | done | |
| 1763 | ||
| 34872 | 1764 | lemma move_matrix_col_mult: "move_matrix ((A::('a::semiring_0) matrix) * B) 0 i = A * (move_matrix B 0 i)"
 | 
| 14940 | 1765 | apply (subst Rep_matrix_inject[symmetric]) | 
| 1766 | apply (rule ext)+ | |
| 1767 | apply (auto simp add: Rep_matrix_mult foldseq_zero) | |
| 1768 | apply (rule_tac foldseq_zerotail[symmetric]) | |
| 1769 | apply (auto simp add: ncols zero_imp_mult_zero max1) | |
| 1770 | apply (rule order_trans) | |
| 1771 | apply (rule nrows_move_matrix_le) | |
| 1772 | apply (simp add: max2) | |
| 1773 | done | |
| 1774 | ||
| 27653 | 1775 | lemma move_matrix_add: "((move_matrix (A + B) j i)::(('a::monoid_add) matrix)) = (move_matrix A j i) + (move_matrix B j i)" 
 | 
| 14940 | 1776 | apply (subst Rep_matrix_inject[symmetric]) | 
| 1777 | apply (rule ext)+ | |
| 1778 | apply (simp) | |
| 1779 | done | |
| 1780 | ||
| 34872 | 1781 | lemma move_matrix_mult: "move_matrix ((A::('a::semiring_0) matrix)*B) j i = (move_matrix A j 0) * (move_matrix B 0 i)"
 | 
| 14940 | 1782 | by (simp add: move_matrix_ortho[of "A*B"] move_matrix_col_mult move_matrix_row_mult) | 
| 1783 | ||
| 1784 | constdefs | |
| 27653 | 1785 |   scalar_mult :: "('a::ring) \<Rightarrow> 'a matrix \<Rightarrow> 'a matrix"
 | 
| 14940 | 1786 | "scalar_mult a m == apply_matrix (op * a) m" | 
| 1787 | ||
| 1788 | lemma scalar_mult_zero[simp]: "scalar_mult y 0 = 0" | |
| 23477 
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
 nipkow parents: 
22452diff
changeset | 1789 | by (simp add: scalar_mult_def) | 
| 14940 | 1790 | |
| 1791 | lemma scalar_mult_add: "scalar_mult y (a+b) = (scalar_mult y a) + (scalar_mult y b)" | |
| 29667 | 1792 | by (simp add: scalar_mult_def apply_matrix_add algebra_simps) | 
| 14940 | 1793 | |
| 1794 | lemma Rep_scalar_mult[simp]: "Rep_matrix (scalar_mult y a) j i = y * (Rep_matrix a j i)" | |
| 23477 
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
 nipkow parents: 
22452diff
changeset | 1795 | by (simp add: scalar_mult_def) | 
| 14940 | 1796 | |
| 1797 | lemma scalar_mult_singleton[simp]: "scalar_mult y (singleton_matrix j i x) = singleton_matrix j i (y * x)" | |
| 23477 
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
 nipkow parents: 
22452diff
changeset | 1798 | apply (subst Rep_matrix_inject[symmetric]) | 
| 
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
 nipkow parents: 
22452diff
changeset | 1799 | apply (rule ext)+ | 
| 
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
 nipkow parents: 
22452diff
changeset | 1800 | apply (auto) | 
| 
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
 nipkow parents: 
22452diff
changeset | 1801 | done | 
| 14940 | 1802 | |
| 27653 | 1803 | lemma Rep_minus[simp]: "Rep_matrix (-(A::_::group_add)) x y = - (Rep_matrix A x y)" | 
| 23477 
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
 nipkow parents: 
22452diff
changeset | 1804 | by (simp add: minus_matrix_def) | 
| 14940 | 1805 | |
| 35028 
108662d50512
more consistent naming of type classes involving orderings (and lattices) -- c.f. NEWS
 haftmann parents: 
34872diff
changeset | 1806 | lemma Rep_abs[simp]: "Rep_matrix (abs (A::_::lattice_ab_group_add)) x y = abs (Rep_matrix A x y)" | 
| 23477 
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
 nipkow parents: 
22452diff
changeset | 1807 | by (simp add: abs_lattice sup_matrix_def) | 
| 14940 | 1808 | |
| 14593 | 1809 | end |