src/HOL/Analysis/Determinants.thy
changeset 64272 f76b6dda2e56
parent 64267 b9a1486e79be
child 66453 cc19f7ca2ed6
equal deleted inserted replaced
64269:c939cc16b605 64272:f76b6dda2e56
    35 
    35 
    36 text \<open>Definition of determinant.\<close>
    36 text \<open>Definition of determinant.\<close>
    37 
    37 
    38 definition det:: "'a::comm_ring_1^'n^'n \<Rightarrow> 'a" where
    38 definition det:: "'a::comm_ring_1^'n^'n \<Rightarrow> 'a" where
    39   "det A =
    39   "det A =
    40     sum (\<lambda>p. of_int (sign p) * setprod (\<lambda>i. A$i$p i) (UNIV :: 'n set))
    40     sum (\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set))
    41       {p. p permutes (UNIV :: 'n set)}"
    41       {p. p permutes (UNIV :: 'n set)}"
    42 
    42 
    43 text \<open>A few general lemmas we need below.\<close>
    43 text \<open>A few general lemmas we need below.\<close>
    44 
    44 
    45 lemma setprod_permute:
    45 lemma prod_permute:
    46   assumes p: "p permutes S"
    46   assumes p: "p permutes S"
    47   shows "setprod f S = setprod (f \<circ> p) S"
    47   shows "prod f S = prod (f \<circ> p) S"
    48   using assms by (fact setprod.permute)
    48   using assms by (fact prod.permute)
    49 
    49 
    50 lemma setproduct_permute_nat_interval:
    50 lemma product_permute_nat_interval:
    51   fixes m n :: nat
    51   fixes m n :: nat
    52   shows "p permutes {m..n} \<Longrightarrow> setprod f {m..n} = setprod (f \<circ> p) {m..n}"
    52   shows "p permutes {m..n} \<Longrightarrow> prod f {m..n} = prod (f \<circ> p) {m..n}"
    53   by (blast intro!: setprod_permute)
    53   by (blast intro!: prod_permute)
    54 
    54 
    55 text \<open>Basic determinant properties.\<close>
    55 text \<open>Basic determinant properties.\<close>
    56 
    56 
    57 lemma det_transpose: "det (transpose A) = det (A::'a::comm_ring_1 ^'n^'n)"
    57 lemma det_transpose: "det (transpose A) = det (A::'a::comm_ring_1 ^'n^'n)"
    58 proof -
    58 proof -
    68       by (metis sign_inverse fU p mem_Collect_eq permutation_permutes)
    68       by (metis sign_inverse fU p mem_Collect_eq permutation_permutes)
    69     from permutes_inj[OF pU]
    69     from permutes_inj[OF pU]
    70     have pi: "inj_on p ?U"
    70     have pi: "inj_on p ?U"
    71       by (blast intro: subset_inj_on)
    71       by (blast intro: subset_inj_on)
    72     from permutes_image[OF pU]
    72     from permutes_image[OF pU]
    73     have "setprod (\<lambda>i. ?di (transpose A) i (inv p i)) ?U =
    73     have "prod (\<lambda>i. ?di (transpose A) i (inv p i)) ?U =
    74       setprod (\<lambda>i. ?di (transpose A) i (inv p i)) (p ` ?U)"
    74       prod (\<lambda>i. ?di (transpose A) i (inv p i)) (p ` ?U)"
    75       by simp
    75       by simp
    76     also have "\<dots> = setprod ((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) ?U"
    76     also have "\<dots> = prod ((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) ?U"
    77       unfolding setprod.reindex[OF pi] ..
    77       unfolding prod.reindex[OF pi] ..
    78     also have "\<dots> = setprod (\<lambda>i. ?di A i (p i)) ?U"
    78     also have "\<dots> = prod (\<lambda>i. ?di A i (p i)) ?U"
    79     proof -
    79     proof -
    80       {
    80       {
    81         fix i
    81         fix i
    82         assume i: "i \<in> ?U"
    82         assume i: "i \<in> ?U"
    83         from i permutes_inv_o[OF pU] permutes_in_image[OF pU]
    83         from i permutes_inv_o[OF pU] permutes_in_image[OF pU]
    84         have "((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) i = ?di A i (p i)"
    84         have "((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) i = ?di A i (p i)"
    85           unfolding transpose_def by (simp add: fun_eq_iff)
    85           unfolding transpose_def by (simp add: fun_eq_iff)
    86       }
    86       }
    87       then show "setprod ((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) ?U =
    87       then show "prod ((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) ?U =
    88         setprod (\<lambda>i. ?di A i (p i)) ?U"
    88         prod (\<lambda>i. ?di A i (p i)) ?U"
    89         by (auto intro: setprod.cong)
    89         by (auto intro: prod.cong)
    90     qed
    90     qed
    91     finally have "of_int (sign (inv p)) * (setprod (\<lambda>i. ?di (transpose A) i (inv p i)) ?U) =
    91     finally have "of_int (sign (inv p)) * (prod (\<lambda>i. ?di (transpose A) i (inv p i)) ?U) =
    92       of_int (sign p) * (setprod (\<lambda>i. ?di A i (p i)) ?U)"
    92       of_int (sign p) * (prod (\<lambda>i. ?di A i (p i)) ?U)"
    93       using sth by simp
    93       using sth by simp
    94   }
    94   }
    95   then show ?thesis
    95   then show ?thesis
    96     unfolding det_def
    96     unfolding det_def
    97     apply (subst sum_permutations_inverse)
    97     apply (subst sum_permutations_inverse)
   102 qed
   102 qed
   103 
   103 
   104 lemma det_lowerdiagonal:
   104 lemma det_lowerdiagonal:
   105   fixes A :: "'a::comm_ring_1^('n::{finite,wellorder})^('n::{finite,wellorder})"
   105   fixes A :: "'a::comm_ring_1^('n::{finite,wellorder})^('n::{finite,wellorder})"
   106   assumes ld: "\<And>i j. i < j \<Longrightarrow> A$i$j = 0"
   106   assumes ld: "\<And>i j. i < j \<Longrightarrow> A$i$j = 0"
   107   shows "det A = setprod (\<lambda>i. A$i$i) (UNIV:: 'n set)"
   107   shows "det A = prod (\<lambda>i. A$i$i) (UNIV:: 'n set)"
   108 proof -
   108 proof -
   109   let ?U = "UNIV:: 'n set"
   109   let ?U = "UNIV:: 'n set"
   110   let ?PU = "{p. p permutes ?U}"
   110   let ?PU = "{p. p permutes ?U}"
   111   let ?pp = "\<lambda>p. of_int (sign p) * setprod (\<lambda>i. A$i$p i) (UNIV :: 'n set)"
   111   let ?pp = "\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set)"
   112   have fU: "finite ?U"
   112   have fU: "finite ?U"
   113     by simp
   113     by simp
   114   from finite_permutations[OF fU] have fPU: "finite ?PU" .
   114   from finite_permutations[OF fU] have fPU: "finite ?PU" .
   115   have id0: "{id} \<subseteq> ?PU"
   115   have id0: "{id} \<subseteq> ?PU"
   116     by (auto simp add: permutes_id)
   116     by (auto simp add: permutes_id)
   121       by blast+
   121       by blast+
   122     from permutes_natset_le[OF pU] pid obtain i where i: "p i > i"
   122     from permutes_natset_le[OF pU] pid obtain i where i: "p i > i"
   123       by (metis not_le)
   123       by (metis not_le)
   124     from ld[OF i] have ex:"\<exists>i \<in> ?U. A$i$p i = 0"
   124     from ld[OF i] have ex:"\<exists>i \<in> ?U. A$i$p i = 0"
   125       by blast
   125       by blast
   126     from setprod_zero[OF fU ex] have "?pp p = 0"
   126     from prod_zero[OF fU ex] have "?pp p = 0"
   127       by simp
   127       by simp
   128   }
   128   }
   129   then have p0: "\<forall>p \<in> ?PU - {id}. ?pp p = 0"
   129   then have p0: "\<forall>p \<in> ?PU - {id}. ?pp p = 0"
   130     by blast
   130     by blast
   131   from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis
   131   from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis
   133 qed
   133 qed
   134 
   134 
   135 lemma det_upperdiagonal:
   135 lemma det_upperdiagonal:
   136   fixes A :: "'a::comm_ring_1^'n::{finite,wellorder}^'n::{finite,wellorder}"
   136   fixes A :: "'a::comm_ring_1^'n::{finite,wellorder}^'n::{finite,wellorder}"
   137   assumes ld: "\<And>i j. i > j \<Longrightarrow> A$i$j = 0"
   137   assumes ld: "\<And>i j. i > j \<Longrightarrow> A$i$j = 0"
   138   shows "det A = setprod (\<lambda>i. A$i$i) (UNIV:: 'n set)"
   138   shows "det A = prod (\<lambda>i. A$i$i) (UNIV:: 'n set)"
   139 proof -
   139 proof -
   140   let ?U = "UNIV:: 'n set"
   140   let ?U = "UNIV:: 'n set"
   141   let ?PU = "{p. p permutes ?U}"
   141   let ?PU = "{p. p permutes ?U}"
   142   let ?pp = "(\<lambda>p. of_int (sign p) * setprod (\<lambda>i. A$i$p i) (UNIV :: 'n set))"
   142   let ?pp = "(\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set))"
   143   have fU: "finite ?U"
   143   have fU: "finite ?U"
   144     by simp
   144     by simp
   145   from finite_permutations[OF fU] have fPU: "finite ?PU" .
   145   from finite_permutations[OF fU] have fPU: "finite ?PU" .
   146   have id0: "{id} \<subseteq> ?PU"
   146   have id0: "{id} \<subseteq> ?PU"
   147     by (auto simp add: permutes_id)
   147     by (auto simp add: permutes_id)
   152       by blast+
   152       by blast+
   153     from permutes_natset_ge[OF pU] pid obtain i where i: "p i < i"
   153     from permutes_natset_ge[OF pU] pid obtain i where i: "p i < i"
   154       by (metis not_le)
   154       by (metis not_le)
   155     from ld[OF i] have ex:"\<exists>i \<in> ?U. A$i$p i = 0"
   155     from ld[OF i] have ex:"\<exists>i \<in> ?U. A$i$p i = 0"
   156       by blast
   156       by blast
   157     from setprod_zero[OF fU ex] have "?pp p = 0"
   157     from prod_zero[OF fU ex] have "?pp p = 0"
   158       by simp
   158       by simp
   159   }
   159   }
   160   then have p0: "\<forall>p \<in> ?PU -{id}. ?pp p = 0"
   160   then have p0: "\<forall>p \<in> ?PU -{id}. ?pp p = 0"
   161     by blast
   161     by blast
   162   from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis
   162   from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis
   164 qed
   164 qed
   165 
   165 
   166 lemma det_diagonal:
   166 lemma det_diagonal:
   167   fixes A :: "'a::comm_ring_1^'n^'n"
   167   fixes A :: "'a::comm_ring_1^'n^'n"
   168   assumes ld: "\<And>i j. i \<noteq> j \<Longrightarrow> A$i$j = 0"
   168   assumes ld: "\<And>i j. i \<noteq> j \<Longrightarrow> A$i$j = 0"
   169   shows "det A = setprod (\<lambda>i. A$i$i) (UNIV::'n set)"
   169   shows "det A = prod (\<lambda>i. A$i$i) (UNIV::'n set)"
   170 proof -
   170 proof -
   171   let ?U = "UNIV:: 'n set"
   171   let ?U = "UNIV:: 'n set"
   172   let ?PU = "{p. p permutes ?U}"
   172   let ?PU = "{p. p permutes ?U}"
   173   let ?pp = "\<lambda>p. of_int (sign p) * setprod (\<lambda>i. A$i$p i) (UNIV :: 'n set)"
   173   let ?pp = "\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set)"
   174   have fU: "finite ?U" by simp
   174   have fU: "finite ?U" by simp
   175   from finite_permutations[OF fU] have fPU: "finite ?PU" .
   175   from finite_permutations[OF fU] have fPU: "finite ?PU" .
   176   have id0: "{id} \<subseteq> ?PU"
   176   have id0: "{id} \<subseteq> ?PU"
   177     by (auto simp add: permutes_id)
   177     by (auto simp add: permutes_id)
   178   {
   178   {
   182       by simp
   182       by simp
   183     then obtain i where i: "p i \<noteq> i"
   183     then obtain i where i: "p i \<noteq> i"
   184       unfolding fun_eq_iff by auto
   184       unfolding fun_eq_iff by auto
   185     from ld [OF i [symmetric]] have ex:"\<exists>i \<in> ?U. A$i$p i = 0"
   185     from ld [OF i [symmetric]] have ex:"\<exists>i \<in> ?U. A$i$p i = 0"
   186       by blast
   186       by blast
   187     from setprod_zero [OF fU ex] have "?pp p = 0"
   187     from prod_zero [OF fU ex] have "?pp p = 0"
   188       by simp
   188       by simp
   189   }
   189   }
   190   then have p0: "\<forall>p \<in> ?PU - {id}. ?pp p = 0"
   190   then have p0: "\<forall>p \<in> ?PU - {id}. ?pp p = 0"
   191     by blast
   191     by blast
   192   from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis
   192   from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis
   202     fix i
   202     fix i
   203     assume i: "i \<in> ?U"
   203     assume i: "i \<in> ?U"
   204     have "?f i i = 1"
   204     have "?f i i = 1"
   205       using i by (vector mat_def)
   205       using i by (vector mat_def)
   206   }
   206   }
   207   then have th: "setprod (\<lambda>i. ?f i i) ?U = setprod (\<lambda>x. 1) ?U"
   207   then have th: "prod (\<lambda>i. ?f i i) ?U = prod (\<lambda>x. 1) ?U"
   208     by (auto intro: setprod.cong)
   208     by (auto intro: prod.cong)
   209   {
   209   {
   210     fix i j
   210     fix i j
   211     assume i: "i \<in> ?U" and j: "j \<in> ?U" and ij: "i \<noteq> j"
   211     assume i: "i \<in> ?U" and j: "j \<in> ?U" and ij: "i \<noteq> j"
   212     have "?f i j = 0" using i j ij
   212     have "?f i j = 0" using i j ij
   213       by (vector mat_def)
   213       by (vector mat_def)
   214   }
   214   }
   215   then have "det ?A = setprod (\<lambda>i. ?f i i) ?U"
   215   then have "det ?A = prod (\<lambda>i. ?f i i) ?U"
   216     using det_diagonal by blast
   216     using det_diagonal by blast
   217   also have "\<dots> = 1"
   217   also have "\<dots> = 1"
   218     unfolding th setprod.neutral_const ..
   218     unfolding th prod.neutral_const ..
   219   finally show ?thesis .
   219   finally show ?thesis .
   220 qed
   220 qed
   221 
   221 
   222 lemma det_0: "det (mat 0 :: 'a::comm_ring_1^'n^'n) = 0"
   222 lemma det_0: "det (mat 0 :: 'a::comm_ring_1^'n^'n) = 0"
   223   by (simp add: det_def setprod_zero)
   223   by (simp add: det_def prod_zero)
   224 
   224 
   225 lemma det_permute_rows:
   225 lemma det_permute_rows:
   226   fixes A :: "'a::comm_ring_1^'n^'n"
   226   fixes A :: "'a::comm_ring_1^'n^'n"
   227   assumes p: "p permutes (UNIV :: 'n::finite set)"
   227   assumes p: "p permutes (UNIV :: 'n::finite set)"
   228   shows "det (\<chi> i. A$p i :: 'a^'n^'n) = of_int (sign p) * det A"
   228   shows "det (\<chi> i. A$p i :: 'a^'n^'n) = of_int (sign p) * det A"
   238   from qPU have q: "q permutes ?U"
   238   from qPU have q: "q permutes ?U"
   239     by blast
   239     by blast
   240   from p q have pp: "permutation p" and qp: "permutation q"
   240   from p q have pp: "permutation p" and qp: "permutation q"
   241     by (metis fU permutation_permutes)+
   241     by (metis fU permutation_permutes)+
   242   from permutes_inv[OF p] have ip: "inv p permutes ?U" .
   242   from permutes_inv[OF p] have ip: "inv p permutes ?U" .
   243   have "setprod (\<lambda>i. A$p i$ (q \<circ> p) i) ?U = setprod ((\<lambda>i. A$p i$(q \<circ> p) i) \<circ> inv p) ?U"
   243   have "prod (\<lambda>i. A$p i$ (q \<circ> p) i) ?U = prod ((\<lambda>i. A$p i$(q \<circ> p) i) \<circ> inv p) ?U"
   244     by (simp only: setprod_permute[OF ip, symmetric])
   244     by (simp only: prod_permute[OF ip, symmetric])
   245   also have "\<dots> = setprod (\<lambda>i. A $ (p \<circ> inv p) i $ (q \<circ> (p \<circ> inv p)) i) ?U"
   245   also have "\<dots> = prod (\<lambda>i. A $ (p \<circ> inv p) i $ (q \<circ> (p \<circ> inv p)) i) ?U"
   246     by (simp only: o_def)
   246     by (simp only: o_def)
   247   also have "\<dots> = setprod (\<lambda>i. A$i$q i) ?U"
   247   also have "\<dots> = prod (\<lambda>i. A$i$q i) ?U"
   248     by (simp only: o_def permutes_inverses[OF p])
   248     by (simp only: o_def permutes_inverses[OF p])
   249   finally have thp: "setprod (\<lambda>i. A$p i$ (q \<circ> p) i) ?U = setprod (\<lambda>i. A$i$q i) ?U"
   249   finally have thp: "prod (\<lambda>i. A$p i$ (q \<circ> p) i) ?U = prod (\<lambda>i. A$i$q i) ?U"
   250     by blast
   250     by blast
   251   show "of_int (sign (q \<circ> p)) * setprod (\<lambda>i. A$ p i$ (q \<circ> p) i) ?U =
   251   show "of_int (sign (q \<circ> p)) * prod (\<lambda>i. A$ p i$ (q \<circ> p) i) ?U =
   252     of_int (sign p) * of_int (sign q) * setprod (\<lambda>i. A$i$q i) ?U"
   252     of_int (sign p) * of_int (sign q) * prod (\<lambda>i. A$i$q i) ?U"
   253     by (simp only: thp sign_compose[OF qp pp] mult.commute of_int_mult)
   253     by (simp only: thp sign_compose[OF qp pp] mult.commute of_int_mult)
   254 qed rule
   254 qed rule
   255 
   255 
   256 lemma det_permute_columns:
   256 lemma det_permute_columns:
   257   fixes A :: "'a::comm_ring_1^'n^'n"
   257   fixes A :: "'a::comm_ring_1^'n^'n"
   339     fix j
   339     fix j
   340     assume j: "j \<in> ?Uk"
   340     assume j: "j \<in> ?Uk"
   341     from j have "?f j $ p j = ?g j $ p j" and "?f j $ p j= ?h j $ p j"
   341     from j have "?f j $ p j = ?g j $ p j" and "?f j $ p j= ?h j $ p j"
   342       by simp_all
   342       by simp_all
   343   }
   343   }
   344   then have th1: "setprod (\<lambda>i. ?f i $ p i) ?Uk = setprod (\<lambda>i. ?g i $ p i) ?Uk"
   344   then have th1: "prod (\<lambda>i. ?f i $ p i) ?Uk = prod (\<lambda>i. ?g i $ p i) ?Uk"
   345     and th2: "setprod (\<lambda>i. ?f i $ p i) ?Uk = setprod (\<lambda>i. ?h i $ p i) ?Uk"
   345     and th2: "prod (\<lambda>i. ?f i $ p i) ?Uk = prod (\<lambda>i. ?h i $ p i) ?Uk"
   346     apply -
   346     apply -
   347     apply (rule setprod.cong, simp_all)+
   347     apply (rule prod.cong, simp_all)+
   348     done
   348     done
   349   have th3: "finite ?Uk" "k \<notin> ?Uk"
   349   have th3: "finite ?Uk" "k \<notin> ?Uk"
   350     by auto
   350     by auto
   351   have "setprod (\<lambda>i. ?f i $ p i) ?U = setprod (\<lambda>i. ?f i $ p i) (insert k ?Uk)"
   351   have "prod (\<lambda>i. ?f i $ p i) ?U = prod (\<lambda>i. ?f i $ p i) (insert k ?Uk)"
   352     unfolding kU[symmetric] ..
   352     unfolding kU[symmetric] ..
   353   also have "\<dots> = ?f k $ p k * setprod (\<lambda>i. ?f i $ p i) ?Uk"
   353   also have "\<dots> = ?f k $ p k * prod (\<lambda>i. ?f i $ p i) ?Uk"
   354     apply (rule setprod.insert)
   354     apply (rule prod.insert)
   355     apply simp
   355     apply simp
   356     apply blast
   356     apply blast
   357     done
   357     done
   358   also have "\<dots> = (a k $ p k * setprod (\<lambda>i. ?f i $ p i) ?Uk) + (b k$ p k * setprod (\<lambda>i. ?f i $ p i) ?Uk)"
   358   also have "\<dots> = (a k $ p k * prod (\<lambda>i. ?f i $ p i) ?Uk) + (b k$ p k * prod (\<lambda>i. ?f i $ p i) ?Uk)"
   359     by (simp add: field_simps)
   359     by (simp add: field_simps)
   360   also have "\<dots> = (a k $ p k * setprod (\<lambda>i. ?g i $ p i) ?Uk) + (b k$ p k * setprod (\<lambda>i. ?h i $ p i) ?Uk)"
   360   also have "\<dots> = (a k $ p k * prod (\<lambda>i. ?g i $ p i) ?Uk) + (b k$ p k * prod (\<lambda>i. ?h i $ p i) ?Uk)"
   361     by (metis th1 th2)
   361     by (metis th1 th2)
   362   also have "\<dots> = setprod (\<lambda>i. ?g i $ p i) (insert k ?Uk) + setprod (\<lambda>i. ?h i $ p i) (insert k ?Uk)"
   362   also have "\<dots> = prod (\<lambda>i. ?g i $ p i) (insert k ?Uk) + prod (\<lambda>i. ?h i $ p i) (insert k ?Uk)"
   363     unfolding  setprod.insert[OF th3] by simp
   363     unfolding  prod.insert[OF th3] by simp
   364   finally have "setprod (\<lambda>i. ?f i $ p i) ?U = setprod (\<lambda>i. ?g i $ p i) ?U + setprod (\<lambda>i. ?h i $ p i) ?U"
   364   finally have "prod (\<lambda>i. ?f i $ p i) ?U = prod (\<lambda>i. ?g i $ p i) ?U + prod (\<lambda>i. ?h i $ p i) ?U"
   365     unfolding kU[symmetric] .
   365     unfolding kU[symmetric] .
   366   then show "of_int (sign p) * setprod (\<lambda>i. ?f i $ p i) ?U =
   366   then show "of_int (sign p) * prod (\<lambda>i. ?f i $ p i) ?U =
   367     of_int (sign p) * setprod (\<lambda>i. ?g i $ p i) ?U + of_int (sign p) * setprod (\<lambda>i. ?h i $ p i) ?U"
   367     of_int (sign p) * prod (\<lambda>i. ?g i $ p i) ?U + of_int (sign p) * prod (\<lambda>i. ?h i $ p i) ?U"
   368     by (simp add: field_simps)
   368     by (simp add: field_simps)
   369 qed rule
   369 qed rule
   370 
   370 
   371 lemma det_row_mul:
   371 lemma det_row_mul:
   372   fixes a b :: "'n::finite \<Rightarrow> _ ^ 'n"
   372   fixes a b :: "'n::finite \<Rightarrow> _ ^ 'n"
   389     fix j
   389     fix j
   390     assume j: "j \<in> ?Uk"
   390     assume j: "j \<in> ?Uk"
   391     from j have "?f j $ p j = ?g j $ p j"
   391     from j have "?f j $ p j = ?g j $ p j"
   392       by simp
   392       by simp
   393   }
   393   }
   394   then have th1: "setprod (\<lambda>i. ?f i $ p i) ?Uk = setprod (\<lambda>i. ?g i $ p i) ?Uk"
   394   then have th1: "prod (\<lambda>i. ?f i $ p i) ?Uk = prod (\<lambda>i. ?g i $ p i) ?Uk"
   395     apply -
   395     apply -
   396     apply (rule setprod.cong)
   396     apply (rule prod.cong)
   397     apply simp_all
   397     apply simp_all
   398     done
   398     done
   399   have th3: "finite ?Uk" "k \<notin> ?Uk"
   399   have th3: "finite ?Uk" "k \<notin> ?Uk"
   400     by auto
   400     by auto
   401   have "setprod (\<lambda>i. ?f i $ p i) ?U = setprod (\<lambda>i. ?f i $ p i) (insert k ?Uk)"
   401   have "prod (\<lambda>i. ?f i $ p i) ?U = prod (\<lambda>i. ?f i $ p i) (insert k ?Uk)"
   402     unfolding kU[symmetric] ..
   402     unfolding kU[symmetric] ..
   403   also have "\<dots> = ?f k $ p k  * setprod (\<lambda>i. ?f i $ p i) ?Uk"
   403   also have "\<dots> = ?f k $ p k  * prod (\<lambda>i. ?f i $ p i) ?Uk"
   404     apply (rule setprod.insert)
   404     apply (rule prod.insert)
   405     apply simp
   405     apply simp
   406     apply blast
   406     apply blast
   407     done
   407     done
   408   also have "\<dots> = (c*s a k) $ p k * setprod (\<lambda>i. ?f i $ p i) ?Uk"
   408   also have "\<dots> = (c*s a k) $ p k * prod (\<lambda>i. ?f i $ p i) ?Uk"
   409     by (simp add: field_simps)
   409     by (simp add: field_simps)
   410   also have "\<dots> = c* (a k $ p k * setprod (\<lambda>i. ?g i $ p i) ?Uk)"
   410   also have "\<dots> = c* (a k $ p k * prod (\<lambda>i. ?g i $ p i) ?Uk)"
   411     unfolding th1 by (simp add: ac_simps)
   411     unfolding th1 by (simp add: ac_simps)
   412   also have "\<dots> = c* (setprod (\<lambda>i. ?g i $ p i) (insert k ?Uk))"
   412   also have "\<dots> = c* (prod (\<lambda>i. ?g i $ p i) (insert k ?Uk))"
   413     unfolding setprod.insert[OF th3] by simp
   413     unfolding prod.insert[OF th3] by simp
   414   finally have "setprod (\<lambda>i. ?f i $ p i) ?U = c* (setprod (\<lambda>i. ?g i $ p i) ?U)"
   414   finally have "prod (\<lambda>i. ?f i $ p i) ?U = c* (prod (\<lambda>i. ?g i $ p i) ?U)"
   415     unfolding kU[symmetric] .
   415     unfolding kU[symmetric] .
   416   then show "of_int (sign p) * setprod (\<lambda>i. ?f i $ p i) ?U =
   416   then show "of_int (sign p) * prod (\<lambda>i. ?f i $ p i) ?U =
   417     c * (of_int (sign p) * setprod (\<lambda>i. ?g i $ p i) ?U)"
   417     c * (of_int (sign p) * prod (\<lambda>i. ?g i $ p i) ?U)"
   418     by (simp add: field_simps)
   418     by (simp add: field_simps)
   419 qed rule
   419 qed rule
   420 
   420 
   421 lemma det_row_0:
   421 lemma det_row_0:
   422   fixes b :: "'n::finite \<Rightarrow> _ ^ 'n"
   422   fixes b :: "'n::finite \<Rightarrow> _ ^ 'n"
   642   shows "A ** B = (\<chi> i. sum (\<lambda>k. A$i$k *s B $ k) (UNIV :: 'n set))"
   642   shows "A ** B = (\<chi> i. sum (\<lambda>k. A$i$k *s B $ k) (UNIV :: 'n set))"
   643   by (vector matrix_matrix_mult_def sum_component)
   643   by (vector matrix_matrix_mult_def sum_component)
   644 
   644 
   645 lemma det_rows_mul:
   645 lemma det_rows_mul:
   646   "det((\<chi> i. c i *s a i)::'a::comm_ring_1^'n^'n) =
   646   "det((\<chi> i. c i *s a i)::'a::comm_ring_1^'n^'n) =
   647     setprod (\<lambda>i. c i) (UNIV:: 'n set) * det((\<chi> i. a i)::'a^'n^'n)"
   647     prod (\<lambda>i. c i) (UNIV:: 'n set) * det((\<chi> i. a i)::'a^'n^'n)"
   648 proof (simp add: det_def sum_distrib_left cong add: setprod.cong, rule sum.cong)
   648 proof (simp add: det_def sum_distrib_left cong add: prod.cong, rule sum.cong)
   649   let ?U = "UNIV :: 'n set"
   649   let ?U = "UNIV :: 'n set"
   650   let ?PU = "{p. p permutes ?U}"
   650   let ?PU = "{p. p permutes ?U}"
   651   fix p
   651   fix p
   652   assume pU: "p \<in> ?PU"
   652   assume pU: "p \<in> ?PU"
   653   let ?s = "of_int (sign p)"
   653   let ?s = "of_int (sign p)"
   654   from pU have p: "p permutes ?U"
   654   from pU have p: "p permutes ?U"
   655     by blast
   655     by blast
   656   have "setprod (\<lambda>i. c i * a i $ p i) ?U = setprod c ?U * setprod (\<lambda>i. a i $ p i) ?U"
   656   have "prod (\<lambda>i. c i * a i $ p i) ?U = prod c ?U * prod (\<lambda>i. a i $ p i) ?U"
   657     unfolding setprod.distrib ..
   657     unfolding prod.distrib ..
   658   then show "?s * (\<Prod>xa\<in>?U. c xa * a xa $ p xa) =
   658   then show "?s * (\<Prod>xa\<in>?U. c xa * a xa $ p xa) =
   659     setprod c ?U * (?s* (\<Prod>xa\<in>?U. a xa $ p xa))"
   659     prod c ?U * (?s* (\<Prod>xa\<in>?U. a xa $ p xa))"
   660     by (simp add: field_simps)
   660     by (simp add: field_simps)
   661 qed rule
   661 qed rule
   662 
   662 
   663 lemma det_mul:
   663 lemma det_mul:
   664   fixes A B :: "'a::linordered_idom^'n^'n"
   664   fixes A B :: "'a::linordered_idom^'n^'n"
   752         unfolding of_int_mult[symmetric]
   752         unfolding of_int_mult[symmetric]
   753         by (simp_all add: sign_idempotent)
   753         by (simp_all add: sign_idempotent)
   754       have ths: "?s q = ?s p * ?s (q \<circ> inv p)"
   754       have ths: "?s q = ?s p * ?s (q \<circ> inv p)"
   755         using pp pq permutation_inverse[OF pp] sign_inverse[OF pp]
   755         using pp pq permutation_inverse[OF pp] sign_inverse[OF pp]
   756         by (simp add:  th00 ac_simps sign_idempotent sign_compose)
   756         by (simp add:  th00 ac_simps sign_idempotent sign_compose)
   757       have th001: "setprod (\<lambda>i. B$i$ q (inv p i)) ?U = setprod ((\<lambda>i. B$i$ q (inv p i)) \<circ> p) ?U"
   757       have th001: "prod (\<lambda>i. B$i$ q (inv p i)) ?U = prod ((\<lambda>i. B$i$ q (inv p i)) \<circ> p) ?U"
   758         by (rule setprod_permute[OF p])
   758         by (rule prod_permute[OF p])
   759       have thp: "setprod (\<lambda>i. (\<chi> i. A$i$p i *s B$p i :: 'a^'n^'n) $i $ q i) ?U =
   759       have thp: "prod (\<lambda>i. (\<chi> i. A$i$p i *s B$p i :: 'a^'n^'n) $i $ q i) ?U =
   760         setprod (\<lambda>i. A$i$p i) ?U * setprod (\<lambda>i. B$i$ q (inv p i)) ?U"
   760         prod (\<lambda>i. A$i$p i) ?U * prod (\<lambda>i. B$i$ q (inv p i)) ?U"
   761         unfolding th001 setprod.distrib[symmetric] o_def permutes_inverses[OF p]
   761         unfolding th001 prod.distrib[symmetric] o_def permutes_inverses[OF p]
   762         apply (rule setprod.cong[OF refl])
   762         apply (rule prod.cong[OF refl])
   763         using permutes_in_image[OF q]
   763         using permutes_in_image[OF q]
   764         apply vector
   764         apply vector
   765         done
   765         done
   766       show "?s q * setprod (\<lambda>i. (((\<chi> i. A$i$p i *s B$p i) :: 'a^'n^'n)$i$q i)) ?U =
   766       show "?s q * prod (\<lambda>i. (((\<chi> i. A$i$p i *s B$p i) :: 'a^'n^'n)$i$q i)) ?U =
   767         ?s p * (setprod (\<lambda>i. A$i$p i) ?U) * (?s (q \<circ> inv p) * setprod (\<lambda>i. B$i$(q \<circ> inv p) i) ?U)"
   767         ?s p * (prod (\<lambda>i. A$i$p i) ?U) * (?s (q \<circ> inv p) * prod (\<lambda>i. B$i$(q \<circ> inv p) i) ?U)"
   768         using ths thp pp pq permutation_inverse[OF pp] sign_inverse[OF pp]
   768         using ths thp pp pq permutation_inverse[OF pp] sign_inverse[OF pp]
   769         by (simp add: sign_nz th00 field_simps sign_idempotent sign_compose)
   769         by (simp add: sign_nz th00 field_simps sign_idempotent sign_compose)
   770     qed rule
   770     qed rule
   771   }
   771   }
   772   then have th2: "sum (\<lambda>f. det (\<chi> i. A$i$f i *s B$f i)) ?PU = det A * det B"
   772   then have th2: "sum (\<lambda>f. det (\<chi> i. A$i$f i *s B$f i)) ?PU = det A * det B"
  1200   shows " orthogonal_matrix Q \<longleftrightarrow> rotation_matrix Q \<or> rotoinversion_matrix Q"
  1200   shows " orthogonal_matrix Q \<longleftrightarrow> rotation_matrix Q \<or> rotoinversion_matrix Q"
  1201   by (metis rotoinversion_matrix_def rotation_matrix_def det_orthogonal_matrix)
  1201   by (metis rotoinversion_matrix_def rotation_matrix_def det_orthogonal_matrix)
  1202 
  1202 
  1203 text \<open>Explicit formulas for low dimensions.\<close>
  1203 text \<open>Explicit formulas for low dimensions.\<close>
  1204 
  1204 
  1205 lemma setprod_neutral_const: "setprod f {(1::nat)..1} = f 1"
  1205 lemma prod_neutral_const: "prod f {(1::nat)..1} = f 1"
  1206   by simp
  1206   by simp
  1207 
  1207 
  1208 lemma setprod_2: "setprod f {(1::nat)..2} = f 1 * f 2"
  1208 lemma prod_2: "prod f {(1::nat)..2} = f 1 * f 2"
  1209   by (simp add: eval_nat_numeral atLeastAtMostSuc_conv mult.commute)
  1209   by (simp add: eval_nat_numeral atLeastAtMostSuc_conv mult.commute)
  1210 
  1210 
  1211 lemma setprod_3: "setprod f {(1::nat)..3} = f 1 * f 2 * f 3"
  1211 lemma prod_3: "prod f {(1::nat)..3} = f 1 * f 2 * f 3"
  1212   by (simp add: eval_nat_numeral atLeastAtMostSuc_conv mult.commute)
  1212   by (simp add: eval_nat_numeral atLeastAtMostSuc_conv mult.commute)
  1213 
  1213 
  1214 lemma det_1: "det (A::'a::comm_ring_1^1^1) = A$1$1"
  1214 lemma det_1: "det (A::'a::comm_ring_1^1^1) = A$1$1"
  1215   by (simp add: det_def of_nat_Suc sign_id)
  1215   by (simp add: det_def of_nat_Suc sign_id)
  1216 
  1216