|
| 1 | +/- |
| 2 | +Copyright (c) 2022 Eric Wieser. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Eric Wieser |
| 5 | +-/ |
| 6 | +import linear_algebra.clifford_algebra.conjugation |
| 7 | + |
| 8 | +/-! |
| 9 | +# Recursive computation rules for the Clifford algebra |
| 10 | +
|
| 11 | +This file provides API for a special case `clifford_algebra.foldr` of the universal property |
| 12 | +`clifford_algebra.lift` with `A = module.End R N` for some arbitrary module `N`. This specialization |
| 13 | +resembles the `list.foldr` operation, allowing a bilinear map to be "folded" along the generators. |
| 14 | +
|
| 15 | +For convenience, this file also provides `clifford_algebra.foldl`, implemented via |
| 16 | +`clifford_algebra.reverse` |
| 17 | +
|
| 18 | +## Main definitions |
| 19 | +
|
| 20 | +* `clifford_algebra.foldr`: a computation rule for building linear maps out of the clifford |
| 21 | + algebra starting on the right, analogous to using `list.foldr` on the generators. |
| 22 | +* `clifford_algebra.foldl`: a computation rule for building linear maps out of the clifford |
| 23 | + algebra starting on the left, analogous to using `list.foldl` on the generators. |
| 24 | +
|
| 25 | +## Main statements |
| 26 | +
|
| 27 | +* `clifford_algebra.right_induction`: an induction rule that adds generators from the right. |
| 28 | +* `clifford_algebra.left_induction`: an induction rule that adds generators from the left. |
| 29 | +-/ |
| 30 | + |
| 31 | +universes u1 u2 u3 |
| 32 | + |
| 33 | +variables {R M N : Type*} |
| 34 | +variables [comm_ring R] [add_comm_group M] [add_comm_group N] |
| 35 | +variables [module R M] [module R N] |
| 36 | +variables (Q : quadratic_form R M) |
| 37 | + |
| 38 | +namespace clifford_algebra |
| 39 | + |
| 40 | +section foldr |
| 41 | + |
| 42 | +/-- Fold a bilinear map along the generators of a term of the clifford algebra, with the rule |
| 43 | +given by `foldr Q f hf n (ι Q m * x) = f m (foldr Q f hf n x)`. |
| 44 | +
|
| 45 | +For example, `foldr f hf n (r • ι R u + ι R v * ι R w) = r • f u n + f v (f w n)`. -/ |
| 46 | +def foldr (f : M →ₗ[R] N →ₗ[R] N) (hf : ∀ m x, f m (f m x) = Q m • x) : |
| 47 | + N →ₗ[R] clifford_algebra Q →ₗ[R] N := |
| 48 | +(clifford_algebra.lift Q ⟨f, λ v, linear_map.ext $ hf v⟩).to_linear_map.flip |
| 49 | + |
| 50 | +@[simp] lemma foldr_ι (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N) (m : M) : |
| 51 | + foldr Q f hf n (ι Q m) = f m n := |
| 52 | +linear_map.congr_fun (lift_ι_apply _ _ _) n |
| 53 | + |
| 54 | +@[simp] lemma foldr_algebra_map (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N) (r : R) : |
| 55 | + foldr Q f hf n (algebra_map R _ r) = r • n := |
| 56 | +linear_map.congr_fun (alg_hom.commutes _ r) n |
| 57 | + |
| 58 | +@[simp] lemma foldr_one (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N) : |
| 59 | + foldr Q f hf n 1 = n := |
| 60 | +linear_map.congr_fun (alg_hom.map_one _) n |
| 61 | + |
| 62 | +@[simp] lemma foldr_mul (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N) (a b : clifford_algebra Q) : |
| 63 | + foldr Q f hf n (a * b) = foldr Q f hf (foldr Q f hf n b) a := |
| 64 | +linear_map.congr_fun (alg_hom.map_mul _ _ _) n |
| 65 | + |
| 66 | + |
| 67 | +/-- This lemma demonstrates the origin of the `foldr` name. -/ |
| 68 | +lemma foldr_prod_map_ι (l : list M) (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N): |
| 69 | + foldr Q f hf n (l.map $ ι Q).prod = list.foldr (λ m n, f m n) n l := |
| 70 | +begin |
| 71 | + induction l with hd tl ih, |
| 72 | + { rw [list.map_nil, list.prod_nil, list.foldr_nil, foldr_one] }, |
| 73 | + { rw [list.map_cons, list.prod_cons, list.foldr_cons, foldr_mul, foldr_ι, ih] }, |
| 74 | +end |
| 75 | + |
| 76 | +end foldr |
| 77 | + |
| 78 | +section foldl |
| 79 | + |
| 80 | +/-- Fold a bilinear map along the generators of a term of the clifford algebra, with the rule |
| 81 | +given by `foldl Q f hf n (ι Q m * x) = f m (foldl Q f hf n x)`. |
| 82 | +
|
| 83 | +For example, `foldl f hf n (r • ι R u + ι R v * ι R w) = r • f u n + f v (f w n)`. -/ |
| 84 | +def foldl (f : M →ₗ[R] N →ₗ[R] N) (hf : ∀ m x, f m (f m x) = Q m • x) : |
| 85 | + N →ₗ[R] clifford_algebra Q →ₗ[R] N := |
| 86 | +linear_map.compl₂ (foldr Q f hf) reverse |
| 87 | + |
| 88 | +@[simp] lemma foldl_reverse (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N) (x : clifford_algebra Q) : |
| 89 | + foldl Q f hf n (reverse x) = foldr Q f hf n x := |
| 90 | +fun_like.congr_arg (foldr Q f hf n) $ reverse_reverse _ |
| 91 | + |
| 92 | +@[simp] lemma foldr_reverse (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N) (x : clifford_algebra Q) : |
| 93 | + foldr Q f hf n (reverse x) = foldl Q f hf n x := rfl |
| 94 | + |
| 95 | +@[simp] lemma foldl_ι (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N) (m : M) : |
| 96 | + foldl Q f hf n (ι Q m) = f m n := |
| 97 | +by rw [←foldr_reverse, reverse_ι, foldr_ι] |
| 98 | + |
| 99 | +@[simp] lemma foldl_algebra_map (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N) (r : R) : |
| 100 | + foldl Q f hf n (algebra_map R _ r) = r • n := |
| 101 | +by rw [←foldr_reverse, reverse.commutes, foldr_algebra_map] |
| 102 | + |
| 103 | +@[simp] lemma foldl_one (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N) : |
| 104 | + foldl Q f hf n 1 = n := |
| 105 | +by rw [←foldr_reverse, reverse.map_one, foldr_one] |
| 106 | + |
| 107 | +@[simp] lemma foldl_mul (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N) (a b : clifford_algebra Q) : |
| 108 | + foldl Q f hf n (a * b) = foldl Q f hf (foldl Q f hf n a) b := |
| 109 | +by rw [←foldr_reverse, ←foldr_reverse, ←foldr_reverse, reverse.map_mul, foldr_mul] |
| 110 | + |
| 111 | +/-- This lemma demonstrates the origin of the `foldl` name. -/ |
| 112 | +lemma foldl_prod_map_ι (l : list M) (f : M →ₗ[R] N →ₗ[R] N) (hf) (n : N): |
| 113 | + foldl Q f hf n (l.map $ ι Q).prod = list.foldl (λ m n, f n m) n l := |
| 114 | +by rw [←foldr_reverse, reverse_prod_map_ι, ←list.map_reverse, foldr_prod_map_ι, list.foldr_reverse] |
| 115 | + |
| 116 | +end foldl |
| 117 | + |
| 118 | +lemma right_induction {P : clifford_algebra Q → Prop} |
| 119 | + (hr : ∀ r : R, P (algebra_map _ _ r)) |
| 120 | + (h_add : ∀ x y, P x → P y → P (x + y)) |
| 121 | + (h_ι_mul : ∀ m x, P x → P (x * ι Q m)) : ∀ x, P x := |
| 122 | +begin |
| 123 | + /- It would be neat if we could prove this via `foldr` like how we prove |
| 124 | + `clifford_algebra.induction`, but going via the grading seems easier. -/ |
| 125 | + intro x, |
| 126 | + have : x ∈ ⊤ := submodule.mem_top, |
| 127 | + rw ←supr_ι_range_eq_top at this, |
| 128 | + apply submodule.supr_induction _ this (λ i x hx, _) _ h_add, |
| 129 | + { refine submodule.pow_induction_on_right _ hr h_add (λ x px m, _) hx, |
| 130 | + rintro ⟨m, rfl⟩, |
| 131 | + exact h_ι_mul _ _ px }, |
| 132 | + { simpa only [map_zero] using hr 0} |
| 133 | +end |
| 134 | + |
| 135 | +lemma left_induction {P : clifford_algebra Q → Prop} |
| 136 | + (hr : ∀ r : R, P (algebra_map _ _ r)) |
| 137 | + (h_add : ∀ x y, P x → P y → P (x + y)) |
| 138 | + (h_mul_ι : ∀ x m, P x → P (ι Q m * x)) : ∀ x, P x := |
| 139 | +begin |
| 140 | + refine reverse_involutive.surjective.forall.2 _, |
| 141 | + intro x, |
| 142 | + induction x using clifford_algebra.right_induction with r x y hx hy m x hx, |
| 143 | + { simpa only [reverse.commutes] using hr r }, |
| 144 | + { simpa only [map_add] using h_add _ _ hx hy }, |
| 145 | + { simpa only [reverse.map_mul, reverse_ι] using h_mul_ι _ _ hx }, |
| 146 | +end |
| 147 | + |
| 148 | +end clifford_algebra |
0 commit comments