src/HOL/Matrix/MatrixGeneral.thy
changeset 15481 fc075ae929e4
parent 15392 290bc97038c7
child 15485 e93a3badc2bc
equal deleted inserted replaced
15480:cb3612cc41a3 15481:fc075ae929e4
   697       fix u::"'b matrix"
   697       fix u::"'b matrix"
   698       fix v::"'b matrix"
   698       fix v::"'b matrix"
   699       let ?mx = "max (ncols a) (max (nrows u) (nrows v))"
   699       let ?mx = "max (ncols a) (max (nrows u) (nrows v))"
   700       from prems show "mult_matrix_n (max (ncols a) (nrows (combine_matrix fadd u v))) fmul fadd a (combine_matrix fadd u v) =
   700       from prems show "mult_matrix_n (max (ncols a) (nrows (combine_matrix fadd u v))) fmul fadd a (combine_matrix fadd u v) =
   701         combine_matrix fadd (mult_matrix_n (max (ncols a) (nrows u)) fmul fadd a u) (mult_matrix_n (max (ncols a) (nrows v)) fmul fadd a v)"
   701         combine_matrix fadd (mult_matrix_n (max (ncols a) (nrows u)) fmul fadd a u) (mult_matrix_n (max (ncols a) (nrows v)) fmul fadd a v)"
   702         apply (subst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   702         apply (simplesubst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   703         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   703         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   704         apply (subst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   704         apply (simplesubst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   705         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   705         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   706         apply (subst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   706         apply (simplesubst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   707         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   707         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   708         apply (simp add: mult_matrix_n_def r_distributive_def foldseq_distr[of fadd])
   708         apply (simp add: mult_matrix_n_def r_distributive_def foldseq_distr[of fadd])
   709         apply (simp add: combine_matrix_def combine_infmatrix_def)
   709         apply (simp add: combine_matrix_def combine_infmatrix_def)
   710         apply (rule comb[of "Abs_matrix" "Abs_matrix"], simp, (rule ext)+)
   710         apply (rule comb[of "Abs_matrix" "Abs_matrix"], simp, (rule ext)+)
   711         apply (subst RepAbs_matrix)
   711         apply (simplesubst RepAbs_matrix)
   712         apply (simp, auto)
   712         apply (simp, auto)
   713         apply (rule exI[of _ "nrows a"], simp add: nrows_le foldseq_zero)
   713         apply (rule exI[of _ "nrows a"], simp add: nrows_le foldseq_zero)
   714         apply (rule exI[of _ "ncols v"], simp add: ncols_le foldseq_zero)
   714         apply (rule exI[of _ "ncols v"], simp add: ncols_le foldseq_zero)
   715         apply (subst RepAbs_matrix)
   715         apply (subst RepAbs_matrix)
   716         apply (simp, auto)
   716         apply (simp, auto)
   737       fix u::"'a matrix"
   737       fix u::"'a matrix"
   738       fix v::"'a matrix"
   738       fix v::"'a matrix"
   739       let ?mx = "max (nrows a) (max (ncols u) (ncols v))"
   739       let ?mx = "max (nrows a) (max (ncols u) (ncols v))"
   740       from prems show "mult_matrix_n (max (ncols (combine_matrix fadd u v)) (nrows a)) fmul fadd (combine_matrix fadd u v) a =
   740       from prems show "mult_matrix_n (max (ncols (combine_matrix fadd u v)) (nrows a)) fmul fadd (combine_matrix fadd u v) a =
   741                combine_matrix fadd (mult_matrix_n (max (ncols u) (nrows a)) fmul fadd u a) (mult_matrix_n (max (ncols v) (nrows a)) fmul fadd v a)"
   741                combine_matrix fadd (mult_matrix_n (max (ncols u) (nrows a)) fmul fadd u a) (mult_matrix_n (max (ncols v) (nrows a)) fmul fadd v a)"
   742         apply (subst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   742         apply (simplesubst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   743         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   743         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   744         apply (subst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   744         apply (simplesubst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   745         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   745         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   746         apply (subst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   746         apply (subst mult_matrix_nm[of _ _ _ ?mx fadd fmul])
   747         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   747         apply (simp add: max1 max2 combine_nrows combine_ncols)+
   748         apply (simp add: mult_matrix_n_def l_distributive_def foldseq_distr[of fadd])
   748         apply (simp add: mult_matrix_n_def l_distributive_def foldseq_distr[of fadd])
   749         apply (simp add: combine_matrix_def combine_infmatrix_def)
   749         apply (simp add: combine_matrix_def combine_infmatrix_def)
   750         apply (rule comb[of "Abs_matrix" "Abs_matrix"], simp, (rule ext)+)
   750         apply (rule comb[of "Abs_matrix" "Abs_matrix"], simp, (rule ext)+)
   751         apply (subst RepAbs_matrix)
   751         apply (simplesubst RepAbs_matrix)
   752         apply (simp, auto)
   752         apply (simp, auto)
   753         apply (rule exI[of _ "nrows v"], simp add: nrows_le foldseq_zero)
   753         apply (rule exI[of _ "nrows v"], simp add: nrows_le foldseq_zero)
   754         apply (rule exI[of _ "ncols a"], simp add: ncols_le foldseq_zero)
   754         apply (rule exI[of _ "ncols a"], simp add: ncols_le foldseq_zero)
   755         apply (subst RepAbs_matrix)
   755         apply (subst RepAbs_matrix)
   756         apply (simp, auto)
   756         apply (simp, auto)
   790 lemma combine_matrix_zero_r_neutral: "zero_r_neutral f \<Longrightarrow> zero_r_neutral (combine_matrix f)"
   790 lemma combine_matrix_zero_r_neutral: "zero_r_neutral f \<Longrightarrow> zero_r_neutral (combine_matrix f)"
   791   by (simp add: zero_r_neutral_def combine_matrix_def combine_infmatrix_def)
   791   by (simp add: zero_r_neutral_def combine_matrix_def combine_infmatrix_def)
   792 
   792 
   793 lemma mult_matrix_zero_closed: "\<lbrakk>fadd 0 0 = 0; zero_closed fmul\<rbrakk> \<Longrightarrow> zero_closed (mult_matrix fmul fadd)"
   793 lemma mult_matrix_zero_closed: "\<lbrakk>fadd 0 0 = 0; zero_closed fmul\<rbrakk> \<Longrightarrow> zero_closed (mult_matrix fmul fadd)"
   794   apply (simp add: zero_closed_def mult_matrix_def mult_matrix_n_def)
   794   apply (simp add: zero_closed_def mult_matrix_def mult_matrix_n_def)
   795   apply (auto)
   795   apply (simp add: foldseq_zero zero_matrix_def) 
   796   by (subst foldseq_zero, (simp add: zero_matrix_def)+)+
   796   done
       
   797 
   797 
   798 
   798 lemma mult_matrix_n_zero_right[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul a 0 = 0\<rbrakk> \<Longrightarrow> mult_matrix_n n fmul fadd A 0 = 0"
   799 lemma mult_matrix_n_zero_right[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul a 0 = 0\<rbrakk> \<Longrightarrow> mult_matrix_n n fmul fadd A 0 = 0"
   799   apply (simp add: mult_matrix_n_def)
   800   apply (simp add: mult_matrix_n_def)
   800   apply (subst foldseq_zero)
   801   apply (simp add: foldseq_zero zero_matrix_def)
   801   by (simp_all add: zero_matrix_def)
   802   done
   802 
   803 
   803 lemma mult_matrix_n_zero_left[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul 0 a = 0\<rbrakk> \<Longrightarrow> mult_matrix_n n fmul fadd 0 A = 0"
   804 lemma mult_matrix_n_zero_left[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul 0 a = 0\<rbrakk> \<Longrightarrow> mult_matrix_n n fmul fadd 0 A = 0"
   804   apply (simp add: mult_matrix_n_def)
   805   apply (simp add: mult_matrix_n_def)
   805   apply (subst foldseq_zero)
   806   apply (simp add: foldseq_zero zero_matrix_def)
   806   by (simp_all add: zero_matrix_def)
   807   done
   807 
   808 
   808 lemma mult_matrix_zero_left[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul 0 a = 0\<rbrakk> \<Longrightarrow> mult_matrix fmul fadd 0 A = 0"
   809 lemma mult_matrix_zero_left[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul 0 a = 0\<rbrakk> \<Longrightarrow> mult_matrix fmul fadd 0 A = 0"
   809 by (simp add: mult_matrix_def)
   810 by (simp add: mult_matrix_def)
   810 
   811 
   811 lemma mult_matrix_zero_right[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul a 0 = 0\<rbrakk> \<Longrightarrow> mult_matrix fmul fadd A 0 = 0"
   812 lemma mult_matrix_zero_right[simp]: "\<lbrakk>fadd 0 0 = 0; !a. fmul a 0 = 0\<rbrakk> \<Longrightarrow> mult_matrix fmul fadd A 0 = 0"
   849 apply (simp add: singleton_matrix_def)
   850 apply (simp add: singleton_matrix_def)
   850 apply (auto)
   851 apply (auto)
   851 apply (subst RepAbs_matrix)
   852 apply (subst RepAbs_matrix)
   852 apply (rule exI[of _ "Suc m"], simp)
   853 apply (rule exI[of _ "Suc m"], simp)
   853 apply (rule exI[of _ "Suc n"], simp+)
   854 apply (rule exI[of _ "Suc n"], simp+)
   854 by (subst RepAbs_matrix, rule exI[of _ "Suc j"], simp, rule exI[of _ "Suc i"], simp+)+
   855 by (simplesubst RepAbs_matrix, rule exI[of _ "Suc j"], simp, rule exI[of _ "Suc i"], simp+)+
   855 
   856 
   856 lemma apply_singleton_matrix[simp]: "f 0 = 0 \<Longrightarrow> apply_matrix f (singleton_matrix j i x) = (singleton_matrix j i (f x))"
   857 lemma apply_singleton_matrix[simp]: "f 0 = 0 \<Longrightarrow> apply_matrix f (singleton_matrix j i x) = (singleton_matrix j i (f x))"
   857 apply (subst Rep_matrix_inject[symmetric])
   858 apply (subst Rep_matrix_inject[symmetric])
   858 apply (rule ext)+
   859 apply (rule ext)+
   859 apply (simp)
   860 apply (simp)
   890 apply (subst ncols_le)
   891 apply (subst ncols_le)
   891 by simp
   892 by simp
   892 
   893 
   893 lemma combine_singleton: "f 0 0 = 0 \<Longrightarrow> combine_matrix f (singleton_matrix j i a) (singleton_matrix j i b) = singleton_matrix j i (f a b)"
   894 lemma combine_singleton: "f 0 0 = 0 \<Longrightarrow> combine_matrix f (singleton_matrix j i a) (singleton_matrix j i b) = singleton_matrix j i (f a b)"
   894 apply (simp add: singleton_matrix_def combine_matrix_def combine_infmatrix_def)
   895 apply (simp add: singleton_matrix_def combine_matrix_def combine_infmatrix_def)
   895 apply (subst RepAbs_matrix)
   896 apply (simplesubst RepAbs_matrix)
   896 apply (rule exI[of _ "Suc j"], simp)
   897 apply (rule exI[of _ "Suc j"], simp)
   897 apply (rule exI[of _ "Suc i"], simp)
   898 apply (rule exI[of _ "Suc i"], simp)
   898 apply (rule comb[of "Abs_matrix" "Abs_matrix"], simp, (rule ext)+)
   899 apply (rule comb[of "Abs_matrix" "Abs_matrix"], simp, (rule ext)+)
   899 apply (subst RepAbs_matrix)
   900 apply (subst RepAbs_matrix)
   900 apply (rule exI[of _ "Suc j"], simp)
   901 apply (rule exI[of _ "Suc j"], simp)
   909 lemma Rep_move_matrix[simp]:
   910 lemma Rep_move_matrix[simp]:
   910   "Rep_matrix (move_matrix A y x) j i =
   911   "Rep_matrix (move_matrix A y x) j i =
   911   (if (neg ((int j)-y)) | (neg ((int i)-x)) then 0 else Rep_matrix A (nat((int j)-y)) (nat((int i)-x)))"
   912   (if (neg ((int j)-y)) | (neg ((int i)-x)) then 0 else Rep_matrix A (nat((int j)-y)) (nat((int i)-x)))"
   912 apply (simp add: move_matrix_def)
   913 apply (simp add: move_matrix_def)
   913 apply (auto)
   914 apply (auto)
   914 by (subst RepAbs_matrix,
   915 by (simplesubst RepAbs_matrix,
   915   rule exI[of _ "(nrows A)+(nat (abs y))"], auto, rule nrows, arith,
   916   rule exI[of _ "(nrows A)+(nat (abs y))"], auto, rule nrows, arith,
   916   rule exI[of _ "(ncols A)+(nat (abs x))"], auto, rule ncols, arith)+
   917   rule exI[of _ "(ncols A)+(nat (abs x))"], auto, rule ncols, arith)+
   917 
   918 
   918 lemma move_matrix_0_0[simp]: "move_matrix A 0 0 = A"
   919 lemma move_matrix_0_0[simp]: "move_matrix A 0 0 = A"
   919 by (simp add: move_matrix_def)
   920 by (simp add: move_matrix_def)
   944 
   945 
   945 lemma Rep_take_columns[simp]:
   946 lemma Rep_take_columns[simp]:
   946   "Rep_matrix (take_columns A c) j i =
   947   "Rep_matrix (take_columns A c) j i =
   947   (if i < c then (Rep_matrix A j i) else 0)"
   948   (if i < c then (Rep_matrix A j i) else 0)"
   948 apply (simp add: take_columns_def)
   949 apply (simp add: take_columns_def)
   949 apply (subst RepAbs_matrix)
   950 apply (simplesubst RepAbs_matrix)
   950 apply (rule exI[of _ "nrows A"], auto, simp add: nrows_le)
   951 apply (rule exI[of _ "nrows A"], auto, simp add: nrows_le)
   951 apply (rule exI[of _ "ncols A"], auto, simp add: ncols_le)
   952 apply (rule exI[of _ "ncols A"], auto, simp add: ncols_le)
   952 done
   953 done
   953 
   954 
   954 lemma Rep_take_rows[simp]:
   955 lemma Rep_take_rows[simp]:
   955   "Rep_matrix (take_rows A r) j i =
   956   "Rep_matrix (take_rows A r) j i =
   956   (if j < r then (Rep_matrix A j i) else 0)"
   957   (if j < r then (Rep_matrix A j i) else 0)"
   957 apply (simp add: take_rows_def)
   958 apply (simp add: take_rows_def)
   958 apply (subst RepAbs_matrix)
   959 apply (simplesubst RepAbs_matrix)
   959 apply (rule exI[of _ "nrows A"], auto, simp add: nrows_le)
   960 apply (rule exI[of _ "nrows A"], auto, simp add: nrows_le)
   960 apply (rule exI[of _ "ncols A"], auto, simp add: ncols_le)
   961 apply (rule exI[of _ "ncols A"], auto, simp add: ncols_le)
   961 done
   962 done
   962 
   963 
   963 lemma Rep_column_of_matrix[simp]:
   964 lemma Rep_column_of_matrix[simp]:
  1161   let ?N = "max (ncols A) (max (ncols B) (max (nrows B) (nrows C)))"
  1162   let ?N = "max (ncols A) (max (ncols B) (max (nrows B) (nrows C)))"
  1162   show ?concl
  1163   show ?concl
  1163     apply (simp add: Rep_matrix_inject[THEN sym])
  1164     apply (simp add: Rep_matrix_inject[THEN sym])
  1164     apply (rule ext)+
  1165     apply (rule ext)+
  1165     apply (simp add: mult_matrix_def)
  1166     apply (simp add: mult_matrix_def)
  1166     apply (subst mult_matrix_nm[of _ "max (ncols (mult_matrix_n (max (ncols A) (nrows B)) fmul1 fadd1 A B)) (nrows C)" _ "max (ncols B) (nrows C)"])
  1167     apply (simplesubst mult_matrix_nm[of _ "max (ncols (mult_matrix_n (max (ncols A) (nrows B)) fmul1 fadd1 A B)) (nrows C)" _ "max (ncols B) (nrows C)"])
  1167     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1168     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1168     apply (subst mult_matrix_nm[of _ "max (ncols A) (nrows (mult_matrix_n (max (ncols B) (nrows C)) fmul2 fadd2 B C))" _ "max (ncols A) (nrows B)"])     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1169     apply (simplesubst mult_matrix_nm[of _ "max (ncols A) (nrows (mult_matrix_n (max (ncols B) (nrows C)) fmul2 fadd2 B C))" _ "max (ncols A) (nrows B)"])     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1169     apply (subst mult_matrix_nm[of _ _ _ "?N"])
  1170     apply (simplesubst mult_matrix_nm[of _ _ _ "?N"])
  1170     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1171     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1171     apply (subst mult_matrix_nm[of _ _ _ "?N"])
  1172     apply (simplesubst mult_matrix_nm[of _ _ _ "?N"])
  1172     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1173     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1173     apply (subst mult_matrix_nm[of _ _ _ "?N"])
  1174     apply (simplesubst mult_matrix_nm[of _ _ _ "?N"])
  1174     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1175     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1175     apply (subst mult_matrix_nm[of _ _ _ "?N"])
  1176     apply (simplesubst mult_matrix_nm[of _ _ _ "?N"])
  1176     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1177     apply (simp add: max1 max2 mult_n_ncols mult_n_nrows prems)+
  1177     apply (simp add: mult_matrix_n_def)
  1178     apply (simp add: mult_matrix_n_def)
  1178     apply (rule comb_left)
  1179     apply (rule comb_left)
  1179     apply ((rule ext)+, simp)
  1180     apply ((rule ext)+, simp)
  1180     apply (subst RepAbs_matrix)
  1181     apply (simplesubst RepAbs_matrix)
  1181     apply (rule exI[of _ "nrows B"])
  1182     apply (rule exI[of _ "nrows B"])
  1182     apply (simp add: nrows prems foldseq_zero)
  1183     apply (simp add: nrows prems foldseq_zero)
  1183     apply (rule exI[of _ "ncols C"])
  1184     apply (rule exI[of _ "ncols C"])
  1184     apply (simp add: prems ncols foldseq_zero)
  1185     apply (simp add: prems ncols foldseq_zero)
  1185     apply (subst RepAbs_matrix)
  1186     apply (subst RepAbs_matrix)
  1225   shows "mult_matrix fmul fadd (mult_matrix fmul fadd A B) C = mult_matrix fmul fadd A (mult_matrix fmul fadd B C)" (is ?concl)
  1226   shows "mult_matrix fmul fadd (mult_matrix fmul fadd A B) C = mult_matrix fmul fadd A (mult_matrix fmul fadd B C)" (is ?concl)
  1226 proof -
  1227 proof -
  1227   have "!! a b c d. fadd (fadd a b) (fadd c d) = fadd (fadd a c) (fadd b d)"
  1228   have "!! a b c d. fadd (fadd a b) (fadd c d) = fadd (fadd a c) (fadd b d)"
  1228     by (simp! add: associative_def commutative_def)
  1229     by (simp! add: associative_def commutative_def)
  1229   then show ?concl
  1230   then show ?concl
  1230     apply (subst mult_matrix_assoc)
  1231     apply (simplesubst mult_matrix_assoc)
  1231     apply (simp_all!)
  1232     apply (simp_all!)
  1232     by (simp add: associative_def distributive_def l_distributive_def r_distributive_def)+
  1233     by (simp add: associative_def distributive_def l_distributive_def r_distributive_def)+
  1233 qed
  1234 qed
  1234 
  1235 
  1235 lemma transpose_apply_matrix: "f 0 = 0 \<Longrightarrow> transpose_matrix (apply_matrix f A) = apply_matrix f (transpose_matrix A)"
  1236 lemma transpose_apply_matrix: "f 0 = 0 \<Longrightarrow> transpose_matrix (apply_matrix f A) = apply_matrix f (transpose_matrix A)"
  1359   "A <= B"
  1360   "A <= B"
  1360   shows
  1361   shows
  1361   "mult_matrix fmul fadd C A <= mult_matrix fmul fadd C B"
  1362   "mult_matrix fmul fadd C A <= mult_matrix fmul fadd C B"
  1362   apply (simp! add: le_matrix_def Rep_mult_matrix)
  1363   apply (simp! add: le_matrix_def Rep_mult_matrix)
  1363   apply (auto)
  1364   apply (auto)
  1364   apply (subst foldseq_zerotail[of _ _ _ "max (ncols C) (max (nrows A) (nrows B))"], simp_all add: nrows ncols max1 max2)+
  1365   apply (simplesubst foldseq_zerotail[of _ _ _ "max (ncols C) (max (nrows A) (nrows B))"], simp_all add: nrows ncols max1 max2)+
  1365   apply (rule le_foldseq)
  1366   apply (rule le_foldseq)
  1366   by (auto)
  1367   by (auto)
  1367 
  1368 
  1368 lemma le_right_mult:
  1369 lemma le_right_mult:
  1369   assumes
  1370   assumes
  1376   "A <= B"
  1377   "A <= B"
  1377   shows
  1378   shows
  1378   "mult_matrix fmul fadd A C <= mult_matrix fmul fadd B C"
  1379   "mult_matrix fmul fadd A C <= mult_matrix fmul fadd B C"
  1379   apply (simp! add: le_matrix_def Rep_mult_matrix)
  1380   apply (simp! add: le_matrix_def Rep_mult_matrix)
  1380   apply (auto)
  1381   apply (auto)
  1381   apply (subst foldseq_zerotail[of _ _ _ "max (nrows C) (max (ncols A) (ncols B))"], simp_all add: nrows ncols max1 max2)+
  1382   apply (simplesubst foldseq_zerotail[of _ _ _ "max (nrows C) (max (ncols A) (ncols B))"], simp_all add: nrows ncols max1 max2)+
  1382   apply (rule le_foldseq)
  1383   apply (rule le_foldseq)
  1383   by (auto)
  1384   by (auto)
  1384 
  1385 
  1385 lemma spec2: "! j i. P j i \<Longrightarrow> P j i" by blast
  1386 lemma spec2: "! j i. P j i \<Longrightarrow> P j i" by blast
  1386 lemma neg_imp: "(\<not> Q \<longrightarrow> \<not> P) \<Longrightarrow> P \<longrightarrow> Q" by blast
  1387 lemma neg_imp: "(\<not> Q \<longrightarrow> \<not> P) \<Longrightarrow> P \<longrightarrow> Q" by blast