[STATEMENT]
lemma rref_and_index_Gauss_Jordan_upt_k:
  fixes A::"'a::{field}^'columns::{mod_type}^'rows::{mod_type}" and k::nat
  assumes  "k < ncols A"
  shows rref_Gauss_Jordan_upt_k: "reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k)"
  and snd_Gauss_Jordan_upt_k:
  "foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] =
  (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0
  else to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1,
  snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k) &&& foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))
[PROOF STEP]
using assms
[PROOF STATE]
proof (prove)
using this:
k < ncols A

goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k) &&& foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))
[PROOF STEP]
proof (induct k)
    \<comment> \<open>Two base cases, one for each show\<close>
    \<comment> \<open>The first one\<close>
[PROOF STATE]
proof (state)
goal (4 subgoals):
 1. 0 < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A 0) (Suc 0)
 2. 0 < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0] = (if \<forall>m. is_zero_row_upt_k m (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))
 3. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))
 4. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
show "reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A 0) (Suc 0)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A 0) (Suc 0)
[PROOF STEP]
unfolding Gauss_Jordan_upt_k_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0])) (Suc 0)
[PROOF STEP]
apply auto
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (snd (Gauss_Jordan_column_k (0, A) 0)) (Suc 0)
[PROOF STEP]
using reduced_row_echelon_form_upt_k_Gauss_Jordan_column_k[OF rref_upt_0, of A]
[PROOF STATE]
proof (prove)
using this:
reduced_row_echelon_form_upt_k (snd (Gauss_Jordan_column_k (if \<forall>m. is_zero_row_upt_k m 0 A then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n 0 A) + 1, A) 0)) (Suc 0)

goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (snd (Gauss_Jordan_column_k (0, A) 0)) (Suc 0)
[PROOF STEP]
using is_zero_row_utp_0'[of A]
[PROOF STATE]
proof (prove)
using this:
reduced_row_echelon_form_upt_k (snd (Gauss_Jordan_column_k (if \<forall>m. is_zero_row_upt_k m 0 A then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n 0 A) + 1, A) 0)) (Suc 0)
\<forall>m. is_zero_row_upt_k m 0 A

goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (snd (Gauss_Jordan_column_k (0, A) 0)) (Suc 0)
[PROOF STEP]
by simp
      \<comment> \<open>The second base case\<close>
[PROOF STATE]
proof (state)
this:
reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A 0) (Suc 0)

goal (3 subgoals):
 1. 0 < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0] = (if \<forall>m. is_zero_row_upt_k m (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))
 2. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))
 3. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
have rw_upt: "[0..<Suc 0] = [0]"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. [0..<Suc 0] = [0]
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
[0..<Suc 0] = [0]

goal (3 subgoals):
 1. 0 < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0] = (if \<forall>m. is_zero_row_upt_k m (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))
 2. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))
 3. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
show "foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0] =
    (if \<forall>m. is_zero_row_upt_k m (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0])) then 0
    else to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))) + 1,
    snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0] = (if \<forall>m. is_zero_row_upt_k m (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))
[PROOF STEP]
unfolding rw_upt
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. foldl Gauss_Jordan_column_k (0, A) [0] = (if \<forall>m. is_zero_row_upt_k m (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0]))
[PROOF STEP]
unfolding foldl.simps
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. Gauss_Jordan_column_k (0, A) 0 = (if \<forall>m. is_zero_row_upt_k m (Suc 0) (snd (Gauss_Jordan_column_k (0, A) 0)) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc 0) (snd (Gauss_Jordan_column_k (0, A) 0))) + 1, snd (Gauss_Jordan_column_k (0, A) 0))
[PROOF STEP]
unfolding Gauss_Jordan_column_k_def Let_def from_nat_0 fst_conv snd_conv
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (if (\<forall>m\<ge>0::'rows. A $ m $ (0::'columns) = (0::'a)) \<or> 0 = nrows A then (0, A) else (0 + 1, Gauss_Jordan_in_ij A (0::'rows) (0::'columns))) = (if \<forall>m. is_zero_row_upt_k m (Suc 0) (snd (if (\<forall>m\<ge>0::'rows. A $ m $ (0::'columns) = (0::'a)) \<or> 0 = nrows A then (0, A) else (0 + 1, Gauss_Jordan_in_ij A (0::'rows) (0::'columns)))) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc 0) (snd (if (\<forall>m\<ge>0::'rows. A $ m $ (0::'columns) = (0::'a)) \<or> 0 = nrows A then (0, A) else (0 + 1, Gauss_Jordan_in_ij A (0::'rows) (0::'columns))))) + 1, snd (if (\<forall>m\<ge>0::'rows. A $ m $ (0::'columns) = (0::'a)) \<or> 0 = nrows A then (0, A) else (0 + 1, Gauss_Jordan_in_ij A (0::'rows) (0::'columns))))
[PROOF STEP]
unfolding is_zero_row_upt_k_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (if (\<forall>m\<ge>0::'rows. A $ m $ (0::'columns) = (0::'a)) \<or> 0 = nrows A then (0, A) else (0 + 1, Gauss_Jordan_in_ij A (0::'rows) (0::'columns))) = (if \<forall>m j. mod_type_class.to_nat j < Suc 0 \<longrightarrow> snd (if (\<forall>m\<ge>0::'rows. A $ m $ (0::'columns) = (0::'a)) \<or> 0 = nrows A then (0, A) else (0 + 1, Gauss_Jordan_in_ij A (0::'rows) (0::'columns))) $ m $ j = (0::'a) then 0 else mod_type_class.to_nat (GREATEST n. \<not> (\<forall>j. mod_type_class.to_nat j < Suc 0 \<longrightarrow> snd (if (\<forall>m\<ge>0::'rows. A $ m $ (0::'columns) = (0::'a)) \<or> 0 = nrows A then (0, A) else (0 + 1, Gauss_Jordan_in_ij A (0::'rows) (0::'columns))) $ n $ j = (0::'a))) + 1, snd (if (\<forall>m\<ge>0::'rows. A $ m $ (0::'columns) = (0::'a)) \<or> 0 = nrows A then (0, A) else (0 + 1, Gauss_Jordan_in_ij A (0::'rows) (0::'columns))))
[PROOF STEP]
apply (auto simp add: least_mod_type to_nat_eq_0)
[PROOF STATE]
proof (prove)
goal (2 subgoals):
 1. \<And>m ma. \<lbrakk>A $ m $ (0::'columns) \<noteq> (0::'a); \<forall>m. Gauss_Jordan_in_ij A (0::'rows) (0::'columns) $ m $ (0::'columns) = (0::'a)\<rbrakk> \<Longrightarrow> A $ ma $ (0::'columns) = (0::'a)
 2. \<And>m ma. \<lbrakk>A $ m $ (0::'columns) \<noteq> (0::'a); Gauss_Jordan_in_ij A (0::'rows) (0::'columns) $ ma $ (0::'columns) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> (GREATEST n. Gauss_Jordan_in_ij A (0::'rows) (0::'columns) $ n $ (0::'columns) \<noteq> (0::'a)) = (0::'rows)
[PROOF STEP]
apply (metis Gauss_Jordan_in_ij_1 least_mod_type zero_neq_one)
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<And>m ma. \<lbrakk>A $ m $ (0::'columns) \<noteq> (0::'a); Gauss_Jordan_in_ij A (0::'rows) (0::'columns) $ ma $ (0::'columns) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> (GREATEST n. Gauss_Jordan_in_ij A (0::'rows) (0::'columns) $ n $ (0::'columns) \<noteq> (0::'a)) = (0::'rows)
[PROOF STEP]
by (metis (lifting, mono_tags) Gauss_Jordan_in_ij_0 GreatestI_ex least_mod_type)
[PROOF STATE]
proof (state)
this:
foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0] = (if \<forall>m. is_zero_row_upt_k m (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc 0) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc 0]))

goal (2 subgoals):
 1. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))
 2. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
next
    \<comment> \<open>Now we begin with the proof of the induction step of the first show. We will make use the induction hypothesis of the second show\<close>
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))
 2. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
fix k
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))
 2. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
assume "(k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k))"
    and "(k < ncols A \<Longrightarrow>
    foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] =
    (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0
    else to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1,
    snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])))"
    and k: "Suc k < ncols A"
[PROOF STATE]
proof (state)
this:
k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k)
k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))
Suc k < ncols A

goal (2 subgoals):
 1. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))
 2. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
hence hyp_rref: "reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k)"
    and hyp_foldl: "foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] =
    (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0
    else to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1,
    snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))"
[PROOF STATE]
proof (prove)
using this:
k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k)
k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))
Suc k < ncols A

goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k) &&& foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))
[PROOF STEP]
by simp+
[PROOF STATE]
proof (state)
this:
reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k)
foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))

goal (2 subgoals):
 1. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))
 2. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
have rw: "[0..<Suc (Suc k)]= [0..<(Suc k)] @ [(Suc k)]"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. [0..<Suc (Suc k)] = [0..<Suc k] @ [Suc k]
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
[0..<Suc (Suc k)] = [0..<Suc k] @ [Suc k]

goal (2 subgoals):
 1. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))
 2. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
have rw2: "(foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) =
    (if \<forall>m. is_zero_row_upt_k m (Suc k) (Gauss_Jordan_upt_k A k) then 0 else to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (Gauss_Jordan_upt_k A k)) + 1,
    Gauss_Jordan_upt_k A k)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (Gauss_Jordan_upt_k A k) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (Gauss_Jordan_upt_k A k)) + 1, Gauss_Jordan_upt_k A k)
[PROOF STEP]
unfolding Gauss_Jordan_upt_k_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))
[PROOF STEP]
using hyp_foldl
[PROOF STATE]
proof (prove)
using this:
foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))

goal (1 subgoal):
 1. foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))
[PROOF STEP]
by fast
[PROOF STATE]
proof (state)
this:
foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (Gauss_Jordan_upt_k A k) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (Gauss_Jordan_upt_k A k)) + 1, Gauss_Jordan_upt_k A k)

goal (2 subgoals):
 1. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))
 2. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
show "reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))
[PROOF STEP]
unfolding Gauss_Jordan_upt_k_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) (Suc (Suc k))
[PROOF STEP]
unfolding rw
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (snd (foldl Gauss_Jordan_column_k (0, A) ([0..<Suc k] @ [Suc k]))) (Suc (Suc k))
[PROOF STEP]
unfolding foldl_append
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (snd (foldl Gauss_Jordan_column_k (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) [Suc k])) (Suc (Suc k))
[PROOF STEP]
unfolding foldl.simps
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (snd (Gauss_Jordan_column_k (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) (Suc k))) (Suc (Suc k))
[PROOF STEP]
unfolding rw2
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (snd (Gauss_Jordan_column_k (if \<forall>m. is_zero_row_upt_k m (Suc k) (Gauss_Jordan_upt_k A k) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (Gauss_Jordan_upt_k A k)) + 1, Gauss_Jordan_upt_k A k) (Suc k))) (Suc (Suc k))
[PROOF STEP]
by (rule reduced_row_echelon_form_upt_k_Gauss_Jordan_column_k[OF hyp_rref])
      \<comment> \<open>Making use of the same hypotheses of above proof, we begin with the proof of the induction step of the second show.\<close>
[PROOF STATE]
proof (state)
this:
reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A (Suc k)) (Suc (Suc k))

goal (1 subgoal):
 1. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
have fst_foldl: "fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) =
    fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0
    else to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1,
    snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) = fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))
[PROOF STEP]
using hyp_foldl
[PROOF STATE]
proof (prove)
using this:
foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))

goal (1 subgoal):
 1. fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) = fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) = fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))

goal (1 subgoal):
 1. \<And>k. \<lbrakk>k < ncols A \<Longrightarrow> reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k); k < ncols A \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc k] = (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])); Suc k < ncols A\<rbrakk> \<Longrightarrow> foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
show "foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] =
    (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0
    else to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1,
    snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
proof (rule prod_eqI)
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
 2. snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) = snd (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
show "snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) =
      snd (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0
      else to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1,
      snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) = snd (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
unfolding Gauss_Jordan_upt_k_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) = snd (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
by force
[PROOF STATE]
proof (state)
this:
snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) = snd (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))

goal (1 subgoal):
 1. fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
define A' where "A' = snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])"
[PROOF STATE]
proof (state)
this:
A' = snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])

goal (1 subgoal):
 1. fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
have ncols_eq: "ncols A = ncols A'"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. ncols A = ncols A'
[PROOF STEP]
unfolding A'_def ncols_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. CARD('columns) = CARD('columns)
[PROOF STEP]
..
[PROOF STATE]
proof (state)
this:
ncols A = ncols A'

goal (1 subgoal):
 1. fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
have rref_A': "reduced_row_echelon_form_upt_k A' (Suc k)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k A' (Suc k)
[PROOF STEP]
using hyp_rref
[PROOF STATE]
proof (prove)
using this:
reduced_row_echelon_form_upt_k (Gauss_Jordan_upt_k A k) (Suc k)

goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k A' (Suc k)
[PROOF STEP]
unfolding A'_def Gauss_Jordan_upt_k_def
[PROOF STATE]
proof (prove)
using this:
reduced_row_echelon_form_upt_k (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) (Suc k)

goal (1 subgoal):
 1. reduced_row_echelon_form_upt_k (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) (Suc k)
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
reduced_row_echelon_form_upt_k A' (Suc k)

goal (1 subgoal):
 1. fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
show "fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) =
      fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0
      else to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1,
      snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))
[PROOF STEP]
apply (simp only: rw)
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. fst (foldl Gauss_Jordan_column_k (0, A) ([0..<Suc k] @ [Suc k])) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) ([0..<Suc k] @ [Suc k]))) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) ([0..<Suc k] @ [Suc k])))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) ([0..<Suc k] @ [Suc k])))
[PROOF STEP]
apply (simp only: foldl_append)
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. fst (foldl Gauss_Jordan_column_k (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) [Suc k]) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) [Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) [Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) [Suc k]))
[PROOF STEP]
apply (simp only: foldl.simps)
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. fst (Gauss_Jordan_column_k (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) (Suc k)) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (Gauss_Jordan_column_k (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) (Suc k))) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (Gauss_Jordan_column_k (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) (Suc k)))) + 1, snd (Gauss_Jordan_column_k (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) (Suc k)))
[PROOF STEP]
apply (simp only: Gauss_Jordan_column_k_def Let_def fst_foldl)
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. fst (if (\<forall>m\<ge>mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))). snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) $ m $ mod_type_class.from_nat (Suc k) = (0::'a)) \<or> fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) = nrows (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])), snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) else (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) + 1, Gauss_Jordan_in_ij (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) (mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])))) (mod_type_class.from_nat (Suc k)))) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (if (\<forall>m\<ge>mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))). snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) $ m $ mod_type_class.from_nat (Suc k) = (0::'a)) \<or> fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) = nrows (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])), snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) else (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) + 1, Gauss_Jordan_in_ij (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) (mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])))) (mod_type_class.from_nat (Suc k))))) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (if (\<forall>m\<ge>mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))). snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) $ m $ mod_type_class.from_nat (Suc k) = (0::'a)) \<or> fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) = nrows (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])), snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) else (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) + 1, Gauss_Jordan_in_ij (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) (mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])))) (mod_type_class.from_nat (Suc k)))))) + 1, snd (if (\<forall>m\<ge>mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))). snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]) $ m $ mod_type_class.from_nat (Suc k) = (0::'a)) \<or> fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) = nrows (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])), snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) else (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) + 1, Gauss_Jordan_in_ij (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) (mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc k])))) (mod_type_class.from_nat (Suc k)))))
[PROOF STEP]
apply (simp only: A'_def[symmetric])
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. fst (if (\<forall>m\<ge>mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A')). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)) \<or> fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A') = nrows A' then (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A'), A') else (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A') + 1, Gauss_Jordan_in_ij A' (mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A'))) (mod_type_class.from_nat (Suc k)))) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (if (\<forall>m\<ge>mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A')). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)) \<or> fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A') = nrows A' then (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A'), A') else (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A') + 1, Gauss_Jordan_in_ij A' (mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A'))) (mod_type_class.from_nat (Suc k))))) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (if (\<forall>m\<ge>mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A')). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)) \<or> fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A') = nrows A' then (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A'), A') else (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A') + 1, Gauss_Jordan_in_ij A' (mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A'))) (mod_type_class.from_nat (Suc k)))))) + 1, snd (if (\<forall>m\<ge>mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A')). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)) \<or> fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A') = nrows A' then (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A'), A') else (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A') + 1, Gauss_Jordan_in_ij A' (mod_type_class.from_nat (fst (if \<forall>m. is_zero_row_upt_k m (Suc k) A' then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1, A'))) (mod_type_class.from_nat (Suc k)))))
[PROOF STEP]
apply auto
[PROOF STATE]
proof (prove)
goal (9 subgoals):
 1. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>mod_type_class.from_nat 0. A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> is_zero_row_upt_k m (Suc (Suc k)) A'
 2. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; mod_type_class.from_nat 0 \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (mod_type_class.from_nat 0) (mod_type_class.from_nat (Suc k)))
 3. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; mod_type_class.from_nat 0 \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (mod_type_class.from_nat 0) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (mod_type_class.from_nat 0) (mod_type_class.from_nat (Suc k)))) = 0
 4. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>mod_type_class.from_nat (Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A'))). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>mod_type_class.from_nat (Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A'))). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 6. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 7. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 8. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; mod_type_class.from_nat (Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A'))) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (mod_type_class.from_nat (Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')))) (mod_type_class.from_nat (Suc k)))
 9. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; mod_type_class.from_nat (Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A'))) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' (mod_type_class.from_nat (Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')))) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (mod_type_class.from_nat (Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')))) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
apply (simp_all only: from_nat_0 from_nat_to_nat_greatest)
[PROOF STATE]
proof (prove)
goal (9 subgoals):
 1. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>0::'rows. A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> is_zero_row_upt_k m (Suc (Suc k)) A'
 2. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))
 3. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 4. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 6. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 7. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 8. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 9. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (9 subgoals):
 1. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>0::'rows. A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> is_zero_row_upt_k m (Suc (Suc k)) A'
 2. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))
 3. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 4. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 6. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 7. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 8. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 9. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
fix m
[PROOF STATE]
proof (state)
goal (9 subgoals):
 1. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>0::'rows. A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> is_zero_row_upt_k m (Suc (Suc k)) A'
 2. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))
 3. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 4. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 6. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 7. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 8. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 9. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
assume "\<forall>m. is_zero_row_upt_k m (Suc k) A'" and "\<forall>m\<ge>0. A' $ m $ from_nat (Suc k) = 0"
[PROOF STATE]
proof (state)
this:
\<forall>m. is_zero_row_upt_k m (Suc k) A'
\<forall>m\<ge>0::'rows. A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)

goal (9 subgoals):
 1. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>0::'rows. A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> is_zero_row_upt_k m (Suc (Suc k)) A'
 2. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))
 3. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 4. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 6. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 7. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 8. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 9. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
thus "is_zero_row_upt_k m (Suc (Suc k)) A'"
[PROOF STATE]
proof (prove)
using this:
\<forall>m. is_zero_row_upt_k m (Suc k) A'
\<forall>m\<ge>0::'rows. A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)

goal (1 subgoal):
 1. is_zero_row_upt_k m (Suc (Suc k)) A'
[PROOF STEP]
using foldl_Gauss_condition_1
[PROOF STATE]
proof (prove)
using this:
\<forall>m. is_zero_row_upt_k m (Suc k) A'
\<forall>m\<ge>0::'rows. A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)
\<lbrakk>\<forall>m. is_zero_row_upt_k m ?k ?A; \<forall>m\<ge>0::?'rows. ?A $ m $ mod_type_class.from_nat ?k = (0::?'a)\<rbrakk> \<Longrightarrow> is_zero_row_upt_k ?m (Suc ?k) ?A

goal (1 subgoal):
 1. is_zero_row_upt_k m (Suc (Suc k)) A'
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
is_zero_row_upt_k m (Suc (Suc k)) A'

goal (8 subgoals):
 1. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))
 2. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 3. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 4. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 5. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 6. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 7. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 8. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (8 subgoals):
 1. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))
 2. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 3. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 4. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 5. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 6. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 7. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 8. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
fix m
[PROOF STATE]
proof (state)
goal (8 subgoals):
 1. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))
 2. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 3. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 4. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 5. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 6. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 7. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 8. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
assume "\<forall>m. is_zero_row_upt_k m (Suc k) A'"
        and "A' $ m $ from_nat (Suc k) \<noteq> 0"
[PROOF STATE]
proof (state)
this:
\<forall>m. is_zero_row_upt_k m (Suc k) A'
A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)

goal (8 subgoals):
 1. \<And>m. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))
 2. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 3. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 4. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 5. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 6. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 7. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 8. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
thus "\<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' 0 (from_nat (Suc k)))"
[PROOF STATE]
proof (prove)
using this:
\<forall>m. is_zero_row_upt_k m (Suc k) A'
A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)

goal (1 subgoal):
 1. \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))
[PROOF STEP]
using foldl_Gauss_condition_2 k ncols_eq
[PROOF STATE]
proof (prove)
using this:
\<forall>m. is_zero_row_upt_k m (Suc k) A'
A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)
\<lbrakk>?k < ncols ?A; \<forall>m. is_zero_row_upt_k m ?k ?A; ?A $ ?m $ mod_type_class.from_nat ?k \<noteq> (0::?'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc ?k) (Gauss_Jordan_in_ij ?A (0::?'rows) (mod_type_class.from_nat ?k))
Suc k < ncols A
ncols A = ncols A'

goal (1 subgoal):
 1. \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
\<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))

goal (7 subgoals):
 1. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 2. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 3. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 4. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 6. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 7. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (7 subgoals):
 1. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 2. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 3. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 4. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 6. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 7. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
fix m ma
[PROOF STATE]
proof (state)
goal (7 subgoals):
 1. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 2. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 3. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 4. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 6. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 7. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
assume "\<forall>m. is_zero_row_upt_k m (Suc k) A'"
        and "A' $ m $ from_nat (Suc k) \<noteq> 0"
        and "\<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' 0 (from_nat (Suc k)))"
[PROOF STATE]
proof (state)
this:
\<forall>m. is_zero_row_upt_k m (Suc k) A'
A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)
\<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))

goal (7 subgoals):
 1. \<And>m ma. \<lbrakk>\<forall>m. is_zero_row_upt_k m (Suc k) A'; (0::'rows) \<le> m; A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
 2. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 3. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 4. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 6. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 7. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
thus "to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' 0 (from_nat (Suc k)))) = 0"
[PROOF STATE]
proof (prove)
using this:
\<forall>m. is_zero_row_upt_k m (Suc k) A'
A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)
\<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))

goal (1 subgoal):
 1. mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
[PROOF STEP]
using foldl_Gauss_condition_3  k ncols_eq
[PROOF STATE]
proof (prove)
using this:
\<forall>m. is_zero_row_upt_k m (Suc k) A'
A' $ m $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)
\<not> is_zero_row_upt_k ma (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))
\<lbrakk>?k < ncols ?A; \<forall>m. is_zero_row_upt_k m ?k ?A; ?A $ ?m $ mod_type_class.from_nat ?k \<noteq> (0::?'a); \<not> is_zero_row_upt_k ?ma (Suc ?k) (Gauss_Jordan_in_ij ?A (0::?'rows) (mod_type_class.from_nat ?k))\<rbrakk> \<Longrightarrow> mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc ?k) (Gauss_Jordan_in_ij ?A (0::?'rows) (mod_type_class.from_nat ?k))) = 0
Suc k < ncols A
ncols A = ncols A'

goal (1 subgoal):
 1. mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' (0::'rows) (mod_type_class.from_nat (Suc k)))) = 0

goal (6 subgoals):
 1. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 3. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 4. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 6. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (6 subgoals):
 1. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 3. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 4. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 6. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
fix m
[PROOF STATE]
proof (state)
goal (6 subgoals):
 1. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 3. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 4. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 6. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
assume "\<not> is_zero_row_upt_k m (Suc k) A' "
[PROOF STATE]
proof (state)
this:
\<not> is_zero_row_upt_k m (Suc k) A'

goal (6 subgoals):
 1. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 3. \<And>m. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
 4. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 5. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 6. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
thus "\<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'" and "\<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'"
[PROOF STATE]
proof (prove)
using this:
\<not> is_zero_row_upt_k m (Suc k) A'

goal (1 subgoal):
 1. \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A' &&& \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
[PROOF STEP]
using is_zero_row_upt_k_le
[PROOF STATE]
proof (prove)
using this:
\<not> is_zero_row_upt_k m (Suc k) A'
is_zero_row_upt_k ?i (Suc ?k) ?A \<Longrightarrow> is_zero_row_upt_k ?i ?k ?A

goal (1 subgoal):
 1. \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A' &&& \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
[PROOF STEP]
by blast+
[PROOF STATE]
proof (state)
this:
\<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'
\<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) A'

goal (4 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 3. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 4. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (4 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 3. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 4. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
fix m
[PROOF STATE]
proof (state)
goal (4 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 3. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 4. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
assume not_zero_m: "\<not> is_zero_row_upt_k m (Suc k) A'"
        and zero_below_greatest: "\<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1. A' $ m $ from_nat (Suc k) = 0"
[PROOF STATE]
proof (state)
this:
\<not> is_zero_row_upt_k m (Suc k) A'
\<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a)

goal (4 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; \<forall>m\<ge>(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows). A' $ m $ mod_type_class.from_nat (Suc k) = (0::'a); \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 3. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 4. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
show "(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')
[PROOF STEP]
by (rule foldl_Gauss_condition_5[OF rref_A' not_zero_m zero_below_greatest])
[PROOF STATE]
proof (state)
this:
(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') = (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A')

goal (3 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 3. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (3 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 3. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
fix m
[PROOF STATE]
proof (state)
goal (3 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 3. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
assume "\<not> is_zero_row_upt_k m (Suc k) A'" and "Suc (to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'"
[PROOF STATE]
proof (state)
this:
\<not> is_zero_row_upt_k m (Suc k) A'
Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'

goal (3 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'; \<not> is_zero_row_upt_k ma (Suc (Suc k)) A'\<rbrakk> \<Longrightarrow> nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
 2. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 3. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
thus "nrows A' = Suc (to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))"
[PROOF STATE]
proof (prove)
using this:
\<not> is_zero_row_upt_k m (Suc k) A'
Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'

goal (1 subgoal):
 1. nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
[PROOF STEP]
using foldl_Gauss_condition_6
[PROOF STATE]
proof (prove)
using this:
\<not> is_zero_row_upt_k m (Suc k) A'
Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = nrows A'
\<lbrakk>\<not> is_zero_row_upt_k ?m ?k ?A; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n ?k ?A)) = nrows ?A\<rbrakk> \<Longrightarrow> nrows ?A = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc ?k) ?A))

goal (1 subgoal):
 1. nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
nrows A' = Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) A'))

goal (2 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 2. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 2. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
fix m ma
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 2. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
assume "\<not> is_zero_row_upt_k m (Suc k) A'"
        and "(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1 \<le> ma"
        and "A' $ ma $ from_nat (Suc k) \<noteq> 0"
[PROOF STATE]
proof (state)
this:
\<not> is_zero_row_upt_k m (Suc k) A'
(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma
A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)

goal (2 subgoals):
 1. \<And>m ma. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
 2. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
thus "\<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1) (from_nat (Suc k)))"
[PROOF STATE]
proof (prove)
using this:
\<not> is_zero_row_upt_k m (Suc k) A'
(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma
A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)

goal (1 subgoal):
 1. \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
[PROOF STEP]
using foldl_Gauss_condition_8
[PROOF STATE]
proof (prove)
using this:
\<not> is_zero_row_upt_k m (Suc k) A'
(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma
A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)
\<lbrakk>?k < ncols ?A; \<not> is_zero_row_upt_k ?m ?k ?A; ?A $ ?ma $ mod_type_class.from_nat ?k \<noteq> (0::?'a); (GREATEST n. \<not> is_zero_row_upt_k n ?k ?A) + (1::?'rows) \<le> ?ma\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc ?k) (Gauss_Jordan_in_ij ?A ((GREATEST n. \<not> is_zero_row_upt_k n ?k ?A) + (1::?'rows)) (mod_type_class.from_nat ?k))

goal (1 subgoal):
 1. \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
[PROOF STEP]
using k ncols_eq
[PROOF STATE]
proof (prove)
using this:
\<not> is_zero_row_upt_k m (Suc k) A'
(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma
A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)
\<lbrakk>?k < ncols ?A; \<not> is_zero_row_upt_k ?m ?k ?A; ?A $ ?ma $ mod_type_class.from_nat ?k \<noteq> (0::?'a); (GREATEST n. \<not> is_zero_row_upt_k n ?k ?A) + (1::?'rows) \<le> ?ma\<rbrakk> \<Longrightarrow> \<exists>m. \<not> is_zero_row_upt_k m (Suc ?k) (Gauss_Jordan_in_ij ?A ((GREATEST n. \<not> is_zero_row_upt_k n ?k ?A) + (1::?'rows)) (mod_type_class.from_nat ?k))
Suc k < ncols A
ncols A = ncols A'

goal (1 subgoal):
 1. \<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
\<exists>m. \<not> is_zero_row_upt_k m (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))

goal (1 subgoal):
 1. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
fix m ma mb
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
assume "\<not> is_zero_row_upt_k m (Suc k) A'" and
        "Suc (to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'"
        and "(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1 \<le> ma"
        and "A' $ ma $ from_nat (Suc k) \<noteq> 0"
        and "\<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1) (from_nat (Suc k)))"
[PROOF STATE]
proof (state)
this:
\<not> is_zero_row_upt_k m (Suc k) A'
Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'
(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma
A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)
\<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))

goal (1 subgoal):
 1. \<And>m ma mb. \<lbrakk>\<not> is_zero_row_upt_k m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma; A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a); \<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
thus "Suc (to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) =
        to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + 1) (from_nat (Suc k))))"
[PROOF STATE]
proof (prove)
using this:
\<not> is_zero_row_upt_k m (Suc k) A'
Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'
(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma
A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)
\<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))

goal (1 subgoal):
 1. Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
using foldl_Gauss_condition_9[OF k[unfolded ncols_eq] rref_A']
[PROOF STATE]
proof (prove)
using this:
\<not> is_zero_row_upt_k m (Suc k) A'
Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'
(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma
A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)
\<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
\<lbrakk>\<not> is_zero_row_upt_k ?m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> nrows A'; (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ?ma; A' $ ?ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))

goal (1 subgoal):
 1. Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
unfolding nrows_def
[PROOF STATE]
proof (prove)
using this:
\<not> is_zero_row_upt_k m (Suc k) A'
Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> CARD('rows)
(GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ma
A' $ ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)
\<not> is_zero_row_upt_k mb (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k)))
\<lbrakk>\<not> is_zero_row_upt_k ?m (Suc k) A'; Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) \<noteq> CARD('rows); (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows) \<le> ?ma; A' $ ?ma $ mod_type_class.from_nat (Suc k) \<noteq> (0::'a)\<rbrakk> \<Longrightarrow> Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))

goal (1 subgoal):
 1. Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
Suc (mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A')) = mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (Gauss_Jordan_in_ij A' ((GREATEST n. \<not> is_zero_row_upt_k n (Suc k) A') + (1::'rows)) (mod_type_class.from_nat (Suc k))))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
fst (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]) = fst (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)] = (if \<forall>m. is_zero_row_upt_k m (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)])) then 0 else mod_type_class.to_nat (GREATEST n. \<not> is_zero_row_upt_k n (Suc (Suc k)) (snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))) + 1, snd (foldl Gauss_Jordan_column_k (0, A) [0..<Suc (Suc k)]))

goal:
No subgoals!
[PROOF STEP]
qed