Clifford project

3. Symplectic form🔗

Throughout this section we assume that d ≥ 1.

Lean codevariable (d : ) [NeZero d]

Below we define the symplectic inner product or symplectic form on ℤ_d^2.

Definition3.2
Group: Basic properties of the symplectic inner product. (8)
Hover another entry in this group to preview it.
L∃∀N

The symplectic inner product of \p = (p_1, p_2) and \q = (q_1, q_2) in ℤ_d^2 is \braket{\p,\q} := p_2 q_1 - p_1 q_2.

Lean code for Definition3.2def symp {R : Type*} [CommRing R] (p q : R × R) : R := p.2 * q.1 - p.1 * q.2

The symplectic inner product is antisymmetric.

Lemma3.3
Group: Basic properties of the symplectic inner product. (8)
Hover another entry in this group to preview it.
L∃∀N
Used by 3
Hover a use site to preview it.

For all \p,\q ∈ ℤ_d^2, \braket{\p,\q} = -\braket{\q,\p}.

Proof

\braket{\p,\q} = p_2 q_1 - p_1 q_2 = - (q_2 p_1 - q_1 p_2) = -\braket{\q,\p}.

Lean code for Lemma3.3omit [NeZero d] in lemma symp_antisymmetric (p q : ZMod d × ZMod d) : symp p q = - symp q p := d:p:ZMod d × ZMod dq:ZMod d × ZMod dsymp p q = -symp q p d:p:ZMod d × ZMod dq:ZMod d × ZMod dp.2 * q.1 - p.1 * q.2 = -(q.2 * p.1 - q.1 * p.2) All goals completed! 🐙

Every vector is isotropic under the symplectic inner product.

Lemma3.4
Group: Basic properties of the symplectic inner product. (8)
Hover another entry in this group to preview it.
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Lemma 5.49
Loading preview
Hover a use site to preview it.

For any \p ∈ ℤ_d^2, \braket{\p,\p} = 0.

Proof

\braket{\p,\p} = p_2 p_1 - p_1 p_2 = 0.

Lean code for Lemma3.4automatically included section variable(s) unused in theorem `self_eq_zero`: [NeZero d] consider restructuring your `variable` declarations so that the variables are not in scope or explicitly omit them: omit [NeZero d] in theorem ... Note: This linter can be disabled with `set_option linter.unusedSectionVars false`lemma self_eq_zero (p : ZMod d × ZMod d) : symp p p = 0 := d:inst✝:NeZero dp:ZMod d × ZMod dsymp p p = 0 d:inst✝:NeZero dp:ZMod d × ZMod dp.2 * p.1 - p.1 * p.2 = 0; All goals completed! 🐙

The symplectic inner product is additive in the first argument.

Lemma3.5
Group: Basic properties of the symplectic inner product. (8)
Hover another entry in this group to preview it.
L∃∀Nused by 1

For all \p, \p', \q ∈ ℤ_d^2, \braket{\p + \p', \q} = \braket{\p,\q} + \braket{\p',\q}.

Lean code for Lemma3.5omit [NeZero d] in lemma symp_add_left (p p' q : ZMod d × ZMod d) : symp (p + p') q = symp p q + symp p' q := d:p:ZMod d × ZMod dp':ZMod d × ZMod dq:ZMod d × ZMod dsymp (p + p') q = symp p q + symp p' q d:p:ZMod d × ZMod dp':ZMod d × ZMod dq:ZMod d × ZMod d(p + p').2 * q.1 - (p + p').1 * q.2 = p.2 * q.1 - p.1 * q.2 + (p'.2 * q.1 - p'.1 * q.2) d:p:ZMod d × ZMod dp':ZMod d × ZMod dq:ZMod d × ZMod d(p.2 + p'.2) * q.1 - (p.1 + p'.1) * q.2 = p.2 * q.1 - p.1 * q.2 + (p'.2 * q.1 - p'.1 * q.2) All goals completed! 🐙

The symplectic inner product is additive in the second argument.

Lemma3.6
Group: Basic properties of the symplectic inner product. (8)
Hover another entry in this group to preview it.
L∃∀Nused by 0

For all \p, \q, \q' ∈ ℤ_d^2, \braket{\p, \q + \q'} = \braket{\p,\q} + \braket{\p,\q'}.

Lean code for Lemma3.6omit [NeZero d] in lemma symp_add_right (p q q' : ZMod d × ZMod d) : symp p (q + q') = symp p q + symp p q' := d:p:ZMod d × ZMod dq:ZMod d × ZMod dq':ZMod d × ZMod dsymp p (q + q') = symp p q + symp p q' d:p:ZMod d × ZMod dq:ZMod d × ZMod dq':ZMod d × ZMod dp.2 * (q + q').1 - p.1 * (q + q').2 = p.2 * q.1 - p.1 * q.2 + (p.2 * q'.1 - p.1 * q'.2); d:p:ZMod d × ZMod dq:ZMod d × ZMod dq':ZMod d × ZMod dp.2 * (q.1 + q'.1) - p.1 * (q.2 + q'.2) = p.2 * q.1 - p.1 * q.2 + (p.2 * q'.1 - p.1 * q'.2); All goals completed! 🐙

Constants can be pulled out of the first argument.

Lemma3.7
Group: Basic properties of the symplectic inner product. (8)
Hover another entry in this group to preview it.
L∃∀Nused by 0

For all c ∈ ℤ_d and \p, \q ∈ ℤ_d^2, \braket{c\p, \q} = c\braket{\p,\q}.

Lean code for Lemma3.7omit [NeZero d] in lemma symp_smul_left (c : ZMod d) (p q : ZMod d × ZMod d) : symp (c p) q = c * symp p q := d:c:ZMod dp:ZMod d × ZMod dq:ZMod d × ZMod dsymp (c p) q = c * symp p q d:c:ZMod dp:ZMod d × ZMod dq:ZMod d × ZMod d(c p).2 * q.1 - (c p).1 * q.2 = c * (p.2 * q.1 - p.1 * q.2); d:c:ZMod dp:ZMod d × ZMod dq:ZMod d × ZMod dc * p.2 * q.1 - c * p.1 * q.2 = c * (p.2 * q.1 - p.1 * q.2); All goals completed! 🐙

Constants can be pulled out of the second argument.

Lemma3.8
Group: Basic properties of the symplectic inner product. (8)
Hover another entry in this group to preview it.
L∃∀Nused by 1

For all c ∈ ℤ_d and \p, \q ∈ ℤ_d^2, \braket{\p, c\q} = c\braket{\p,\q}.

Lean code for Lemma3.8omit [NeZero d] in lemma symp_smul_right (c : ZMod d) (p q : ZMod d × ZMod d) : symp p (c q) = c * symp p q := d:c:ZMod dp:ZMod d × ZMod dq:ZMod d × ZMod dsymp p (c q) = c * symp p q d:c:ZMod dp:ZMod d × ZMod dq:ZMod d × ZMod dp.2 * (c q).1 - p.1 * (c q).2 = c * (p.2 * q.1 - p.1 * q.2); d:c:ZMod dp:ZMod d × ZMod dq:ZMod d × ZMod dp.2 * (c * q.1) - p.1 * (c * q.2) = c * (p.2 * q.1 - p.1 * q.2); All goals completed! 🐙

If both arguments of the symplectic inner product are transformed by a linear map F, the value gets multiplied by \det F.

Lemma3.9
Group: Basic properties of the symplectic inner product. (8)
Hover another entry in this group to preview it.
L∃∀Nused by 1

For any matrix F \in \mathrm{M}_2(ℤ_d) and vectors \p, \q \in ℤ_d^2, \langle F\p, F\q \rangle = (\det F) \langle \p, \q \rangle.

Proof

If F = \bigl(\begin{smallmatrix} \alpha & \beta \\ \gamma & \delta \end{smallmatrix}\bigr) and \p = (p_1, \, p_2)^T then F\p = (\alpha p_1 + \beta p_2, \, \gamma p_1 + \delta p_2)^T. After applying F the symplectic inner product evaluates to \begin{aligned} \langle F\p, F\q\rangle &= (\gamma p_1 + \delta p_2)(\alpha q_1 + \beta q_2) - (\alpha p_1 + \beta p_2)(\gamma q_1 + \delta q_2) \\ &= (\alpha\delta - \beta\gamma)(p_2 q_1 - p_1 q_2) \\ &= (\det F)\langle \p, \q\rangle. \end{aligned}

Lean code for Lemma3.9def pair_apply_mat (F : Matrix (Fin 2) (Fin 2) (ZMod d)) (p : ZMod d × ZMod d) : ZMod d × ZMod d := (vecForm 0, vecForm 1) where vecForm := (Matrix.vecMul (fun i : Fin 2 => if i.val = 0 then p.fst else p.snd) F) automatically included section variable(s) unused in theorem `pair_apply_mat_alg`: [NeZero d] consider restructuring your `variable` declarations so that the variables are not in scope or explicitly omit them: omit [NeZero d] in theorem ... Note: This linter can be disabled with `set_option linter.unusedSectionVars false`lemma pair_apply_mat_alg (F : Matrix (Fin 2) (Fin 2) (ZMod d)) (p : ZMod d × ZMod d) : pair_apply_mat d F p = ((F 0 0) * p.1 + (F 1 0) * p.2, (F 0 1) * p.1 + (F 1 1) * p.2) := d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dpair_apply_mat d F p = (F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2) d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod d(pair_apply_mat.vecForm d F p 0, pair_apply_mat.vecForm d F p 1) = (F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2); d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod d(Matrix.vecMul (fun i => if i = 0 then p.1 else p.2) F 0, Matrix.vecMul (fun i => if i = 0 then p.1 else p.2) F 1) = (F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2); d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod d(have j := 0; (fun i => if i = 0 then p.1 else p.2) ⬝ᵥ fun i => F i j, have j := 1; (fun i => if i = 0 then p.1 else p.2) ⬝ᵥ fun i => F i j) = (F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2); d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dp.1 * F 0 0 + p.2 * F 1 0 = F 0 0 * p.1 + F 1 0 * p.2 p.1 * F 0 1 + p.2 * F 1 1 = F 0 1 * p.1 + F 1 1 * p.2; d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dp.1 * F 0 0 + p.2 * F 1 0 = F 0 0 * p.1 + F 1 0 * p.2d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dp.1 * F 0 1 + p.2 * F 1 1 = F 0 1 * p.1 + F 1 1 * p.2; d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dp.1 * F 0 1 + p.2 * F 1 1 = F 0 1 * p.1 + F 1 1 * p.2; All goals completed! 🐙 automatically included section variable(s) unused in theorem `symp_det`: [NeZero d] consider restructuring your `variable` declarations so that the variables are not in scope or explicitly omit them: omit [NeZero d] in theorem ... Note: This linter can be disabled with `set_option linter.unusedSectionVars false`lemma symp_det (F : Matrix (Fin 2) (Fin 2) (ZMod d)) (p q : ZMod d × ZMod d) : symp (pair_apply_mat d F p) (pair_apply_mat d F q) = Matrix.det F * (symp p q) := d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (pair_apply_mat d F p) (pair_apply_mat d F q) = F.det * symp p q calc symp (pair_apply_mat d F p) (pair_apply_mat d F q) = symp ((F 0 0) * p.1 + (F 1 0) * p.2, (F 0 1) * p.1 + (F 1 1) * p.2) ((F 0 0) * q.1 + (F 1 0) * q.2, (F 0 1) * q.1 + (F 1 1) * q.2) := d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (pair_apply_mat d F p) (pair_apply_mat d F q) = symp (F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2) (F 0 0 * q.1 + F 1 0 * q.2, F 0 1 * q.1 + F 1 1 * q.2) d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (pair_apply_mat.vecForm d F p 0, pair_apply_mat.vecForm d F p 1) (pair_apply_mat.vecForm d F q 0, pair_apply_mat.vecForm d F q 1) = symp (F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2) (F 0 0 * q.1 + F 1 0 * q.2, F 0 1 * q.1 + F 1 1 * q.2); d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (Matrix.vecMul (fun i => if i = 0 then p.1 else p.2) F 0, Matrix.vecMul (fun i => if i = 0 then p.1 else p.2) F 1) (Matrix.vecMul (fun i => if i = 0 then q.1 else q.2) F 0, Matrix.vecMul (fun i => if i = 0 then q.1 else q.2) F 1) = symp (F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2) (F 0 0 * q.1 + F 1 0 * q.2, F 0 1 * q.1 + F 1 1 * q.2); d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (have j := 0; (fun i => if i = 0 then p.1 else p.2) ⬝ᵥ fun i => F i j, have j := 1; (fun i => if i = 0 then p.1 else p.2) ⬝ᵥ fun i => F i j) (have j := 0; (fun i => if i = 0 then q.1 else q.2) ⬝ᵥ fun i => F i j, have j := 1; (fun i => if i = 0 then q.1 else q.2) ⬝ᵥ fun i => F i j) = symp (F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2) (F 0 0 * q.1 + F 1 0 * q.2, F 0 1 * q.1 + F 1 1 * q.2); d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (p.1 * F 0 0 + p.2 * F 1 0, p.1 * F 0 1 + p.2 * F 1 1) (q.1 * F 0 0 + q.2 * F 1 0, q.1 * F 0 1 + q.2 * F 1 1) = symp (F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2) (F 0 0 * q.1 + F 1 0 * q.2, F 0 1 * q.1 + F 1 1 * q.2); Try this: [apply] ring_nf The `ring` tactic failed to close the goal. Use `ring_nf` to obtain a normal form. Note that `ring` works primarily in *commutative* rings. If you have a noncommutative ring, abelian group or module, consider using `noncomm_ring`, `abel` or `module` instead.All goals completed! 🐙 _ = (((F 0 1) * p.1 + (F 1 1) * p.2) * ((F 0 0) * q.1 + (F 1 0) * q.2)) - (((F 0 1) * q.1 + (F 1 1) * q.2) * ((F 0 0) * p.1 + (F 1 0) * p.2)) := d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2) (F 0 0 * q.1 + F 1 0 * q.2, F 0 1 * q.1 + F 1 1 * q.2) = (F 0 1 * p.1 + F 1 1 * p.2) * (F 0 0 * q.1 + F 1 0 * q.2) - (F 0 1 * q.1 + F 1 1 * q.2) * (F 0 0 * p.1 + F 1 0 * p.2) d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod d(F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2).2 * (F 0 0 * q.1 + F 1 0 * q.2, F 0 1 * q.1 + F 1 1 * q.2).1 - (F 0 0 * p.1 + F 1 0 * p.2, F 0 1 * p.1 + F 1 1 * p.2).1 * (F 0 0 * q.1 + F 1 0 * q.2, F 0 1 * q.1 + F 1 1 * q.2).2 = (F 0 1 * p.1 + F 1 1 * p.2) * (F 0 0 * q.1 + F 1 0 * q.2) - (F 0 1 * q.1 + F 1 1 * q.2) * (F 0 0 * p.1 + F 1 0 * p.2); d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod d(F 0 0 * p.1 + F 1 0 * p.2) * (F 0 1 * q.1 + F 1 1 * q.2) = (F 0 1 * q.1 + F 1 1 * q.2) * (F 0 0 * p.1 + F 1 0 * p.2); All goals completed! 🐙 _ = ((F 0 0) * (F 1 1) - (F 1 0) * (F 0 1)) * (p.2 * q.1 - p.1 * q.2 ) := d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod d(F 0 1 * p.1 + F 1 1 * p.2) * (F 0 0 * q.1 + F 1 0 * q.2) - (F 0 1 * q.1 + F 1 1 * q.2) * (F 0 0 * p.1 + F 1 0 * p.2) = (F 0 0 * F 1 1 - F 1 0 * F 0 1) * (p.2 * q.1 - p.1 * q.2) All goals completed! 🐙 _ = (Matrix.det F) * (symp p q) := d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod d(F 0 0 * F 1 1 - F 1 0 * F 0 1) * (p.2 * q.1 - p.1 * q.2) = F.det * symp p q d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dF.det * symp p q = (F 0 0 * F 1 1 - F 1 0 * F 0 1) * (p.2 * q.1 - p.1 * q.2); d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dF.det * (p.2 * q.1 - p.1 * q.2) = (F 0 0 * F 1 1 - F 1 0 * F 0 1) * (p.2 * q.1 - p.1 * q.2); d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod d(F 0 0 * F 1 1 - F 0 1 * F 1 0) * (p.2 * q.1 - p.1 * q.2) = (F 0 0 * F 1 1 - F 1 0 * F 0 1) * (p.2 * q.1 - p.1 * q.2); All goals completed! 🐙

Adjoint property of the symplectic inner product.

Lemma3.10
Group: Basic properties of the symplectic inner product. (8)
Hover another entry in this group to preview it.
L∃∀Nused by 1

If F ∈ \SL(2,ℤ_d) then \braket{\p,F\q} \equiv \braket{F^{-1}\p,\q} \pmod{d} for all \p,\q ∈ ℤ.

Proof

Since F is invertible, one can write p = FF^{-1}p. Hence, \begin{align*} \langle p, F q \rangle &= \langle FF^{-1}p , F q \rangle\ &= (\det F) \langle F^{-1}p, q \rangle\\ &=\langle F^{-1}p, q \rangle \end{align*}

Lean code for Lemma3.10def SpecialLinearInverse (F : Matrix.SpecialLinearGroup (Fin 2) (ZMod d)) : Matrix.SpecialLinearGroup (Fin 2) (ZMod d) := Matrix.SpecialLinearGroup.hasInv.inv F lemma declaration uses `sorry`MatrixMulToDoubleApply (F G : Matrix (Fin 2) (Fin 2) (ZMod d)) (p : ZMod d × ZMod d) : pair_apply_mat d F (pair_apply_mat d G p) = pair_apply_mat d (F * G) p := d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)G:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dpair_apply_mat d F (pair_apply_mat d G p) = pair_apply_mat d (F * G) p d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)G:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod d(F 0 0 * (pair_apply_mat d G p).1 + F 1 0 * (pair_apply_mat d G p).2, F 0 1 * (pair_apply_mat d G p).1 + F 1 1 * (pair_apply_mat d G p).2) = pair_apply_mat d (F * G) p; d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)G:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod d(F 0 0 * (G 0 0 * p.1 + G 1 0 * p.2, G 0 1 * p.1 + G 1 1 * p.2).1 + F 1 0 * (G 0 0 * p.1 + G 1 0 * p.2, G 0 1 * p.1 + G 1 1 * p.2).2, F 0 1 * (G 0 0 * p.1 + G 1 0 * p.2, G 0 1 * p.1 + G 1 1 * p.2).1 + F 1 1 * (G 0 0 * p.1 + G 1 0 * p.2, G 0 1 * p.1 + G 1 1 * p.2).2) = pair_apply_mat d (F * G) p; d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)G:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod d(F 0 0 * (G 0 0 * p.1 + G 1 0 * p.2, G 0 1 * p.1 + G 1 1 * p.2).1 + F 1 0 * (G 0 0 * p.1 + G 1 0 * p.2, G 0 1 * p.1 + G 1 1 * p.2).2, F 0 1 * (G 0 0 * p.1 + G 1 0 * p.2, G 0 1 * p.1 + G 1 1 * p.2).1 + F 1 1 * (G 0 0 * p.1 + G 1 0 * p.2, G 0 1 * p.1 + G 1 1 * p.2).2) = ((F * G) 0 0 * p.1 + (F * G) 1 0 * p.2, (F * G) 0 1 * p.1 + (F * G) 1 1 * p.2); d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)G:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dF 0 0 * (G 0 0 * p.1 + G 1 0 * p.2) + F 1 0 * (G 0 1 * p.1 + G 1 1 * p.2) = (F * G) 0 0 * p.1 + (F * G) 1 0 * p.2 F 0 1 * (G 0 0 * p.1 + G 1 0 * p.2) + F 1 1 * (G 0 1 * p.1 + G 1 1 * p.2) = (F * G) 0 1 * p.1 + (F * G) 1 1 * p.2; d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)G:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dF 0 0 * (G 0 0 * p.1 + G 1 0 * p.2) + F 1 0 * (G 0 1 * p.1 + G 1 1 * p.2) = (F * G) 0 0 * p.1 + (F * G) 1 0 * p.2d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)G:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dF 0 1 * (G 0 0 * p.1 + G 1 0 * p.2) + F 1 1 * (G 0 1 * p.1 + G 1 1 * p.2) = (F * G) 0 1 * p.1 + (F * G) 1 1 * p.2; d:inst✝:NeZero dF:Matrix (Fin 2) (Fin 2) (ZMod d)G:Matrix (Fin 2) (Fin 2) (ZMod d)p:ZMod d × ZMod dF 0 1 * (G 0 0 * p.1 + G 1 0 * p.2) + F 1 1 * (G 0 1 * p.1 + G 1 1 * p.2) = (F * G) 0 1 * p.1 + (F * G) 1 1 * p.2; All goals completed! 🐙 -- Find a way to unfold matrix product automatically included section variable(s) unused in theorem `SpecialLinearDet`: [NeZero d] consider restructuring your `variable` declarations so that the variables are not in scope or explicitly omit them: omit [NeZero d] in theorem ... Note: This linter can be disabled with `set_option linter.unusedSectionVars false`lemma SpecialLinearDet (F : Matrix.SpecialLinearGroup (Fin 2) (ZMod d)): Matrix.det (CoeFun.coe F) = 1 := d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)Matrix.det (CoeFun.coe F) = 1 All goals completed! 🐙 automatically included section variable(s) unused in theorem `FactorByInverse`: [NeZero d] consider restructuring your `variable` declarations so that the variables are not in scope or explicitly omit them: omit [NeZero d] in theorem ... Note: This linter can be disabled with `set_option linter.unusedSectionVars false`lemma FactorByInverse (F : Matrix.SpecialLinearGroup (Fin 2) (ZMod d)) (p : ZMod d × ZMod d) : pair_apply_mat d ((F * F⁻¹) : Matrix.SpecialLinearGroup (Fin 2) (ZMod d)) p = p := d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dpair_apply_mat d (↑(F * F⁻¹)) p = p d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dpair_apply_mat d (↑1) p = p; d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dpair_apply_mat d 1 p = p; d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod d(pair_apply_mat.vecForm d 1 p 0, pair_apply_mat.vecForm d 1 p 1) = p; d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod d(Matrix.vecMul (fun i => if i = 0 then p.1 else p.2) 1 0, Matrix.vecMul (fun i => if i = 0 then p.1 else p.2) 1 1) = p; All goals completed! 🐙 lemma symp_adjoint (F : Matrix.SpecialLinearGroup (Fin 2) (ZMod d)) (p q : ZMod d × ZMod d) : (symp p (pair_apply_mat d F q)) = (symp (pair_apply_mat d (SpecialLinearInverse d F) p) q) := d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp p (pair_apply_mat d (↑F) q) = symp (pair_apply_mat d (↑(SpecialLinearInverse d F)) p) q calc symp p (pair_apply_mat d F q) = symp (pair_apply_mat d ((F * (SpecialLinearInverse d F)) : Matrix.SpecialLinearGroup (Fin 2) (ZMod d)) p) (pair_apply_mat d F q) := d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp p (pair_apply_mat d (↑F) q) = symp (pair_apply_mat d (↑(F * SpecialLinearInverse d F)) p) (pair_apply_mat d (↑F) q) d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (pair_apply_mat d (↑(F * SpecialLinearInverse d F)) p) (pair_apply_mat d (↑F) q) = symp p (pair_apply_mat d (↑F) q); d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (pair_apply_mat d (↑(F * F⁻¹)) p) (pair_apply_mat d (↑F) q) = symp p (pair_apply_mat d (↑F) q); All goals completed! 🐙 _ = (Matrix.det (Matrix.SpecialLinearGroup.instCoeFun.coe F)) * symp (pair_apply_mat d (SpecialLinearInverse d F) p) q := d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (pair_apply_mat d (↑(F * SpecialLinearInverse d F)) p) (pair_apply_mat d (↑F) q) = Matrix.det (CoeFun.coe F) * symp (pair_apply_mat d (↑(SpecialLinearInverse d F)) p) q d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (pair_apply_mat d (F * (SpecialLinearInverse d F)) p) (pair_apply_mat d (↑F) q) = Matrix.det (CoeFun.coe F) * symp (pair_apply_mat d (↑(SpecialLinearInverse d F)) p) q; d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dsymp (pair_apply_mat d (↑F) (pair_apply_mat d (↑(SpecialLinearInverse d F)) p)) (pair_apply_mat d (↑F) q) = Matrix.det (CoeFun.coe F) * symp (pair_apply_mat d (↑(SpecialLinearInverse d F)) p) q; All goals completed! 🐙 _ = symp (pair_apply_mat d (SpecialLinearInverse d F) p) q := d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod dMatrix.det (CoeFun.coe F) * symp (pair_apply_mat d (↑(SpecialLinearInverse d F)) p) q = symp (pair_apply_mat d (↑(SpecialLinearInverse d F)) p) q d:inst✝:NeZero dF:Matrix.SpecialLinearGroup (Fin 2) (ZMod d)p:ZMod d × ZMod dq:ZMod d × ZMod d1 * symp (pair_apply_mat d (↑(SpecialLinearInverse d F)) p) q = symp (pair_apply_mat d (↑(SpecialLinearInverse d F)) p) q; All goals completed! 🐙