[STATEMENT]
lemma associativity:
 fixes M1 M2 M3
 shows
      " (mat (row_length M1) (length M1) M1)
      \<and> (mat (row_length M2) (length M2) M2)
      \<and> (mat (row_length M3) (length M3) M3)
        \<Longrightarrow>
           M1 \<otimes> (M2 \<otimes> M3) = (M1 \<otimes> M2) \<otimes> M3" (is "?x \<Longrightarrow>?l = ?r")
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
proof-
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
fix j
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
assume 0:"  (mat (row_length M1) (length M1) M1)
           \<and> (mat (row_length M2) (length M2) M2)
           \<and> (mat (row_length M3) (length M3) M3)"
[PROOF STATE]
proof (state)
this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have 1:"length ((M1 \<otimes> M2) \<otimes> M3)
                    = (length M1)*(length M2)* (length M3)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3
[PROOF STEP]
proof-
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3
[PROOF STEP]
have "length (M2 \<otimes> M3) = (length M2)* (length M3)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. length (M2 \<otimes> M3) = length M2 * length M3
[PROOF STEP]
by (metis length_Tensor)
[PROOF STATE]
proof (state)
this:
length (M2 \<otimes> M3) = length M2 * length M3

goal (1 subgoal):
 1. length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
length (M2 \<otimes> M3) = length M2 * length M3
[PROOF STEP]
have "length (M1 \<otimes> (M2 \<otimes> M3))
                  = (length M1)*(length M2)* (length M3)"
[PROOF STATE]
proof (prove)
using this:
length (M2 \<otimes> M3) = length M2 * length M3

goal (1 subgoal):
 1. length (M1 \<otimes> (M2 \<otimes> M3)) = length M1 * length M2 * length M3
[PROOF STEP]
using mult.assoc length_Tensor
[PROOF STATE]
proof (prove)
using this:
length (M2 \<otimes> M3) = length M2 * length M3
Matrix_Tensor.mult ?id ?f \<Longrightarrow> ?f (?f ?a ?b) ?c = ?f ?a (?f ?b ?c)
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0

goal (1 subgoal):
 1. length (M1 \<otimes> (M2 \<otimes> M3)) = length M1 * length M2 * length M3
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
length (M1 \<otimes> (M2 \<otimes> M3)) = length M1 * length M2 * length M3

goal (1 subgoal):
 1. length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
length (M1 \<otimes> (M2 \<otimes> M3)) = length M1 * length M2 * length M3

goal (1 subgoal):
 1. length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3
[PROOF STEP]
have " length (M1 \<otimes> M2) = (length M1)* (length M2)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. length (M1 \<otimes> M2) = length M1 * length M2
[PROOF STEP]
by (metis length_Tensor)
[PROOF STATE]
proof (state)
this:
length (M1 \<otimes> M2) = length M1 * length M2

goal (1 subgoal):
 1. length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
length (M1 \<otimes> (M2 \<otimes> M3)) = length M1 * length M2 * length M3
length (M1 \<otimes> M2) = length M1 * length M2
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
length (M1 \<otimes> (M2 \<otimes> M3)) = length M1 * length M2 * length M3
length (M1 \<otimes> M2) = length M1 * length M2

goal (1 subgoal):
 1. length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3
[PROOF STEP]
using mult.assoc length_Tensor
[PROOF STATE]
proof (prove)
using this:
length (M1 \<otimes> (M2 \<otimes> M3)) = length M1 * length M2 * length M3
length (M1 \<otimes> M2) = length M1 * length M2
Matrix_Tensor.mult ?id ?f \<Longrightarrow> ?f (?f ?a ?b) ?c = ?f ?a (?f ?b ?c)
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0

goal (1 subgoal):
 1. length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have 2:"row_length ((M1 \<otimes> M2) \<otimes> M3)
                    = (row_length M1)*(row_length M2)* (row_length M3)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3
[PROOF STEP]
proof-
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3
[PROOF STEP]
have "row_length (M2 \<otimes> M3) = (row_length M2)* (row_length M3)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. row_length (M2 \<otimes> M3) = row_length M2 * row_length M3
[PROOF STEP]
using row_length_mat assoc
[PROOF STATE]
proof (prove)
using this:
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0
?a * ?b * ?c = ?a * (?b * ?c)

goal (1 subgoal):
 1. row_length (M2 \<otimes> M3) = row_length M2 * row_length M3
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
row_length (M2 \<otimes> M3) = row_length M2 * row_length M3

goal (1 subgoal):
 1. row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
row_length (M2 \<otimes> M3) = row_length M2 * row_length M3
[PROOF STEP]
have "row_length (M1 \<otimes> (M2 \<otimes> M3))
                   = (row_length M1)*(row_length M2)* (row_length M3)"
[PROOF STATE]
proof (prove)
using this:
row_length (M2 \<otimes> M3) = row_length M2 * row_length M3

goal (1 subgoal):
 1. row_length (M1 \<otimes> (M2 \<otimes> M3)) = row_length M1 * row_length M2 * row_length M3
[PROOF STEP]
using row_length_mat assoc
[PROOF STATE]
proof (prove)
using this:
row_length (M2 \<otimes> M3) = row_length M2 * row_length M3
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0
?a * ?b * ?c = ?a * (?b * ?c)

goal (1 subgoal):
 1. row_length (M1 \<otimes> (M2 \<otimes> M3)) = row_length M1 * row_length M2 * row_length M3
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
row_length (M1 \<otimes> (M2 \<otimes> M3)) = row_length M1 * row_length M2 * row_length M3

goal (1 subgoal):
 1. row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
row_length (M1 \<otimes> (M2 \<otimes> M3)) = row_length M1 * row_length M2 * row_length M3

goal (1 subgoal):
 1. row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3
[PROOF STEP]
have " row_length (M1 \<otimes> M2)
                                   = (row_length M1)* (row_length M2)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. row_length (M1 \<otimes> M2) = row_length M1 * row_length M2
[PROOF STEP]
using row_length_mat
[PROOF STATE]
proof (prove)
using this:
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0

goal (1 subgoal):
 1. row_length (M1 \<otimes> M2) = row_length M1 * row_length M2
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
row_length (M1 \<otimes> M2) = row_length M1 * row_length M2

goal (1 subgoal):
 1. row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
row_length (M1 \<otimes> (M2 \<otimes> M3)) = row_length M1 * row_length M2 * row_length M3
row_length (M1 \<otimes> M2) = row_length M1 * row_length M2
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
row_length (M1 \<otimes> (M2 \<otimes> M3)) = row_length M1 * row_length M2 * row_length M3
row_length (M1 \<otimes> M2) = row_length M1 * row_length M2

goal (1 subgoal):
 1. row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3
[PROOF STEP]
using row_length_mat assoc
[PROOF STATE]
proof (prove)
using this:
row_length (M1 \<otimes> (M2 \<otimes> M3)) = row_length M1 * row_length M2 * row_length M3
row_length (M1 \<otimes> M2) = row_length M1 * row_length M2
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0
?a * ?b * ?c = ?a * (?b * ?c)

goal (1 subgoal):
 1. row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have 3:
      "\<forall>i.\<forall>j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
                \<longrightarrow>
            (((M1 \<otimes> M2) \<otimes> M3)!j!i)
                = f
                   ((M1 \<otimes> M2)!(j div (length M3))!(i div (row_length M3)))
                   (M3!(j mod length M3)!(i mod (row_length M3))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
using 0 matrix_Tensor_elements 1 2 effective_well_defined_Tensor
             length_Tensor row_length_mat
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3
\<forall>i j. (i < row_length ?M1.0 * row_length ?M2.0 \<and> j < length ?M1.0 * length ?M2.0) \<and> mat (row_length ?M1.0) (length ?M1.0) ?M1.0 \<and> mat (row_length ?M2.0) (length ?M2.0) ?M2.0 \<longrightarrow> (?M1.0 \<otimes> ?M2.0) ! j ! i = ?M1.0 ! (j div length ?M2.0) ! (i div row_length ?M2.0) * ?M2.0 ! (j mod length ?M2.0) ! (i mod row_length ?M2.0)
length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3
row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3
\<lbrakk>mat (row_length ?M1.0) (length ?M1.0) ?M1.0; mat (row_length ?M2.0) (length ?M2.0) ?M2.0\<rbrakk> \<Longrightarrow> mat (row_length ?M1.0 * row_length ?M2.0) (length ?M1.0 * length ?M2.0) (?M1.0 \<otimes> ?M2.0)
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have
       "\<forall>j.(j < (length M1)*(length M2)*(length M3))
                          \<longrightarrow> (j div (length M3)) < (length M1)*(length M2)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>j<length M1 * length M2 * length M3. j div length M3 < length M1 * length M2
[PROOF STEP]
apply(rule allI)
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<And>j. j < length M1 * length M2 * length M3 \<longrightarrow> j div length M3 < length M1 * length M2
[PROOF STEP]
apply(simp add:div_left_ineq)
[PROOF STATE]
proof (prove)
goal:
No subgoals!
[PROOF STEP]
done
[PROOF STATE]
proof (state)
this:
\<forall>j<length M1 * length M2 * length M3. j div length M3 < length M1 * length M2

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
\<forall>j<length M1 * length M2 * length M3. j div length M3 < length M1 * length M2

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have "\<forall>i.(i < (row_length M1)*(row_length M2)*(row_length M3))
                       \<longrightarrow> (i div (row_length M3))
                                         < (row_length M1)*(row_length M2)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>i<row_length M1 * row_length M2 * row_length M3. i div row_length M3 < row_length M1 * row_length M2
[PROOF STEP]
apply(rule allI)
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<And>i. i < row_length M1 * row_length M2 * row_length M3 \<longrightarrow> i div row_length M3 < row_length M1 * row_length M2
[PROOF STEP]
apply(simp add:div_left_ineq)
[PROOF STATE]
proof (prove)
goal:
No subgoals!
[PROOF STEP]
done
[PROOF STATE]
proof (state)
this:
\<forall>i<row_length M1 * row_length M2 * row_length M3. i div row_length M3 < row_length M1 * row_length M2

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)
\<forall>j<length M1 * length M2 * length M3. j div length M3 < length M1 * length M2
\<forall>i<row_length M1 * row_length M2 * row_length M3. i div row_length M3 < row_length M1 * row_length M2
[PROOF STEP]
have 4:"\<forall>i.\<forall>j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
          \<longrightarrow>
                ((i div (row_length M3)) < (row_length M1)*(row_length M2))
                \<and> ((j div (length M3)) < (length M1)*(length M2)))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)
\<forall>j<length M1 * length M2 * length M3. j div length M3 < length M1 * length M2
\<forall>i<row_length M1 * row_length M2 * row_length M3. i div row_length M3 < row_length M1 * row_length M2

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i div row_length M3 < row_length M1 * row_length M2 \<and> j div length M3 < length M1 * length M2
[PROOF STEP]
using allI 0
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)
\<forall>j<length M1 * length M2 * length M3. j div length M3 < length M1 * length M2
\<forall>i<row_length M1 * row_length M2 * row_length M3. i div row_length M3 < row_length M1 * row_length M2
(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i div row_length M3 < row_length M1 * row_length M2 \<and> j div length M3 < length M1 * length M2
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i div row_length M3 < row_length M1 * row_length M2 \<and> j div length M3 < length M1 * length M2

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have " (mat (row_length M1) (length M1) M1)
           \<and> (mat (row_length M2) (length M2) M2)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2
[PROOF STEP]
using 0
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2
[PROOF STEP]
have "\<forall>i.\<forall>j.(((i div (row_length M3)) < (row_length M1)*(row_length M2))
         \<and> ((j div (length M3)) < (length M1)*(length M2))
          \<longrightarrow>
       (((M1 \<otimes> M2))!(j div (length M3))!(i div row_length M3))
                = f
          ((M1)!((j div (length M3)) div (length M2))
               !((i div (row_length M3)) div (row_length M2)))
          (M2!((j div (length M3)) mod (length M2))
             !((i div (row_length M3)) mod (row_length M2))))"
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2

goal (1 subgoal):
 1. \<forall>i j. i div row_length M3 < row_length M1 * row_length M2 \<and> j div length M3 < length M1 * length M2 \<longrightarrow> (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2)
[PROOF STEP]
using  effective_matrix_tensor_elements
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2
(?i < row_length ?M1.0 * row_length ?M2.0 \<and> ?j < length ?M1.0 * length ?M2.0) \<and> mat (row_length ?M1.0) (length ?M1.0) ?M1.0 \<and> mat (row_length ?M2.0) (length ?M2.0) ?M2.0 \<Longrightarrow> (?M1.0 \<otimes> ?M2.0) ! ?j ! ?i = ?M1.0 ! (?j div length ?M2.0) ! (?i div row_length ?M2.0) * ?M2.0 ! (?j mod length ?M2.0) ! (?i mod row_length ?M2.0)

goal (1 subgoal):
 1. \<forall>i j. i div row_length M3 < row_length M1 * row_length M2 \<and> j div length M3 < length M1 * length M2 \<longrightarrow> (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i div row_length M3 < row_length M1 * row_length M2 \<and> j div length M3 < length M1 * length M2 \<longrightarrow> (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
with 4
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i div row_length M3 < row_length M1 * row_length M2 \<and> j div length M3 < length M1 * length M2
\<forall>i j. i div row_length M3 < row_length M1 * row_length M2 \<and> j div length M3 < length M1 * length M2 \<longrightarrow> (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2)
[PROOF STEP]
have 5:"\<forall>i j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
          \<longrightarrow>  (((M1 \<otimes> M2))!(j div (length M3))!(i div row_length M3))
                = f
       ((M1)!((j div (length M3)) div (length M2))
            !((i div (row_length M3)) div (row_length M2)))
        (M2!((j div (length M3)) mod (length M2))
            !((i div (row_length M3)) mod (row_length M2))))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i div row_length M3 < row_length M1 * row_length M2 \<and> j div length M3 < length M1 * length M2
\<forall>i j. i div row_length M3 < row_length M1 * row_length M2 \<and> j div length M3 < length M1 * length M2 \<longrightarrow> (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2)

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
with 3
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2)
[PROOF STEP]
have 6:
      "\<forall>i.\<forall>j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
                \<longrightarrow>
            (((M1 \<otimes> M2) \<otimes> M3)!j!i)
                = f
                   (f
                     ((M1)!((j div (length M3)) div (length M2))
                             !((i div (row_length M3)) div (row_length M2)))
                     (M2!((j div (length M3)) mod (length M2))
                           !((i div (row_length M3)) mod (row_length M2))))
                   (M3!(j mod length M3)!(i mod (row_length M3))))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2) ! (j div length M3) ! (i div row_length M3) = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2)

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have "(j div (length M3))div (length M2) = (j div ((length M3)*(length M2)))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. j div length M3 div length M2 = j div (length M3 * length M2)
[PROOF STEP]
using div_mult2_eq
[PROOF STATE]
proof (prove)
using this:
?m div (?n * ?q) = ?m div ?n div ?q

goal (1 subgoal):
 1. j div length M3 div length M2 = j div (length M3 * length M2)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
j div length M3 div length M2 = j div (length M3 * length M2)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
j div length M3 div length M2 = j div (length M3 * length M2)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have "((i div (row_length M3)) div (row_length M2)) = (i div ((row_length M3)*(row_length M2)))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. i div row_length M3 div row_length M2 = i div (row_length M3 * row_length M2)
[PROOF STEP]
using div_mult2_eq
[PROOF STATE]
proof (prove)
using this:
?m div (?n * ?q) = ?m div ?n div ?q

goal (1 subgoal):
 1. i div row_length M3 div row_length M2 = i div (row_length M3 * row_length M2)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
i div row_length M3 div row_length M2 = i div (row_length M3 * row_length M2)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
j div length M3 div length M2 = j div (length M3 * length M2)
i div row_length M3 div row_length M2 = i div (row_length M3 * row_length M2)
[PROOF STEP]
have step1:"\<forall>i.\<forall>j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
                \<longrightarrow>
            (((M1 \<otimes> M2) \<otimes> M3)!j!i)
                = f
                   (f
       ((M1)!(j div ((length M3)*(length M2)))! (i div ((row_length M3)*(row_length M2))))
          (M2!((j div (length M3)) mod (length M2))!((i div (row_length M3)) mod (row_length M2))))
                   (M3!(j mod length M3)!(i mod (row_length M3))))"
[PROOF STATE]
proof (prove)
using this:
j div length M3 div length M2 = j div (length M3 * length M2)
i div row_length M3 div row_length M2 = i div (row_length M3 * row_length M2)

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div (length M3 * length M2)) ! (i div (row_length M3 * row_length M2)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
using 6
[PROOF STATE]
proof (prove)
using this:
j div length M3 div length M2 = j div (length M3 * length M2)
i div row_length M3 div row_length M2 = i div (row_length M3 * row_length M2)
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div length M3 div length M2) ! (i div row_length M3 div row_length M2) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div (length M3 * length M2)) ! (i div (row_length M3 * row_length M2)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
by (metis "3" "5" div_mult2_eq)
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div (length M3 * length M2)) ! (i div (row_length M3 * row_length M2)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div (length M3 * length M2)) ! (i div (row_length M3 * row_length M2)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
have step1:"\<forall>i j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
                \<longrightarrow>
            (((M1 \<otimes> M2) \<otimes> M3)!j!i)
                = f
                   (f
       ((M1)!(j div ((length M2)*(length M3)))! (i div ((row_length M2)*(row_length M3))))
          (M2!((j div (length M3)) mod (length M2))!((i div (row_length M3)) mod (row_length M2))))
                   (M3!(j mod length M3)!(i mod (row_length M3))))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div (length M3 * length M2)) ! (i div (row_length M3 * row_length M2)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
by (metis mult.commute)
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have 7:
      "\<forall>i.\<forall>j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
                \<longrightarrow>
            ((M1 \<otimes> (M2 \<otimes> M3))!j!i)
                = f
                   ((M1)!(j div (length (M2 \<otimes>  M3)))!(i div (row_length (M2 \<otimes> M3))))
                   ((M2 \<otimes> M3)!(j mod length (M2 \<otimes>M3))!(i mod (row_length (M2 \<otimes> M3)))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div length (M2 \<otimes> M3)) ! (i div row_length (M2 \<otimes> M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
[PROOF STEP]
using 0 matrix_Tensor_elements 1 2 effective_well_defined_Tensor
             length_Tensor row_length_mat
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3
\<forall>i j. (i < row_length ?M1.0 * row_length ?M2.0 \<and> j < length ?M1.0 * length ?M2.0) \<and> mat (row_length ?M1.0) (length ?M1.0) ?M1.0 \<and> mat (row_length ?M2.0) (length ?M2.0) ?M2.0 \<longrightarrow> (?M1.0 \<otimes> ?M2.0) ! j ! i = ?M1.0 ! (j div length ?M2.0) ! (i div row_length ?M2.0) * ?M2.0 ! (j mod length ?M2.0) ! (i mod row_length ?M2.0)
length (M1 \<otimes> M2 \<otimes> M3) = length M1 * length M2 * length M3
row_length (M1 \<otimes> M2 \<otimes> M3) = row_length M1 * row_length M2 * row_length M3
\<lbrakk>mat (row_length ?M1.0) (length ?M1.0) ?M1.0; mat (row_length ?M2.0) (length ?M2.0) ?M2.0\<rbrakk> \<Longrightarrow> mat (row_length ?M1.0 * row_length ?M2.0) (length ?M1.0 * length ?M2.0) (?M1.0 \<otimes> ?M2.0)
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div length (M2 \<otimes> M3)) ! (i div row_length (M2 \<otimes> M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div length (M2 \<otimes> M3)) ! (i div row_length (M2 \<otimes> M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div length (M2 \<otimes> M3)) ! (i div row_length (M2 \<otimes> M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
[PROOF STEP]
have
      "\<forall>i.\<forall>j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
                \<longrightarrow>
            ((M1 \<otimes> (M2 \<otimes> M3))!j!i)
                = f
                   ((M1)!(j div ((length M2)*(length M3)))!(i div ((row_length M2)*(row_length M3))))
                   ((M2 \<otimes> M3)!(j mod length (M2 \<otimes>M3))!(i mod (row_length (M2 \<otimes> M3)))))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div length (M2 \<otimes> M3)) ! (i div row_length (M2 \<otimes> M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
[PROOF STEP]
using length_Tensor row_length_mat
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div length (M2 \<otimes> M3)) ! (i div row_length (M2 \<otimes> M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
[PROOF STEP]
have
      "\<forall>i.\<forall>j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
                \<longrightarrow>
            ((M1 \<otimes> (M2 \<otimes> M3))!j!i)
                = f
                   ((M1)!(j div ((length M3)*(length M2)))
                        !(i div ((row_length M3)*(row_length M2))))
                   ((M2 \<otimes> M3)!(j mod length (M2 \<otimes>M3))
                             !(i mod (row_length (M2 \<otimes> M3)))))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M3 * length M2)) ! (i div (row_length M3 * row_length M2)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
[PROOF STEP]
using mult.commute
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
?a * ?b = ?b * ?a

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M3 * length M2)) ! (i div (row_length M3 * row_length M2)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
[PROOF STEP]
by (metis)
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M3 * length M2)) ! (i div (row_length M3 * row_length M2)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have 8:
       "\<forall>j.((j < (length M1)*(length M2)*(length M3)))
                \<longrightarrow> (j mod (length (M2 \<otimes> M3))) < (length (M2 \<otimes> M3))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
proof(cases "length (M2 \<otimes> M3) = 0")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. length (M2 \<otimes> M3) = 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
 2. length (M2 \<otimes> M3) \<noteq> 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
length (M2 \<otimes> M3) = 0

goal (2 subgoals):
 1. length (M2 \<otimes> M3) = 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
 2. length (M2 \<otimes> M3) \<noteq> 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
have "(length M2)*(length M3) = 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. length M2 * length M3 = 0
[PROOF STEP]
using length_Tensor True
[PROOF STATE]
proof (prove)
using this:
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0
length (M2 \<otimes> M3) = 0

goal (1 subgoal):
 1. length M2 * length M3 = 0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
length M2 * length M3 = 0

goal (2 subgoals):
 1. length (M2 \<otimes> M3) = 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
 2. length (M2 \<otimes> M3) \<noteq> 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
length M2 * length M3 = 0
[PROOF STEP]
have "(length M1)*(length M2)*(length M3) = 0"
[PROOF STATE]
proof (prove)
using this:
length M2 * length M3 = 0

goal (1 subgoal):
 1. length M1 * length M2 * length M3 = 0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
length M1 * length M2 * length M3 = 0

goal (2 subgoals):
 1. length (M2 \<otimes> M3) = 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
 2. length (M2 \<otimes> M3) \<noteq> 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
length M1 * length M2 * length M3 = 0
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
length M1 * length M2 * length M3 = 0

goal (1 subgoal):
 1. \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
by (metis  less_nat_zero_code)
[PROOF STATE]
proof (state)
this:
\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)

goal (1 subgoal):
 1. length (M2 \<otimes> M3) \<noteq> 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. length (M2 \<otimes> M3) \<noteq> 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
length (M2 \<otimes> M3) \<noteq> 0

goal (1 subgoal):
 1. length (M2 \<otimes> M3) \<noteq> 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
have "length (M2 \<otimes> M3)  > 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. 0 < length (M2 \<otimes> M3)
[PROOF STEP]
using False
[PROOF STATE]
proof (prove)
using this:
length (M2 \<otimes> M3) \<noteq> 0

goal (1 subgoal):
 1. 0 < length (M2 \<otimes> M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
0 < length (M2 \<otimes> M3)

goal (1 subgoal):
 1. length (M2 \<otimes> M3) \<noteq> 0 \<Longrightarrow> \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
0 < length (M2 \<otimes> M3)
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
0 < length (M2 \<otimes> M3)

goal (1 subgoal):
 1. \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
using mod_less_divisor
[PROOF STATE]
proof (prove)
using this:
0 < length (M2 \<otimes> M3)
0 < ?n \<Longrightarrow> ?m mod ?n < ?n

goal (1 subgoal):
 1. \<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
have 9:
        "\<forall>i.((i < (row_length M1)*(row_length M2)*(row_length M3)))
                \<longrightarrow> (i mod (row_length (M2 \<otimes> M3))) < (row_length (M2 \<otimes> M3))"
[PROOF STATE]
proof (prove)
using this:
\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)

goal (1 subgoal):
 1. \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
proof(cases "row_length (M2 \<otimes> M3) = 0")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) = 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
 2. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) \<noteq> 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
row_length (M2 \<otimes> M3) = 0

goal (2 subgoals):
 1. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) = 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
 2. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) \<noteq> 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
have "(row_length M2)*(row_length M3) = 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. row_length M2 * row_length M3 = 0
[PROOF STEP]
using  True
[PROOF STATE]
proof (prove)
using this:
row_length (M2 \<otimes> M3) = 0

goal (1 subgoal):
 1. row_length M2 * row_length M3 = 0
[PROOF STEP]
by (metis row_length_mat)
[PROOF STATE]
proof (state)
this:
row_length M2 * row_length M3 = 0

goal (2 subgoals):
 1. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) = 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
 2. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) \<noteq> 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
row_length M2 * row_length M3 = 0
[PROOF STEP]
have "(row_length M1)*(row_length M2)*(row_length M3) = 0"
[PROOF STATE]
proof (prove)
using this:
row_length M2 * row_length M3 = 0

goal (1 subgoal):
 1. row_length M1 * row_length M2 * row_length M3 = 0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
row_length M1 * row_length M2 * row_length M3 = 0

goal (2 subgoals):
 1. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) = 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
 2. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) \<noteq> 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
row_length M1 * row_length M2 * row_length M3 = 0
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
row_length M1 * row_length M2 * row_length M3 = 0

goal (1 subgoal):
 1. \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
by (metis less_nat_zero_code)
[PROOF STATE]
proof (state)
this:
\<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)

goal (1 subgoal):
 1. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) \<noteq> 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) \<noteq> 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
row_length (M2 \<otimes> M3) \<noteq> 0

goal (1 subgoal):
 1. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) \<noteq> 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
have "row_length (M2 \<otimes> M3)  > 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. 0 < row_length (M2 \<otimes> M3)
[PROOF STEP]
using False
[PROOF STATE]
proof (prove)
using this:
row_length (M2 \<otimes> M3) \<noteq> 0

goal (1 subgoal):
 1. 0 < row_length (M2 \<otimes> M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
0 < row_length (M2 \<otimes> M3)

goal (1 subgoal):
 1. \<lbrakk>\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3); row_length (M2 \<otimes> M3) \<noteq> 0\<rbrakk> \<Longrightarrow> \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
0 < row_length (M2 \<otimes> M3)
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
0 < row_length (M2 \<otimes> M3)

goal (1 subgoal):
 1. \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
using mod_less_divisor
[PROOF STATE]
proof (prove)
using this:
0 < row_length (M2 \<otimes> M3)
0 < ?n \<Longrightarrow> ?m mod ?n < ?n

goal (1 subgoal):
 1. \<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
with 8
[PROOF STATE]
proof (chain)
picking this:
\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
\<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)
[PROOF STEP]
have 10:"\<forall>i.\<forall>j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
             \<longrightarrow>
                (i mod (row_length (M2 \<otimes> M3))) < (row_length (M2 \<otimes> M3))
              \<and> (j mod (length (M2 \<otimes> M3))) < (length (M2 \<otimes> M3)))"
[PROOF STATE]
proof (prove)
using this:
\<forall>j<length M1 * length M2 * length M3. j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
\<forall>i<row_length M1 * row_length M2 * row_length M3. i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3)

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3) \<and> j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3) \<and> j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3) \<and> j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
[PROOF STEP]
have 11:"\<forall> i j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
             \<longrightarrow>
                (i mod (row_length (M2 \<otimes> M3)))
                              < (row_length M2)*(row_length M3)
                \<and>(j mod (length (M2 \<otimes> M3))) < (length M2)*(length  M3))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3) \<and> j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i mod row_length (M2 \<otimes> M3) < row_length M2 * row_length M3 \<and> j mod length (M2 \<otimes> M3) < length M2 * length M3
[PROOF STEP]
using length_Tensor row_length_mat
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i mod row_length (M2 \<otimes> M3) < row_length (M2 \<otimes> M3) \<and> j mod length (M2 \<otimes> M3) < length (M2 \<otimes> M3)
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i mod row_length (M2 \<otimes> M3) < row_length M2 * row_length M3 \<and> j mod length (M2 \<otimes> M3) < length M2 * length M3
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i mod row_length (M2 \<otimes> M3) < row_length M2 * row_length M3 \<and> j mod length (M2 \<otimes> M3) < length M2 * length M3

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have "(mat (row_length M2) (length M2) M2)
           \<and> (mat (row_length M3) (length M3) M3)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3
[PROOF STEP]
using 0
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3

goal (1 subgoal):
 1. mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3
[PROOF STEP]
have "\<forall> i j.(((i mod (row_length (M2 \<otimes> M3)))
                                 < (row_length M2)*(row_length M3))
                  \<and>((j mod (length (M2\<otimes>M3))) < (length M2)*(length M3))
       \<longrightarrow>
       (((M2 \<otimes> M3))!(j mod (length (M2 \<otimes> M3)))!(i mod row_length (M2 \<otimes> M3)))
                = f
                  ((M2)!((j mod (length (M2 \<otimes> M3))) div (length M3))
                        !((i mod (row_length (M2 \<otimes> M3))) div (row_length M3)))
                  (M3!((j mod (length (M2 \<otimes> M3))) mod (length M3))
                     !((i mod (row_length (M2 \<otimes> M3))) mod (row_length M3))))"
[PROOF STATE]
proof (prove)
using this:
mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3

goal (1 subgoal):
 1. \<forall>i j. i mod row_length (M2 \<otimes> M3) < row_length M2 * row_length M3 \<and> j mod length (M2 \<otimes> M3) < length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)
[PROOF STEP]
using matrix_Tensor_elements
[PROOF STATE]
proof (prove)
using this:
mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3
\<forall>i j. (i < row_length ?M1.0 * row_length ?M2.0 \<and> j < length ?M1.0 * length ?M2.0) \<and> mat (row_length ?M1.0) (length ?M1.0) ?M1.0 \<and> mat (row_length ?M2.0) (length ?M2.0) ?M2.0 \<longrightarrow> (?M1.0 \<otimes> ?M2.0) ! j ! i = ?M1.0 ! (j div length ?M2.0) ! (i div row_length ?M2.0) * ?M2.0 ! (j mod length ?M2.0) ! (i mod row_length ?M2.0)

goal (1 subgoal):
 1. \<forall>i j. i mod row_length (M2 \<otimes> M3) < row_length M2 * row_length M3 \<and> j mod length (M2 \<otimes> M3) < length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i mod row_length (M2 \<otimes> M3) < row_length M2 * row_length M3 \<and> j mod length (M2 \<otimes> M3) < length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i mod row_length (M2 \<otimes> M3) < row_length M2 * row_length M3 \<and> j mod length (M2 \<otimes> M3) < length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)
[PROOF STEP]
have "\<forall> i j.
         ((i < (row_length M1)*(row_length M2)*(row_length M3))
       \<and>(j < (length M1)*(length M2)*(length M3) )
             \<longrightarrow>
           (((M2 \<otimes> M3))!(j mod (length (M2 \<otimes> M3)))
                       !(i mod row_length (M2 \<otimes> M3)))
                =
       f
       ((M2)!((j mod (length (M2 \<otimes> M3))) div (length M3))
            !((i mod (row_length (M2 \<otimes> M3))) div (row_length M3)))
        (M3!((j mod (length (M2 \<otimes> M3))) mod (length M3))
           !((i mod (row_length (M2 \<otimes> M3))) mod (row_length M3))))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i mod row_length (M2 \<otimes> M3) < row_length M2 * row_length M3 \<and> j mod length (M2 \<otimes> M3) < length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)
[PROOF STEP]
using 11
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i mod row_length (M2 \<otimes> M3) < row_length M2 * row_length M3 \<and> j mod length (M2 \<otimes> M3) < length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> i mod row_length (M2 \<otimes> M3) < row_length M2 * row_length M3 \<and> j mod length (M2 \<otimes> M3) < length M2 * length M3

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)
[PROOF STEP]
have "\<forall>j.(j mod (length (M2 \<otimes> M3))) mod (length M3)
                         = j mod (length M3)"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)

goal (1 subgoal):
 1. \<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3
[PROOF STEP]
proof
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<forall>j. ?x < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (?x mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (?x mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (?x mod row_length (M2 \<otimes> M3) mod row_length M3) \<Longrightarrow> \<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3
[PROOF STEP]
have "\<forall>j.((j mod (length (M2 \<otimes> M3)))
                         = (j mod ((length M2) *(length M3))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)
[PROOF STEP]
using length_Tensor
[PROOF STATE]
proof (prove)
using this:
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0

goal (1 subgoal):
 1. \<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)

goal (1 subgoal):
 1. \<forall>j. ?x < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (?x mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (?x mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (?x mod row_length (M2 \<otimes> M3) mod row_length M3) \<Longrightarrow> \<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
\<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)

goal (1 subgoal):
 1. \<forall>j. ?x < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (?x mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (?x mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (?x mod row_length (M2 \<otimes> M3) mod row_length M3) \<Longrightarrow> \<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3
[PROOF STEP]
have
         "\<forall>j.((j mod ((length M2) *(length M3))) mod (length M3)
                                 = (j mod (length M3)))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>j. j mod (length M2 * length M3) mod length M3 = j mod length M3
[PROOF STEP]
using mod_prop1
[PROOF STATE]
proof (prove)
using this:
?a mod (?b * ?c) mod ?c = ?a mod ?c

goal (1 subgoal):
 1. \<forall>j. j mod (length M2 * length M3) mod length M3 = j mod length M3
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>j. j mod (length M2 * length M3) mod length M3 = j mod length M3

goal (1 subgoal):
 1. \<forall>j. ?x < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (?x mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (?x mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (?x mod row_length (M2 \<otimes> M3) mod row_length M3) \<Longrightarrow> \<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
\<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)
\<forall>j. j mod (length M2 * length M3) mod length M3 = j mod length M3
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)
\<forall>j. j mod (length M2 * length M3) mod length M3 = j mod length M3

goal (1 subgoal):
 1. \<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
\<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3
[PROOF STEP]
have "\<forall>i.(i mod (row_length (M2 \<otimes> M3))) mod (row_length M3)
                         = i mod (row_length M3)"
[PROOF STATE]
proof (prove)
using this:
\<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3

goal (1 subgoal):
 1. \<forall>i. i mod row_length (M2 \<otimes> M3) mod row_length M3 = i mod row_length M3
[PROOF STEP]
proof
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. ?x mod length (M2 \<otimes> M3) mod length M3 = ?x mod length M3 \<Longrightarrow> \<forall>i. i mod row_length (M2 \<otimes> M3) mod row_length M3 = i mod row_length M3
[PROOF STEP]
have "\<forall>i.((i mod (row_length (M2 \<otimes> M3)))
                         = (i mod ((row_length M2) *(row_length M3))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)
[PROOF STEP]
using row_length_mat
[PROOF STATE]
proof (prove)
using this:
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0

goal (1 subgoal):
 1. \<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)

goal (1 subgoal):
 1. ?x mod length (M2 \<otimes> M3) mod length M3 = ?x mod length M3 \<Longrightarrow> \<forall>i. i mod row_length (M2 \<otimes> M3) mod row_length M3 = i mod row_length M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
\<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)

goal (1 subgoal):
 1. ?x mod length (M2 \<otimes> M3) mod length M3 = ?x mod length M3 \<Longrightarrow> \<forall>i. i mod row_length (M2 \<otimes> M3) mod row_length M3 = i mod row_length M3
[PROOF STEP]
have "\<forall>i.((i mod ((row_length M2)*(row_length M3)))
                                       mod (row_length M3)
                                 = (i mod (row_length M3)))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>i. i mod (row_length M2 * row_length M3) mod row_length M3 = i mod row_length M3
[PROOF STEP]
using mod_prop1
[PROOF STATE]
proof (prove)
using this:
?a mod (?b * ?c) mod ?c = ?a mod ?c

goal (1 subgoal):
 1. \<forall>i. i mod (row_length M2 * row_length M3) mod row_length M3 = i mod row_length M3
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i. i mod (row_length M2 * row_length M3) mod row_length M3 = i mod row_length M3

goal (1 subgoal):
 1. ?x mod length (M2 \<otimes> M3) mod length M3 = ?x mod length M3 \<Longrightarrow> \<forall>i. i mod row_length (M2 \<otimes> M3) mod row_length M3 = i mod row_length M3
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
\<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)
\<forall>i. i mod (row_length M2 * row_length M3) mod row_length M3 = i mod row_length M3
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)
\<forall>i. i mod (row_length M2 * row_length M3) mod row_length M3 = i mod row_length M3

goal (1 subgoal):
 1. \<forall>i. i mod row_length (M2 \<otimes> M3) mod row_length M3 = i mod row_length M3
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i. i mod row_length (M2 \<otimes> M3) mod row_length M3 = i mod row_length M3

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<forall>i. i mod row_length (M2 \<otimes> M3) mod row_length M3 = i mod row_length M3

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)
\<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3
\<forall>i. i mod row_length (M2 \<otimes> M3) mod row_length M3 = i mod row_length M3
[PROOF STEP]
have 12:"\<forall> i j.((i < (row_length M1)
                            *(row_length M2)
                            *(row_length M3))
                            \<and>(j < (length M1)*(length M2)*(length M3) )
                       \<longrightarrow>
                          (((M2 \<otimes> M3))!(j mod (length (M2 \<otimes> M3)))
                                       !(i mod row_length (M2 \<otimes> M3)))
                = f
                   ((M2)!((j mod (length (M2 \<otimes> M3))) div (length M3))
                        !((i mod (row_length (M2 \<otimes> M3))) div (row_length M3)))
                   (M3!(j mod  (length M3))!(i mod (row_length M3))))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length (M2 \<otimes> M3) mod length M3) ! (i mod row_length (M2 \<otimes> M3) mod row_length M3)
\<forall>j. j mod length (M2 \<otimes> M3) mod length M3 = j mod length M3
\<forall>i. i mod row_length (M2 \<otimes> M3) mod row_length M3 = i mod row_length M3

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have "\<forall>j.(j mod (length (M2 \<otimes> M3))) div (length M3)
                    = (j div (length M3)) mod (length M2)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>j. j mod length (M2 \<otimes> M3) div length M3 = j div length M3 mod length M2
[PROOF STEP]
proof-
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<forall>j. j mod length (M2 \<otimes> M3) div length M3 = j div length M3 mod length M2
[PROOF STEP]
have "\<forall>j.((j mod (length (M2 \<otimes> M3)))
                    = (j mod ((length M2)*(length M3))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)
[PROOF STEP]
using length_Tensor
[PROOF STATE]
proof (prove)
using this:
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0

goal (1 subgoal):
 1. \<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)

goal (1 subgoal):
 1. \<forall>j. j mod length (M2 \<otimes> M3) div length M3 = j div length M3 mod length M2
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)

goal (1 subgoal):
 1. \<forall>j. j mod length (M2 \<otimes> M3) div length M3 = j div length M3 mod length M2
[PROOF STEP]
using mod_div_relation
[PROOF STATE]
proof (prove)
using this:
\<forall>j. j mod length (M2 \<otimes> M3) = j mod (length M2 * length M3)
?a mod (?b * ?c) div ?c = ?a div ?c mod ?b

goal (1 subgoal):
 1. \<forall>j. j mod length (M2 \<otimes> M3) div length M3 = j div length M3 mod length M2
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>j. j mod length (M2 \<otimes> M3) div length M3 = j div length M3 mod length M2

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<forall>j. j mod length (M2 \<otimes> M3) div length M3 = j div length M3 mod length M2

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
\<forall>j. j mod length (M2 \<otimes> M3) div length M3 = j div length M3 mod length M2

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have "\<forall>i.(i mod (row_length (M2 \<otimes> M3))) div (row_length M3)
                    = (i div (row_length M3)) mod (row_length M2)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>i. i mod row_length (M2 \<otimes> M3) div row_length M3 = i div row_length M3 mod row_length M2
[PROOF STEP]
proof-
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<forall>i. i mod row_length (M2 \<otimes> M3) div row_length M3 = i div row_length M3 mod row_length M2
[PROOF STEP]
have "\<forall>i.((i mod (row_length (M2 \<otimes> M3)))
                    = (i mod ((row_length M2)*(row_length M3))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)
[PROOF STEP]
using row_length_mat
[PROOF STATE]
proof (prove)
using this:
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0

goal (1 subgoal):
 1. \<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)

goal (1 subgoal):
 1. \<forall>i. i mod row_length (M2 \<otimes> M3) div row_length M3 = i div row_length M3 mod row_length M2
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)

goal (1 subgoal):
 1. \<forall>i. i mod row_length (M2 \<otimes> M3) div row_length M3 = i div row_length M3 mod row_length M2
[PROOF STEP]
using mod_div_relation
[PROOF STATE]
proof (prove)
using this:
\<forall>i. i mod row_length (M2 \<otimes> M3) = i mod (row_length M2 * row_length M3)
?a mod (?b * ?c) div ?c = ?a div ?c mod ?b

goal (1 subgoal):
 1. \<forall>i. i mod row_length (M2 \<otimes> M3) div row_length M3 = i div row_length M3 mod row_length M2
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i. i mod row_length (M2 \<otimes> M3) div row_length M3 = i div row_length M3 mod row_length M2

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<forall>i. i mod row_length (M2 \<otimes> M3) div row_length M3 = i div row_length M3 mod row_length M2

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)
\<forall>j. j mod length (M2 \<otimes> M3) div length M3 = j div length M3 mod length M2
\<forall>i. i mod row_length (M2 \<otimes> M3) div row_length M3 = i div row_length M3 mod row_length M2
[PROOF STEP]
have "\<forall> i j.
                      ((i < (row_length M1)*(row_length M2)*(row_length M3))
                      \<and>(j < (length M1)*(length M2)*(length M3) )
             \<longrightarrow>
                 (((M2 \<otimes> M3))!(j mod (length (M2 \<otimes> M3)))
                             !(i mod row_length (M2 \<otimes> M3)))
                       = f
                          ((M2)!((j div (length M3)) mod (length M2))
                               !((i div (row_length M3)) mod (row_length M2)))
                           (M3!(j mod  (length M3))!(i mod (row_length M3))))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j mod length (M2 \<otimes> M3) div length M3) ! (i mod row_length (M2 \<otimes> M3) div row_length M3) * M3 ! (j mod length M3) ! (i mod row_length M3)
\<forall>j. j mod length (M2 \<otimes> M3) div length M3 = j div length M3 mod length M2
\<forall>i. i mod row_length (M2 \<otimes> M3) div row_length M3 = i div row_length M3 mod row_length M2

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
with 7
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div length (M2 \<otimes> M3)) ! (i div row_length (M2 \<otimes> M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
have 13:"\<forall>i j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
                \<longrightarrow>
            ((M1 \<otimes> (M2 \<otimes> M3))!j!i)
                = f
                   ((M1)!(j div ((length M2)*(length  M3)))
                        !(i div ((row_length M2)*(row_length M3))))
                  (f
       ((M2)!((j div (length M3)) mod (length M2))!((i div (row_length M3)) mod (row_length M2)))
       (M3!(j mod  (length M3))
           !(i mod (row_length M3)))))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div length (M2 \<otimes> M3)) ! (i div row_length (M2 \<otimes> M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3))
[PROOF STEP]
using length_Tensor row_length_mat
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div length (M2 \<otimes> M3)) ! (i div row_length (M2 \<otimes> M3)) * (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3))
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M2 \<otimes> M3) ! (j mod length (M2 \<otimes> M3)) ! (i mod row_length (M2 \<otimes> M3)) = M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3))

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3))

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have "\<forall> i j.( f
                    ((M1)!(j div ((length M2)*(length  M3)))
                        !(i div ((row_length M2)*(row_length M3))))
                  (f
                   ((M2)!((j div (length M3)) mod (length M2))!((i div (row_length M3)) mod (row_length M2)))
       (M3!(j mod  (length M3))
           !(i mod (row_length M3)))))
           = f (f
                    ((M1)!(j div ((length M2)*(length  M3)))
                        !(i div ((row_length M2)*(row_length M3))))
                    ((M2)!((j div (length M3)) mod (length M2))
                         !((i div (row_length M3)) mod (row_length M2))))
                (M3!(j mod  (length M3))
                   !(i mod (row_length M3)))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>i j. M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)) = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
using assoc
[PROOF STATE]
proof (prove)
using this:
?a * ?b * ?c = ?a * (?b * ?c)

goal (1 subgoal):
 1. \<forall>i j. M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)) = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)) = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
with 13
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3))
\<forall>i j. M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)) = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
have "\<forall>i j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
                \<longrightarrow>
            ((M1 \<otimes> (M2 \<otimes> M3))!j!i)
                = f (f
                    ((M1)!(j div ((length M2)*(length  M3)))
                        !(i div ((row_length M2)*(row_length M3))))
                    ((M2)!((j div (length M3)) mod (length M2))
                         !((i div (row_length M3)) mod (row_length M2))))
                (M3!(j mod  (length M3))
                   !(i mod (row_length M3))))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3))
\<forall>i j. M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)) = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
with step1
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
[PROOF STEP]
have step2:
       "\<forall>i j.(((i<((row_length M1)*(row_length M2)*(row_length M3)))
       \<and>(j < (length M1)*(length M2)*(length M3)))
                \<longrightarrow>
            ((M1 \<otimes> (M2 \<otimes> M3))!j!i) = (((M1 \<otimes> M2) \<otimes> M3)!j!i))"
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> M2 \<otimes> M3) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3)

goal (1 subgoal):
 1. \<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = (M1 \<otimes> M2 \<otimes> M3) ! j ! i
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = (M1 \<otimes> M2 \<otimes> M3) ! j ! i

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = (M1 \<otimes> M2 \<otimes> M3) ! j ! i

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have "mat ((row_length M1)*(row_length M2)*(row_length M3))
           ((length M1)*(length M2)*(length M3))
               (M1 \<otimes> (M2 \<otimes> M3))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))
[PROOF STEP]
proof-
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))
[PROOF STEP]
have "mat ((row_length M2)*(row_length M3)) ((length M2)*(length M3)) (M2 \<otimes> M3)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. mat (row_length M2 * row_length M3) (length M2 * length M3) (M2 \<otimes> M3)
[PROOF STEP]
using 0 effective_well_defined_Tensor  row_length_mat length_Tensor
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3
\<lbrakk>mat (row_length ?M1.0) (length ?M1.0) ?M1.0; mat (row_length ?M2.0) (length ?M2.0) ?M2.0\<rbrakk> \<Longrightarrow> mat (row_length ?M1.0 * row_length ?M2.0) (length ?M1.0 * length ?M2.0) (?M1.0 \<otimes> ?M2.0)
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0

goal (1 subgoal):
 1. mat (row_length M2 * row_length M3) (length M2 * length M3) (M2 \<otimes> M3)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
mat (row_length M2 * row_length M3) (length M2 * length M3) (M2 \<otimes> M3)

goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
mat (row_length M2 * row_length M3) (length M2 * length M3) (M2 \<otimes> M3)

goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))
[PROOF STEP]
have  "mat ((row_length M1)*((row_length (M2 \<otimes> M3))))
           ((length M1)*((length (M2 \<otimes> M3))))
               (M1 \<otimes> (M2 \<otimes> M3))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. mat (row_length M1 * row_length (M2 \<otimes> M3)) (length M1 * length (M2 \<otimes> M3)) (M1 \<otimes> (M2 \<otimes> M3))
[PROOF STEP]
using  0 effective_well_defined_Tensor row_length_mat length_Tensor
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3
\<lbrakk>mat (row_length ?M1.0) (length ?M1.0) ?M1.0; mat (row_length ?M2.0) (length ?M2.0) ?M2.0\<rbrakk> \<Longrightarrow> mat (row_length ?M1.0 * row_length ?M2.0) (length ?M1.0 * length ?M2.0) (?M1.0 \<otimes> ?M2.0)
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0

goal (1 subgoal):
 1. mat (row_length M1 * row_length (M2 \<otimes> M3)) (length M1 * length (M2 \<otimes> M3)) (M1 \<otimes> (M2 \<otimes> M3))
[PROOF STEP]
by metis
[PROOF STATE]
proof (state)
this:
mat (row_length M1 * row_length (M2 \<otimes> M3)) (length M1 * length (M2 \<otimes> M3)) (M1 \<otimes> (M2 \<otimes> M3))

goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
mat (row_length M2 * row_length M3) (length M2 * length M3) (M2 \<otimes> M3)
mat (row_length M1 * row_length (M2 \<otimes> M3)) (length M1 * length (M2 \<otimes> M3)) (M1 \<otimes> (M2 \<otimes> M3))
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
mat (row_length M2 * row_length M3) (length M2 * length M3) (M2 \<otimes> M3)
mat (row_length M1 * row_length (M2 \<otimes> M3)) (length M1 * length (M2 \<otimes> M3)) (M1 \<otimes> (M2 \<otimes> M3))

goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))
[PROOF STEP]
using row_length_mat length_Tensor mult.assoc
[PROOF STATE]
proof (prove)
using this:
mat (row_length M2 * row_length M3) (length M2 * length M3) (M2 \<otimes> M3)
mat (row_length M1 * row_length (M2 \<otimes> M3)) (length M1 * length (M2 \<otimes> M3)) (M1 \<otimes> (M2 \<otimes> M3))
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0
Matrix_Tensor.mult ?id ?f \<Longrightarrow> ?f (?f ?a ?b) ?c = ?f ?a (?f ?b ?c)

goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))
[PROOF STEP]
by (simp add: length_Tensor row_length_mat  semigroup_mult_class.mult.assoc)
[PROOF STATE]
proof (state)
this:
mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
have "mat ((row_length M1)*(row_length M2)*(row_length M3))
           ((length M1)*(length M2)*(length M3))
               ((M1 \<otimes> M2) \<otimes> M3)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)
[PROOF STEP]
proof-
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)
[PROOF STEP]
have "mat ((row_length M1)*(row_length M2)) ((length M1)*(length M2)) (M1 \<otimes> M2)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. mat (row_length M1 * row_length M2) (length M1 * length M2) (M1 \<otimes> M2)
[PROOF STEP]
using 0 effective_well_defined_Tensor row_length_mat length_Tensor
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3
\<lbrakk>mat (row_length ?M1.0) (length ?M1.0) ?M1.0; mat (row_length ?M2.0) (length ?M2.0) ?M2.0\<rbrakk> \<Longrightarrow> mat (row_length ?M1.0 * row_length ?M2.0) (length ?M1.0 * length ?M2.0) (?M1.0 \<otimes> ?M2.0)
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0

goal (1 subgoal):
 1. mat (row_length M1 * row_length M2) (length M1 * length M2) (M1 \<otimes> M2)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
mat (row_length M1 * row_length M2) (length M1 * length M2) (M1 \<otimes> M2)

goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
mat (row_length M1 * row_length M2) (length M1 * length M2) (M1 \<otimes> M2)

goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)
[PROOF STEP]
have  "mat ((row_length (M1 \<otimes> M2))*(row_length M3))
           ((length (M1 \<otimes> M2))*(length M3))
               ((M1 \<otimes> M2 )\<otimes> M3)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. mat (row_length (M1 \<otimes> M2) * row_length M3) (length (M1 \<otimes> M2) * length M3) (M1 \<otimes> M2 \<otimes> M3)
[PROOF STEP]
using  0 effective_well_defined_Tensor  row_length_mat length_Tensor
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3
\<lbrakk>mat (row_length ?M1.0) (length ?M1.0) ?M1.0; mat (row_length ?M2.0) (length ?M2.0) ?M2.0\<rbrakk> \<Longrightarrow> mat (row_length ?M1.0 * row_length ?M2.0) (length ?M1.0 * length ?M2.0) (?M1.0 \<otimes> ?M2.0)
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0

goal (1 subgoal):
 1. mat (row_length (M1 \<otimes> M2) * row_length M3) (length (M1 \<otimes> M2) * length M3) (M1 \<otimes> M2 \<otimes> M3)
[PROOF STEP]
by metis
[PROOF STATE]
proof (state)
this:
mat (row_length (M1 \<otimes> M2) * row_length M3) (length (M1 \<otimes> M2) * length M3) (M1 \<otimes> M2 \<otimes> M3)

goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
mat (row_length M1 * row_length M2) (length M1 * length M2) (M1 \<otimes> M2)
mat (row_length (M1 \<otimes> M2) * row_length M3) (length (M1 \<otimes> M2) * length M3) (M1 \<otimes> M2 \<otimes> M3)
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1 * row_length M2) (length M1 * length M2) (M1 \<otimes> M2)
mat (row_length (M1 \<otimes> M2) * row_length M3) (length (M1 \<otimes> M2) * length M3) (M1 \<otimes> M2 \<otimes> M3)

goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)
[PROOF STEP]
using row_length_mat length_Tensor
[PROOF STATE]
proof (prove)
using this:
mat (row_length M1 * row_length M2) (length M1 * length M2) (M1 \<otimes> M2)
mat (row_length (M1 \<otimes> M2) * row_length M3) (length (M1 \<otimes> M2) * length M3) (M1 \<otimes> M2 \<otimes> M3)
row_length (?m1.0 \<otimes> ?m2.0) = row_length ?m1.0 * row_length ?m2.0
length (?M1.0 \<otimes> ?M2.0) = length ?M1.0 * length ?M2.0

goal (1 subgoal):
 1. mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)
[PROOF STEP]
by (metis mult.assoc)
[PROOF STATE]
proof (state)
this:
mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)

goal (1 subgoal):
 1. mat (row_length M1) (length M1) M1 \<and> mat (row_length M2) (length M2) M2 \<and> mat (row_length M3) (length M3) M3 \<Longrightarrow> M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3))
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = (M1 \<otimes> M2 \<otimes> M3) ! j ! i
mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))
mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3))
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = (M1 \<otimes> M2 \<otimes> M3) ! j ! i
mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))
mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)

goal (1 subgoal):
 1. M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
using mat_eqI
[PROOF STATE]
proof (prove)
using this:
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = M1 ! (j div (length M2 * length M3)) ! (i div (row_length M2 * row_length M3)) * (M2 ! (j div length M3 mod length M2) ! (i div row_length M3 mod row_length M2) * M3 ! (j mod length M3) ! (i mod row_length M3))
\<forall>i j. i < row_length M1 * row_length M2 * row_length M3 \<and> j < length M1 * length M2 * length M3 \<longrightarrow> (M1 \<otimes> (M2 \<otimes> M3)) ! j ! i = (M1 \<otimes> M2 \<otimes> M3) ! j ! i
mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> (M2 \<otimes> M3))
mat (row_length M1 * row_length M2 * row_length M3) (length M1 * length M2 * length M3) (M1 \<otimes> M2 \<otimes> M3)
\<lbrakk>mat ?nr ?nc ?m1.0; mat ?nr ?nc ?m2.0; \<And>i j. \<lbrakk>i < ?nc; j < ?nr\<rbrakk> \<Longrightarrow> ?m1.0 ! i ! j = ?m2.0 ! i ! j\<rbrakk> \<Longrightarrow> ?m1.0 = ?m2.0

goal (1 subgoal):
 1. M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
M1 \<otimes> (M2 \<otimes> M3) = M1 \<otimes> M2 \<otimes> M3

goal:
No subgoals!
[PROOF STEP]
qed