(* Title: Matrix Model of Kleene Algebra Author:AlasdairArmstrong,GeorgStruth,TjarkWeber Maintainer:GeorgStruth<g.struthatsheffield.ac.uk> TjarkWeber<tjark.weberatit.uu.se>
*)
section‹Matrices›
theory Matrix imports"HOL-Library.Word" Dioid begin
text‹In this section we formalise a perhaps more natural version of
of fixed dimension ($m \times n$-matrices). It is well known
such matrices over a Kleene algebra form a Kleene
~cite‹"conway71regular"›.›
subsection‹Type Definition›
typedef (overloaded) 'a atMost = "{..<LENGTH('a::len)}" by auto
declare Rep_atMost_inject [simp]
lemma UNIV_atMost: "(UNIV::'a atMost set) = Abs_atMost ` {..<LENGTH('a::len)}" apply auto apply (rule Abs_atMost_induct) apply auto done
text‹Our matrix type is similar to \mbox{‹'a^'n^'m›} from \em HOL/Multivariate\_Analysis/Finite\_Cartesian\_Product.thy}, but
i)~we explicitly define a type constructor for matrices and square
, and (ii)~in the definition of operations, e.g., matrix
, we impose weaker sort requirements on the element
.›
fun sqmatrix_of_matrix where "sqmatrix_of_matrix (Matrix A) = SqMatrix A"
fun matrix_of_sqmatrix where "matrix_of_sqmatrix (SqMatrix A) = Matrix A"
subsection‹0 and 1›
instantiation matrix :: (zero,type,type) zero begin definition zero_matrix_def: "0 ≡ Matrix (λi j. 0)" instance .. end
instantiation sqmatrix :: (zero,type) zero begin definition zero_sqmatrix_def: "0 ≡ SqMatrix (λi j. 0)" instance .. end
text‹Tricky sort issues: compare @{term one_matrix} with @{term
} \dots›
instantiation matrix :: ("{zero,one}",len,len) one begin definition one_matrix_def: "1 ≡ Matrix (λi j. if Rep_atMost i = Rep_atMost j then 1 else 0)" instance .. end
instantiation sqmatrix :: ("{zero,one}",type) one begin definition one_sqmatrix_def: "1 ≡ SqMatrix (λi j. if i = j then 1 else 0)" instance .. end
subsection‹Matrix Addition›
fun matrix_plus where "matrix_plus (Matrix A) (Matrix B) = Matrix (λi j. A i j + B i j)"
instantiation matrix :: (plus,type,type) plus begin definition plus_matrix_def: "A + B ≡ matrix_plus A B" instance .. end
lemma plus_matrix_def' [simp]: "Matrix A + Matrix B = Matrix (λi j. A i j + B i j)" by (simp add: plus_matrix_def)
instantiation sqmatrix :: (plus,type) plus begin definition plus_sqmatrix_def: "A + B ≡ sqmatrix_of_matrix (matrix_of_sqmatrix A + matrix_of_sqmatrix B)" instance .. end
lemma plus_sqmatrix_def' [simp]: "SqMatrix A + SqMatrix B = SqMatrix (λi j. A i j + B i j)" by (simp add: plus_sqmatrix_def)
lemma matrix_add_0_right [simp]: "A + 0 = (A::('a::monoid_add,'m,'n) matrix)" by (cases A, simp add: zero_matrix_def)
lemma matrix_add_0_left [simp]: "0 + A = (A::('a::monoid_add,'m,'n) matrix)" by (cases A, simp add: zero_matrix_def)
lemma matrix_add_commute [simp]: "(A::('a::ab_semigroup_add,'m,'n) matrix) + B = B + A" by (cases A, cases B, simp add: add.commute)
lemma matrix_add_assoc: "(A::('a::semigroup_add,'m,'n) matrix) + B + C = A + (B + C)" by (cases A, cases B, cases C, simp add: add.assoc)
lemma matrix_add_left_commute [simp]: "(A::('a::ab_semigroup_add,'m,'n) matrix) + (B + C) = B + (A + C)" by (metis matrix_add_assoc matrix_add_commute)
lemma sqmatrix_add_0_right [simp]: "A + 0 = (A::('a::monoid_add,'m) sqmatrix)" by (cases A, simp add: zero_sqmatrix_def)
lemma sqmatrix_add_0_left [simp]: "0 + A = (A::('a::monoid_add,'m) sqmatrix)" by (cases A, simp add: zero_sqmatrix_def)
lemma sqmatrix_add_commute [simp]: "(A::('a::ab_semigroup_add,'m) sqmatrix) + B = B + A" by (cases A, cases B, simp add: add.commute)
lemma sqmatrix_add_assoc: "(A::('a::semigroup_add,'m) sqmatrix) + B + C = A + (B + C)" by (cases A, cases B, cases C, simp add: add.assoc)
lemma sqmatrix_add_left_commute [simp]: "(A::('a::ab_semigroup_add,'m) sqmatrix) + (B + C) = B + (A + C)" by (metis sqmatrix_add_commute sqmatrix_add_assoc)
subsection‹Order (via Addition)›
instantiation matrix :: (plus,type,type) plus_ord begin definition less_eq_matrix_def: "(A::('a, 'b, 'c) matrix) ≤ B ≡ A + B = B" definition less_matrix_def: "(A::('a, 'b, 'c) matrix) < B ≡ A ≤ B ∧ A ≠ B"
instance proof fix A B :: "('a, 'b, 'c) matrix" show"A ≤ B ⟷ A + B = B" by (metis less_eq_matrix_def) show"A < B ⟷ A ≤ B ∧ A ≠ B" by (metis less_matrix_def) qed end
instantiation sqmatrix :: (plus,type) plus_ord begin definition less_eq_sqmatrix_def: "(A::('a, 'b) sqmatrix) ≤ B ≡ A + B = B" definition less_sqmatrix_def: "(A::('a, 'b) sqmatrix) < B ≡ A ≤ B ∧ A ≠ B"
instance proof fix A B :: "('a, 'b) sqmatrix" show"A ≤ B ⟷ A + B = B" by (metis less_eq_sqmatrix_def) show"A < B ⟷ A ≤ B ∧ A ≠ B" by (metis less_sqmatrix_def) qed end
subsection‹Matrix Multiplication›
fun matrix_times :: "('a::{comm_monoid_add,times},'m,'k) matrix ==> ('a,'k,'n) matrix ==> ('a,'m,'n) matrix"where "matrix_times (Matrix A) (Matrix B) = Matrix (λi j. sum (λk. A i k * B k j) (UNIV::'k atMost set))"
notation matrix_times (infixl‹*M›70)
instantiation sqmatrix :: ("{comm_monoid_add,times}",type) times begin definition times_sqmatrix_def: "A * B = sqmatrix_of_matrix (matrix_of_sqmatrix A *M matrix_of_sqmatrix B)" instance .. end
lemma times_sqmatrix_def' [simp]: "SqMatrix A * SqMatrix B = SqMatrix (λi j. sum (λk. A i k * B k j) (UNIV::'k atMost set))" by (simp add: times_sqmatrix_def)
lemma matrix_mult_0_right [simp]: "(A::('a::{comm_monoid_add,mult_zero},'m,'n) matrix) *M 0 = 0" by (cases A, simp add: zero_matrix_def)
lemma matrix_mult_0_left [simp]: "0 *M (A::('a::{comm_monoid_add,mult_zero},'m,'n) matrix) = 0" by (cases A, simp add: zero_matrix_def)
lemma sum_delta_r_0 [simp]: "[ finite S; j ∉ S ]==> (∑k∈S. f k * (if k = j then 1 else (0::'b::{semiring_0,monoid_mult}))) = 0" by (induct S rule: finite_induct, auto)
lemma sum_delta_r_1 [simp]: "[ finite S; j ∈ S ]==> (∑k∈S. f k * (if k = j then 1 else (0::'b::{semiring_0,monoid_mult}))) = f j" by (induct S rule: finite_induct, auto)
lemma matrix_mult_1_right [simp]: "(A::('a::{semiring_0,monoid_mult},'m::len,'n::len) matrix) *M 1 = A" by (cases A, simp add: one_matrix_def)
lemma sum_delta_l_0 [simp]: "[ finite S; i ∉ S ]==> (∑k∈S. (if i = k then 1 else (0::'b::{semiring_0,monoid_mult})) * f k j) = 0" by (induct S rule: finite_induct, auto)
lemma sum_delta_l_1 [simp]: "[ finite S; i ∈ S ]==> (∑k∈S. (if i = k then 1 else (0::'b::{semiring_0,monoid_mult})) * f k j) = f i j" by (induct S rule: finite_induct, auto)
lemma matrix_mult_1_left [simp]: "1 *M (A::('a::{semiring_0,monoid_mult},'m::len,'n::len) matrix) = A" by (cases A, simp add: one_matrix_def)
lemma matrix_mult_assoc: "(A::('a::semiring_0,'m,'n) matrix) *M B *M C = A *M (B *M C)" apply (cases A) apply (cases B) apply (cases C) apply (simp add: sum_distrib_right sum_distrib_left mult.assoc) apply (subst sum.swap) apply (rule refl) done
lemma matrix_mult_distrib_left: "(A::('a::{comm_monoid_add,semiring},'m,'n::len) matrix) *M (B + C) = A *M B + A *M C" by (cases A, cases B, cases C, simp add: distrib_left sum.distrib)
lemma matrix_mult_distrib_right: "((A::('a::{comm_monoid_add,semiring},'m,'n::len) matrix) + B) *M C = A *M C + B *M C" by (cases A, cases B, cases C, simp add: distrib_right sum.distrib)
lemma sqmatrix_mult_0_right [simp]: "(A::('a::{comm_monoid_add,mult_zero},'m) sqmatrix) * 0 = 0" by (cases A, simp add: zero_sqmatrix_def)
lemma sqmatrix_mult_0_left [simp]: "0 * (A::('a::{comm_monoid_add,mult_zero},'m) sqmatrix) = 0" by (cases A, simp add: zero_sqmatrix_def)
lemma sqmatrix_mult_1_right [simp]: "(A::('a::{semiring_0,monoid_mult},'m::len) sqmatrix) * 1 = A" by (cases A, simp add: one_sqmatrix_def)
lemma sqmatrix_mult_1_left [simp]: "1 * (A::('a::{semiring_0,monoid_mult},'m::len) sqmatrix) = A" by (cases A, simp add: one_sqmatrix_def)
lemma sqmatrix_mult_assoc: "(A::('a::{semiring_0,monoid_mult},'m) sqmatrix) * B * C = A * (B * C)" apply (cases A) apply (cases B) apply (cases C) apply (simp add: sum_distrib_right sum_distrib_left mult.assoc) apply (subst sum.swap) apply (rule refl) done
lemma sqmatrix_mult_distrib_left: "(A::('a::{comm_monoid_add,semiring},'m::len) sqmatrix) * (B + C) = A * B + A * C" by (cases A, cases B, cases C, simp add: distrib_left sum.distrib)
lemma sqmatrix_mult_distrib_right: "((A::('a::{comm_monoid_add,semiring},'m::len) sqmatrix) + B) * C = A * C + B * C" by (cases A, cases B, cases C, simp add: distrib_right sum.distrib)
subsection‹Square-Matrix Model of Dioids›
text‹The following subclass proofs are necessary to connect parts
our algebraic hierarchy to the hierarchy found in the Isabelle/HOL
.›
subclass (in ab_near_semiring_one_zerol) comm_monoid_add proof fix a :: 'a show"0 + a = a" by (fact add_zerol) qed
subclass (in semiring_one_zero) semiring_0 proof fix a :: 'a show"0 * a = 0" by (fact annil) show"a * 0 = 0" by (fact annir) qed
subclass (in ab_near_semiring_one) monoid_mult ..
instantiation sqmatrix :: (dioid_one_zero,len) dioid_one_zero begin instance proof fix A B C :: "('a, 'b) sqmatrix" show"A + B + C = A + (B + C)" by (fact sqmatrix_add_assoc) show"A + B = B + A" by (fact sqmatrix_add_commute) show"A * B * C = A * (B * C)" by (fact sqmatrix_mult_assoc) show"(A + B) * C = A * C + B * C" by (fact sqmatrix_mult_distrib_right) show"1 * A = A" by (fact sqmatrix_mult_1_left) show"A * 1 = A" by (fact sqmatrix_mult_1_right) show"0 + A = A" by (fact sqmatrix_add_0_left) show"0 * A = 0" by (fact sqmatrix_mult_0_left) show"A * 0 = 0" by (fact sqmatrix_mult_0_right) show"A + A = A" by (cases A, simp) show"A * (B + C) = A * B + A * C" by (fact sqmatrix_mult_distrib_left) qed end
subsection‹Kleene Star for Matrices›
text‹We currently do not implement the Kleene star of matrices,
this is complicated.›
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.