1-- Explicit 3 × 3 real matrices: triples as functions on 3, the matrix2-- matrix3of(a, b, c, d, e, f, g, h, k) with the given rows as an element of3-- matrixRing(realRing, 3), its entries, and the entries of a product of4-- two 3 × 3 real matrices as sums of three terms5-- Part of Cumulus, the Grace17 mathematics library.6-- Copyright (c) 2026 Grant Passmore.7-- Released under the Apache License 2.0. See LICENSE in the repository root.8-- Authors: Grant Passmore910module Grace.Cumulus.Geometry.Absorption.Triples11import Rotation.Vectors12import Set.Tuple1314-- The index set 3 = {0, 1, 2}, as Rotation/Vectors states it.15theorem threeIndex.cases (i : Set)16requires member : i ∈317shows i =0∨ i =1∨ i =218proof19exact index.cases with member2021theorem threeIndex.zero_ne_one22shows (0:N) ≠ (1:N)23proof24exact index.zero_ne_one2526theorem threeIndex.zero_ne_two27shows (0:N) ≠ (2:N)28proof29exact index.zero_ne_two3031theorem threeIndex.one_ne_two32shows (1:N) ≠ (2:N)33proof34exact index.one_ne_two3536-- The operations of realRing read as the real operations.37theorem realRing.call_add (x y : Set)38shows call2(Ring.add(realRing), x, y) = call2(realAdd, x, y)39proof40simp [realRing, Ring.mk.add]4142theorem realRing.call_mul (x y : Set)43shows call2(Ring.mul(realRing), x, y) = call2(realMul, x, y)44proof45simp [realRing, Ring.mk.mul]4647theorem realRing.zero_eq48shows Ring.zero(realRing) = realZero49proof50simp [realRing, Ring.mk.zero]5152theorem realRing.one_eq53shows Ring.one(realRing) = realOne54proof55simp [realRing, Ring.mk.one]5657-- A finite ring sum over the index set 3 is the sum of its three terms.58theorem finiteRingSum.over_three (A add zero neg mul one w : Set)59requiresring : IsCommRing(A, add, zero, neg, mul, one)60requires weights : w : 3→ A61shows finiteRingSum(3, A, add, zero, neg, mul, one, w) =62 call2(add, call2(add, call2(add, zero, w(0)), w(1)), w(2))63proof64have enumeration := identity.bijective at365have indexed := finiteRingSum.enumeration at3, A, add, zero, neg, mul, one,66 w, identity(3), 3withring, weights, enumeration67have zeroIn : 0∈3bytypecheck68have oneIn : 1∈3bytypecheck69have twoIn : 2∈3bytypecheck70have at0 := identity.apply at0, 3with zeroIn71have at1 := identity.apply at1, 3with oneIn72have at2 := identity.apply at2, 3with twoIn73rw indexed74simp [indexedRingSum, at0, at1, at2]7576-- A triple (a, b, c) as the function on 3 with those values.77defunique tripleValue (A a b c j : Set) (v ∈ A) :=78 (j =0∧ v = a) ∨ (j =1∧ v = b) ∨ (j =2∧ v = c)79requires aIn : a ∈ A80requires bIn : b ∈ A81requires cIn : c ∈ A82requires index : j ∈383proof84have alternatives := threeIndex.cases with index85rcases alternatives with first | second | third86 . refine⟨a, aIn, ?_⟩87left88exact⟨first, rfl⟩89 . refine⟨b, bIn, ?_⟩90right91left92exact⟨second, rfl⟩93 . refine⟨c, cIn, ?_⟩94right95right96exact⟨third, rfl⟩97uniqueness98intros u hu first v hv second99have d01 := threeIndex.zero_ne_one100have d02 := threeIndex.zero_ne_two101have d12 := threeIndex.one_ne_two102rcases first with firstZero | firstOne | firstTwo103 . obtain⟨jZero, ua⟩:= firstZero104rcases second with secondZero | secondOne | secondTwo105 . obtain⟨kZero, va⟩:= secondZero106cc107 . obtain⟨kOne, vb⟩:= secondOne108exfalso109apply d01110cc111 . obtain⟨kTwo, vc⟩:= secondTwo112exfalso113apply d02114cc115 . obtain⟨jOne, ub⟩:= firstOne116rcases second with secondZero | secondOne | secondTwo117 . obtain⟨kZero, va⟩:= secondZero118exfalso119apply d01120cc121 . obtain⟨kOne, vb⟩:= secondOne122cc123 . obtain⟨kTwo, vc⟩:= secondTwo124exfalso125apply d12126cc127 . obtain⟨jTwo, uc⟩:= firstTwo128rcases second with secondZero | secondOne | secondTwo129 . obtain⟨kZero, va⟩:= secondZero130exfalso131apply d02132cc133 . obtain⟨kOne, vb⟩:= secondOne134exfalso135apply d12136cc137 . obtain⟨kTwo, vc⟩:= secondTwo138cc139140defgraph triple (A a b c : Set) (j ∈3) : A := tripleValue(A, a, b, c, j)141requires aIn : a ∈ A142requires bIn : b ∈ A143requires cIn : c ∈ A144proof145have selected := tripleValue.selected at A, a, b, c, j with*146exact selected.left147148section TripleValues149variable (A a b c : Set)150hypothesis aIn : a ∈ A151hypothesis bIn : b ∈ A152hypothesis cIn : c ∈ A153154theorem triple.zero155shows triple(A, a, b, c)(0) = a156proof157have zeroIn : 0∈3bytypecheck158have value := triple.value at A, a, b, c, 0with*159have selected := tripleValue.selected at A, a, b, c, 0with*160have d01 := threeIndex.zero_ne_one161have d02 := threeIndex.zero_ne_two162rw value163obtain⟨inA, property⟩:= selected164rcases property with same | badOne | badTwo165 . exact same.right166 . exfalso167exact d01 with badOne.left168 . exfalso169exact d02 with badTwo.left170171theorem triple.one172shows triple(A, a, b, c)(1) = b173proof174have oneIn : 1∈3bytypecheck175have value := triple.value at A, a, b, c, 1with*176have selected := tripleValue.selected at A, a, b, c, 1with*177have d01 := threeIndex.zero_ne_one178have d12 := threeIndex.one_ne_two179rw value180obtain⟨inA, property⟩:= selected181rcases property with badZero | same | badTwo182 . exfalso183have flipped := badZero.left184 symm at flipped185exact d01 with flipped186 . exact same.right187 . exfalso188exact d12 with badTwo.left189190theorem triple.two191shows triple(A, a, b, c)(2) = c192proof193have twoIn : 2∈3bytypecheck194have value := triple.value at A, a, b, c, 2with*195have selected := tripleValue.selected at A, a, b, c, 2with*196have d02 := threeIndex.zero_ne_two197have d12 := threeIndex.one_ne_two198rw value199obtain⟨inA, property⟩:= selected200rcases property with badZero | badOne | same201 . exfalso202have flipped := badZero.left203 symm at flipped204exact d02 with flipped205 . exfalso206have flipped := badOne.left207 symm at flipped208exact d12 with flipped209 . exact same.right210211end TripleValues212213-- The 3 × 3 matrix with the three given rows, rows being functions 3 → ℝ.214defgraph matrix3 (r0 r1 r2 : Set) (p ∈3×3) : ℝ :=215 triple(functionSpace(3, ℝ), r0, r1, r2)(fst(p))(snd(p))216requires row0 : r0 ∈ functionSpace(3, ℝ)217requires row1 : r1 ∈ functionSpace(3, ℝ)218requires row2 : r2 ∈ functionSpace(3, ℝ)219proof220obtain⟨bound, i, hi, j, hj, shape⟩:= product.membership.forward with member221have rows := triple.function at functionSpace(3, ℝ), r0, r1, r2 with*222rw [shape, fst.pair, snd.pair]223have rowIn := FunctionBetween.apply_closed with rows, hi224have rowFunction := functionSpace.mem_iff.forward with rowIn225exact FunctionBetween.apply_closed with rowFunction, hj226227section MatrixRows228variable (r0 r1 r2 : Set)229hypothesis row0 : r0 ∈ functionSpace(3, ℝ)230hypothesis row1 : r1 ∈ functionSpace(3, ℝ)231hypothesis row2 : r2 ∈ functionSpace(3, ℝ)232233theorem matrix3.entry (i j : Set)234requires hi : i ∈3235requires hj : j ∈3236shows matrix3(r0, r1, r2)[i, j] = triple(functionSpace(3, ℝ), r0, r1, r2)(i)(j)237proof238have pair := product.pair at i, j, 3, 3with*239have value := matrix3.value at r0, r1, r2, (i, j) with*240rw [value, fst.pair, snd.pair]241rfl242243theorem matrix3.square244shows matrix3(r0, r1, r2) ∈ squareMatrices(realRing, 3)245proof246have function := matrix3.function at r0, r1, r2 with*247rw← realRing.carrierOf at function248exact squareMatrices.of_function with function249250instance matrix3.matrix251shows matrix3(r0, r1, r2) : realRing ^ 3×3252proof253have square : matrix3(r0, r1, r2) ∈ squareMatrices(realRing, 3) := matrix3.square with*254exact Matrix.of_square with square255256end MatrixRows257258-- A row of three reals, and the matrix with nine given real entries.259def row3 (a b c : Set) : Set:= triple(ℝ, a, b, c)260def matrix3of (a b c d e f g h k : Set) : Set:=261 matrix3(row3(a, b, c), row3(d, e, f), row3(g, h, k))262263theorem row3.graph (a b c : Set)264shows row3(a, b, c) = triple(ℝ, a, b, c)265proof266simp [row3]267268theorem matrix3of.graph (a b c d e f g h k : Set)269shows matrix3of(a, b, c, d, e, f, g, h, k) =270 matrix3(row3(a, b, c), row3(d, e, f), row3(g, h, k))271proof272simp [matrix3of]273274instance row3.member (a b c : Real)275shows row3(a, b, c) ∈ functionSpace(3, ℝ)276proof277have function := triple.function at ℝ, a, b, c with*278rw row3.graph279exact functionSpace.mem_iff.backward with function280281section Entries282variable (a b c d e f g h k : Real)283284instance matrix3of.matrix285shows matrix3of(a, b, c, d, e, f, g, h, k) : realRing ^ 3×3286proof287rw matrix3of.graph288exact matrix3.matrix with*289290theorem matrix3of.entry (i j : Set)291requires hi : i ∈3292requires hj : j ∈3293shows matrix3of(a, b, c, d, e, f, g, h, k)[i, j] =294 triple(functionSpace(3, ℝ), row3(a, b, c), row3(d, e, f), row3(g, h, k))(i)(j)295proof296rw matrix3of.graph297exact matrix3.entry with*298299theorem matrix3of.entry00300shows matrix3of(a, b, c, d, e, f, g, h, k)[0, 0] = a301proof302have zeroIn : 0∈3bytypecheck303rw [matrix3of.entry, triple.zero, row3.graph, triple.zero]304rfl305306theorem matrix3of.entry01307shows matrix3of(a, b, c, d, e, f, g, h, k)[0, 1] = b308proof309have zeroIn : 0∈3bytypecheck310have oneIn : 1∈3bytypecheck311rw [matrix3of.entry, triple.zero, row3.graph, triple.one]312rfl313314theorem matrix3of.entry02315shows matrix3of(a, b, c, d, e, f, g, h, k)[0, 2] = c316proof317have zeroIn : 0∈3bytypecheck318have twoIn : 2∈3bytypecheck319rw [matrix3of.entry, triple.zero, row3.graph, triple.two]320rfl321322theorem matrix3of.entry10323shows matrix3of(a, b, c, d, e, f, g, h, k)[1, 0] = d324proof325have zeroIn : 0∈3bytypecheck326have oneIn : 1∈3bytypecheck327rw [matrix3of.entry, triple.one, row3.graph, triple.zero]328rfl329330theorem matrix3of.entry11331shows matrix3of(a, b, c, d, e, f, g, h, k)[1, 1] = e332proof333have oneIn : 1∈3bytypecheck334rw [matrix3of.entry, triple.one, row3.graph, triple.one]335rfl336337theorem matrix3of.entry12338shows matrix3of(a, b, c, d, e, f, g, h, k)[1, 2] = f339proof340have oneIn : 1∈3bytypecheck341have twoIn : 2∈3bytypecheck342rw [matrix3of.entry, triple.one, row3.graph, triple.two]343rfl344345theorem matrix3of.entry20346shows matrix3of(a, b, c, d, e, f, g, h, k)[2, 0] = g347proof348have zeroIn : 0∈3bytypecheck349have twoIn : 2∈3bytypecheck350rw [matrix3of.entry, triple.two, row3.graph, triple.zero]351rfl352353theorem matrix3of.entry21354shows matrix3of(a, b, c, d, e, f, g, h, k)[2, 1] = h355proof356have oneIn : 1∈3bytypecheck357have twoIn : 2∈3bytypecheck358rw [matrix3of.entry, triple.two, row3.graph, triple.one]359rfl360361theorem matrix3of.entry22362shows matrix3of(a, b, c, d, e, f, g, h, k)[2, 2] = k363proof364have twoIn : 2∈3bytypecheck365rw [matrix3of.entry, triple.two, row3.graph, triple.two]366rfl367368end Entries369370-- Entries of 3 × 3 real matrices are real, and a product entry is the371-- sum of three products.372section Products373variable (M N : realRing ^ 3×3)374375instance matrix3.entry_real (i j : Set)376requires hi : i ∈3377requires hj : j ∈3378shows M[i, j] ∈ ℝ379proof380have entry := Matrix.entry at M, realRing, 3, i, j with*381rw realRing.carrierOf at entry382exact entry383384theorem matrix3.mul_entry (i j : Set)385requires hi : i ∈3386requires hj : j ∈3387shows call2(Ring.mul(matrixRing(realRing, 3)), M, N)[i, j] =388 (M[i, 0]:R) * (N[0, j]:R) + (M[i, 1]:R) * (N[1, j]:R) + (M[i, 2]:R) * (N[2, j]:R)389proof390have comm := realRing.comm_ring391have parts := CommRing.parts with comm392have squareM := Matrix.square at M, realRing, 3withassumption393have squareN := Matrix.square at N, realRing, 3withassumption394have shapeM := squareMatrices.membership.forward with squareM395have shapeN := squareMatrices.membership.forward with squareN396have entry := matrixRing.mul_entry at realRing, 3, M, N, i, j with*397have weights := matrixProductWeights.function at3, Ring.carrier(realRing),398 Ring.add(realRing), Ring.zero(realRing), Ring.neg(realRing),399 Ring.mul(realRing), Ring.one(realRing), M, N, i, j with*400have zeroIn : 0∈3bytypecheck401have oneIn : 1∈3bytypecheck402have twoIn : 2∈3bytypecheck403have w0 := matrixProductWeights.value at3, Ring.carrier(realRing),404 Ring.add(realRing), Ring.zero(realRing), Ring.neg(realRing),405 Ring.mul(realRing), Ring.one(realRing), M, N, i, j, 0with*406have w1 := matrixProductWeights.value at3, Ring.carrier(realRing),407 Ring.add(realRing), Ring.zero(realRing), Ring.neg(realRing),408 Ring.mul(realRing), Ring.one(realRing), M, N, i, j, 1with*409have w2 := matrixProductWeights.value at3, Ring.carrier(realRing),410 Ring.add(realRing), Ring.zero(realRing), Ring.neg(realRing),411 Ring.mul(realRing), Ring.one(realRing), M, N, i, j, 2with*412have sum := finiteRingSum.over_three with parts, weights413rw entry414simp [matrixProductEntry]415rw [realRing.call_add, realRing.call_add, realRing.call_add,416 realRing.call_mul, realRing.call_mul, realRing.call_mul, realRing.zero_eq]417have m0 : M[i, 0] ∈ ℝ := matrix3.entry_real with*418have m1 : M[i, 1] ∈ ℝ := matrix3.entry_real with*419have m2 : M[i, 2] ∈ ℝ := matrix3.entry_real with*420have n0 : N[0, j] ∈ ℝ := matrix3.entry_real with*421have n1 : N[1, j] ∈ ℝ := matrix3.entry_real with*422have n2 : N[2, j] ∈ ℝ := matrix3.entry_real with*423ring424425instance matrix3.mul_matrix426shows call2(Ring.mul(matrixRing(realRing, 3)), M, N) : realRing ^ 3×3427proof428have comm := realRing.comm_ring429havering:= matrixRing.ring at realRing, 3with comm430have mIn : M ∈ Ring.carrier(matrixRing(realRing, 3)) := Matrix.mem_ring withassumption431have nIn : N∈ Ring.carrier(matrixRing(realRing, 3)) := Matrix.mem_ring withassumption432have productIn : call2(Ring.mul(matrixRing(realRing, 3)), M, N) ∈ Ring.carrier(matrixRing(realRing, 3)) :=433 Ring.mul_mem with*434exact Matrix.of_mem with productIn435436end Products437438-- The 3 × 3 real matrices as a type: Matrix3(M) is the guard439-- M : realRing ^ 3 × 3, and M * N on such matrices is matrixMul3(M, N),440-- the product of the matrix ring.441class Matrix3 (M : Set) := Matrix(M, realRing, 3, 3)442def matrixMul3 (M N : Set) : Set:= call2(Ring.mul(matrixRing(realRing, 3)), M, N)443notationinfixl70"*"=> matrixMul3 for Matrix3444445theorem matrixMul3.graph (M N : Set)446shows matrixMul3(M, N) = call2(Ring.mul(matrixRing(realRing, 3)), M, N)447proof448simp [matrixMul3]449450instance Matrix3.of_matrix (M : Set)451requires matrix : M : realRing ^ 3×3452shows Matrix3(M)453proof454exact matrix455456theorem Matrix3.matrix (M : Matrix3)457shows M : realRing ^ 3×3458proof459have typed : Matrix3(M) byassumption460unfold Matrix3 at typed461exact typed462463instance Matrix3.mul (M N : Matrix3)464shows Matrix3(matrixMul3(M, N))465proof466have matrixM : M : realRing ^ 3×3:= Matrix3.matrix with*467have matrixN : N : realRing ^ 3×3:= Matrix3.matrix with*468have product : call2(Ring.mul(matrixRing(realRing, 3)), M, N) : realRing ^ 3×3:=469 matrix3.mul_matrix with*470unfold Matrix3471rw matrixMul3.graph472exact product473474instance Matrix3.entry_real (M : Matrix3) (i j : Set)475requires hi : i ∈3476requires hj : j ∈3477shows M[i, j] ∈ ℝ478proof479have matrixM : M : realRing ^ 3×3:= Matrix3.matrix with*480exact matrix3.entry_real with*481482theorem Matrix3.mul_entry (M N : Matrix3) (i j : Set)483requires hi : i ∈3484requires hj : j ∈3485shows matrixMul3(M, N)[i, j] =486 (M[i, 0]:R) * (N[0, j]:R) + (M[i, 1]:R) * (N[1, j]:R) + (M[i, 2]:R) * (N[2, j]:R)487proof488have matrixM : M : realRing ^ 3×3:= Matrix3.matrix with*489have matrixN : N : realRing ^ 3×3:= Matrix3.matrix with*490rw matrixMul3.graph491exact matrix3.mul_entry with*492493instance Matrix3.one494shows Matrix3(Ring.one(matrixRing(realRing, 3)))495proof496have comm := realRing.comm_ring497havering:= matrixRing.ring at realRing, 3with comm498have oneIn : Ring.one(matrixRing(realRing, 3)) ∈ Ring.carrier(matrixRing(realRing, 3)) :=499 Ring.one_mem with*500unfold Matrix3501exact Matrix.of_mem with oneIn502503theorem Matrix3.ext (M N : Matrix3)504requires entries : ∀ i ∈3, ∀ j ∈3, M[i, j] = N[i, j]505shows M = N506proof507have comm := realRing.comm_ring508have matrixM : M : realRing ^ 3×3:= Matrix3.matrix with*509have matrixN : N : realRing ^ 3×3:= Matrix3.matrix with*510exact matrixRing.ext with entries511512-- Two explicit matrices with the same entries are equal, the product of513-- two explicit matrices, and the identity matrix as an explicit matrix.514theorem matrix3of.congr (a b c d e f g h k l m n o p q r s u : Real)515requires e00 : a = l516requires e01 : b = m517requires e02 : c = n518requires e10 : d = o519requires e11 : e = p520requires e12 : f = q521requires e20 : g = r522requires e21 : h = s523requires e22 : k = u524shows matrix3of(a, b, c, d, e, f, g, h, k) = matrix3of(l, m, n, o, p, q, r, s, u)525proof526rw [e00, e01, e02, e10, e11, e12, e20, e21, e22]527rfl528529tactic matrix3of_entries :=simp [matrix3of.entry00, matrix3of.entry01, matrix3of.entry02, matrix3of.entry10, matrix3of.entry11, matrix3of.entry12, matrix3of.entry20, matrix3of.entry21, matrix3of.entry22]530531theorem matrix3of.mul (a b c d e f g h k l m n o p q r s u : Real)532shows matrixMul3(matrix3of(a, b, c, d, e, f, g, h, k), matrix3of(l, m, n, o, p, q, r, s, u)) =533 matrix3of(a * l + b * o + c * r, a * m + b * p + c * s, a * n + b * q + c * u,534 d * l + e * o + f * r, d * m + e * p + f * s, d * n + e * q + f * u,535 g * l + h * o + k * r, g * m + h * p + k * s, g * n + h * q + k * u)536proof537have leftMatrix : matrix3of(a, b, c, d, e, f, g, h, k) : realRing ^ 3×3:=538 matrix3of.matrix with*539have rightMatrix : matrix3of(l, m, n, o, p, q, r, s, u) : realRing ^ 3×3:=540 matrix3of.matrix with*541have leftTyped : Matrix3(matrix3of(a, b, c, d, e, f, g, h, k)) :=542 Matrix3.of_matrix with leftMatrix543have rightTyped : Matrix3(matrix3of(l, m, n, o, p, q, r, s, u)) :=544 Matrix3.of_matrix with rightMatrix545have entries : ∀ i ∈3, ∀ j ∈3,546 matrixMul3(matrix3of(a, b, c, d, e, f, g, h, k), matrix3of(l, m, n, o, p, q, r, s, u))[i, j] =547 matrix3of(a * l + b * o + c * r, a * m + b * p + c * s, a * n + b * q + c * u,548 d * l + e * o + f * r, d * m + e * p + f * s, d * n + e * q + f * u,549 g * l + h * o + k * r, g * m + h * p + k * s, g * n + h * q + k * u)[i, j]550intros i hi j hj551have entry := Matrix3.mul_entry at matrix3of(a, b, c, d, e, f, g, h, k), matrix3of(l, m, n, o, p, q, r, s, u), i, j with leftTyped, rightTyped, hi, hj552rw entry553have rows := threeIndex.cases with hi554have columns := threeIndex.cases with hj555rcases rows with rowZero | rowOne | rowTwo556 . rcases columns with columnZero | columnOne | columnTwo557 . rw [rowZero, columnZero]558 matrix3of_entries559 . rw [rowZero, columnOne]560 matrix3of_entries561 . rw [rowZero, columnTwo]562 matrix3of_entries563 . rcases columns with columnZero | columnOne | columnTwo564 . rw [rowOne, columnZero]565 matrix3of_entries566 . rw [rowOne, columnOne]567 matrix3of_entries568 . rw [rowOne, columnTwo]569 matrix3of_entries570 . rcases columns with columnZero | columnOne | columnTwo571 . rw [rowTwo, columnZero]572 matrix3of_entries573 . rw [rowTwo, columnOne]574 matrix3of_entries575 . rw [rowTwo, columnTwo]576 matrix3of_entries577have e00 : a * l + b * o + c * r ∈ ℝ bytypecheck578have e01 : a * m + b * p + c * s ∈ ℝ bytypecheck579have e02 : a * n + b * q + c * u ∈ ℝ bytypecheck580have e10 : d * l + e * o + f * r ∈ ℝ bytypecheck581have e11 : d * m + e * p + f * s ∈ ℝ bytypecheck582have e12 : d * n + e * q + f * u ∈ ℝ bytypecheck583have e20 : g * l + h * o + k * r ∈ ℝ bytypecheck584have e21 : g * m + h * p + k * s ∈ ℝ bytypecheck585have e22 : g * n + h * q + k * u ∈ ℝ bytypecheck586have resultMatrix : matrix3of(a * l + b * o + c * r, a * m + b * p + c * s,587 a * n + b * q + c * u, d * l + e * o + f * r, d * m + e * p + f * s,588 d * n + e * q + f * u, g * l + h * o + k * r, g * m + h * p + k * s,589 g * n + h * q + k * u) : realRing ^ 3×3:=590 matrix3of.matrix with*591have productTyped : Matrix3(matrixMul3(matrix3of(a, b, c, d, e, f, g, h, k), matrix3of(l, m, n, o, p, q, r, s, u))) :=592 Matrix3.mul with leftTyped, rightTyped593have resultTyped : Matrix3(matrix3of(a * l + b * o + c * r, a * m + b * p + c * s,594 a * n + b * q + c * u, d * l + e * o + f * r, d * m + e * p + f * s,595 d * n + e * q + f * u, g * l + h * o + k * r, g * m + h * p + k * s,596 g * n + h * q + k * u)) :=597 Matrix3.of_matrix with resultMatrix598exact Matrix3.ext with productTyped, resultTyped, entries599600theorem matrix3of.one601shows matrix3of((1:R), (0:R), (0:R), (0:R), (1:R), (0:R), (0:R), (0:R), (1:R)) =602 Ring.one(matrixRing(realRing, 3))603proof604have zeroReal : (0:R) ∈ ℝ bytypecheck605have oneReal : (1:R) ∈ ℝ bytypecheck606have d01 := threeIndex.zero_ne_one607have d02 := threeIndex.zero_ne_two608have d12 := threeIndex.one_ne_two609have entries : ∀ i ∈3, ∀ j ∈3,610 matrix3of((1:R), (0:R), (0:R), (0:R), (1:R), (0:R), (0:R), (0:R), (1:R))[i, j] =611 Ring.one(matrixRing(realRing, 3))[i, j]612intros i hi j hj613have comm := realRing.comm_ring614have entry := matrixRing.one_entry at realRing, 3, i, j with*615rw [entry, realRing.carrierOf, realRing.zero_eq, realRing.one_eq]616have rows := threeIndex.cases with hi617have columns := threeIndex.cases with hj618rcases rows with rowZero | rowOne | rowTwo619 . rcases columns with columnZero | columnOne | columnTwo620 . rw [rowZero, columnZero, matrix3of.entry00, singleValue.same]621rfl622 . have different : (0:N) ≠ (1:N) := d01623rw [rowZero, columnOne, matrix3of.entry01, singleValue.other]624rfl625 . have different : (0:N) ≠ (2:N) := d02626rw [rowZero, columnTwo, matrix3of.entry02, singleValue.other]627rfl628 . rcases columns with columnZero | columnOne | columnTwo629 . have different : (1:N) ≠ (0:N)630intro same631 symm at same632exact d01 with same633rw [rowOne, columnZero, matrix3of.entry10, singleValue.other]634rfl635 . rw [rowOne, columnOne, matrix3of.entry11, singleValue.same]636rfl637 . have different : (1:N) ≠ (2:N) := d12638rw [rowOne, columnTwo, matrix3of.entry12, singleValue.other]639rfl640 . rcases columns with columnZero | columnOne | columnTwo641 . have different : (2:N) ≠ (0:N)642intro same643 symm at same644exact d02 with same645rw [rowTwo, columnZero, matrix3of.entry20, singleValue.other]646rfl647 . have different : (2:N) ≠ (1:N)648intro same649 symm at same650exact d12 with same651rw [rowTwo, columnOne, matrix3of.entry21, singleValue.other]652rfl653 . rw [rowTwo, columnTwo, matrix3of.entry22, singleValue.same]654rfl655have leftMatrix : matrix3of((1:R), (0:R), (0:R), (0:R), (1:R), (0:R), (0:R), (0:R), (1:R)) : realRing ^ 3×3:=656 matrix3of.matrix with*657have leftTyped : Matrix3(matrix3of((1:R), (0:R), (0:R), (0:R), (1:R), (0:R), (0:R), (0:R), (1:R))) :=658 Matrix3.of_matrix with leftMatrix659have oneTyped : Matrix3(Ring.one(matrixRing(realRing, 3))) := Matrix3.one660exact Matrix3.ext with leftTyped, oneTyped, entries661