Session 5: Division of maps: Sections and retractions
1. Determination problems
(a) Show that if there is a map g for which {h = g \circ f}, then for any pair a_1, a_2 of points {\mathbf{1} \rightarrow A} of the domain A of f (and of h) we have:
\text{if}\; fa_1 = fa_2 \;\text{then}\; ha_1 = ha_2.
(So, if for some pair of points one has {f a_1 = f a_2} but {h a_1 \ne h a_2}, then h is not determined by f.)
(b) Does the converse hold? That is, if maps (of sets) f and h satisfy the conditions above ('for any pair ... then {h a_1 = h a_2}'), must there be a map {B \xrightarrow{g} C} with {h = g \circ f}?
Solution: Exercise 1
We use types instead of sets here, and we begin by showing that part (a) holds.
example {A B C : Type} {f : A โถ B} {h : A โถ C}
(hg : โ g : B โถ C, h = g โ f)
: โ aโ aโ : Point A, f โ aโ = f โ aโ โ h โ aโ = h โ aโ := A:TypeB:TypeC:Typef:A โถ Bh:A โถ Chg:โ g, h = g โ fโข โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโ
A:TypeB:TypeC:Typef:A โถ Bh:A โถ Cg:B โถ Chg:h = g โ fโข โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโ
intro _ A:TypeB:TypeC:Typef:A โถ Bh:A โถ Cg:B โถ Chg:h = g โ faโโ:Point Aaโโ:Point Aโข f โ aโโ = f โ aโโ โ h โ aโโ = h โ aโโ A:TypeB:TypeC:Typef:A โถ Bh:A โถ Cg:B โถ Chg:h = g โ faโโ:Point Aaโโ:Point Ahfa:f โ aโโ = f โ aโโโข h โ aโโ = h โ aโโ
A:TypeB:TypeC:Typef:A โถ Bh:A โถ Cg:B โถ Chg:h = g โ faโโ:Point Aaโโ:Point Ahfa:f โ aโโ = f โ aโโโข (g โ f) โ aโโ = (g โ f) โ aโโ
repeat A:TypeB:TypeC:Typef:A โถ Bh:A โถ Cg:B โถ Chg:h = g โ faโโ:Point Aaโโ:Point Ahfa:f โ aโโ = f โ aโโโข g โ f โ aโโ = g โ f โ aโโ
All goals completed! ๐
For part (b), we first prove the converse in the case when f is surjective.
example {A B C : Type} {f : A โถ B} {h : A โถ C}
(H : โ aโ aโ : Point A, f โ aโ = f โ aโ โ h โ aโ = h โ aโ)
(hfsurj : Function.Surjective f)
: โ g : B โถ C, h = g โ f := A:TypeB:TypeC:Typef:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโhfsurj:Function.Surjective fโข โ g, h = g โ f
A:TypeB:TypeC:Typef:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโhfsurj:Function.Surjective fg:B โถ C := fun ฮฒ โฆ h (Classical.choose โฏ)โข โ g, h = g โ f
A:TypeB:TypeC:Typef:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโhfsurj:Function.Surjective fg:B โถ C := fun ฮฒ โฆ h (Classical.choose โฏ)โข h = g โ f
A:TypeB:TypeC:Typef:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโhfsurj:Function.Surjective fg:B โถ C := fun ฮฒ โฆ h (Classical.choose โฏ)ฮฑ:Aโข h ฮฑ = (g โ f) ฮฑ
A:TypeB:TypeC:Typef:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโhfsurj:Function.Surjective fg:B โถ C := fun ฮฒ โฆ h (Classical.choose โฏ)ฮฑ:Aaโ:Point A := fun x โฆ ฮฑโข h ฮฑ = (g โ f) ฮฑ
A:TypeB:TypeC:Typef:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโhfsurj:Function.Surjective fg:B โถ C := fun ฮฒ โฆ h (Classical.choose โฏ)ฮฑ:Aaโ:Point A := fun x โฆ ฮฑaโ:Point A := fun x โฆ Classical.choose โฏโข h ฮฑ = (g โ f) ฮฑ
have hfa : f โ aโ = f โ aโ := A:TypeB:TypeC:Typef:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโhfsurj:Function.Surjective fโข โ g, h = g โ f
A:TypeB:TypeC:Typef:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโhfsurj:Function.Surjective fg:B โถ C := fun ฮฒ โฆ h (Classical.choose โฏ)ฮฑ:Aaโ:Point A := fun x โฆ ฮฑaโ:Point A := fun x โฆ Classical.choose โฏxโ:Oneโข (f โ aโ) xโ = (f โ aโ) xโ
All goals completed! ๐
A:TypeB:TypeC:Typef:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโhfsurj:Function.Surjective fg:B โถ C := fun ฮฒ โฆ h (Classical.choose โฏ)ฮฑ:Aaโ:Point A := fun x โฆ ฮฑaโ:Point A := fun x โฆ Classical.choose โฏhfa:f โ aโ = f โ aโ := funext fun x โฆ Eq.symm (Classical.choose_spec (hfsurj (f ฮฑ)))hha:h โ aโ = h โ aโ := H aโ aโ hfaโข h ฮฑ = (g โ f) ฮฑ
All goals completed! ๐
Proof in the general case is slightly more complicated and is given below.
open Classical in
example {A B C : Type} [Nonempty C] {f : A โถ B} {h : A โถ C}
(H : โ aโ aโ : Point A, f โ aโ = f โ aโ โ h โ aโ = h โ aโ)
: โ g : B โถ C, h = g โ f := A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโโข โ g, h = g โ f
-- ฮฒ : B may or may not be in the image of f,
-- so we need to handle both cases
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏโข โ g, h = g โ f
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏโข h = g โ f
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏฮฑ:Aโข h ฮฑ = (g โ f) ฮฑ
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏฮฑ:Aฮฒ_in_image_exists:โ ฮฑ', f ฮฑ' = f ฮฑ := Exists.intro ฮฑ rflโข h ฮฑ = (g โ f) ฮฑ
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏฮฑ:Aฮฒ_in_image_exists:โ ฮฑ', f ฮฑ' = f ฮฑ := Exists.intro ฮฑ rflaโ:Point A := fun x โฆ ฮฑโข h ฮฑ = (g โ f) ฮฑ
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏฮฑ:Aฮฒ_in_image_exists:โ ฮฑ', f ฮฑ' = f ฮฑ := Exists.intro ฮฑ rflaโ:Point A := fun x โฆ ฮฑaโ:Point A := fun x โฆ choose ฮฒ_in_image_existsโข h ฮฑ = (g โ f) ฮฑ
have hfa : f โ aโ = f โ aโ := A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโโข โ g, h = g โ f
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏฮฑ:Aฮฒ_in_image_exists:โ ฮฑ', f ฮฑ' = f ฮฑ := Exists.intro ฮฑ rflaโ:Point A := fun x โฆ ฮฑaโ:Point A := fun x โฆ choose ฮฒ_in_image_existsxโ:Oneโข (f โ aโ) xโ = (f โ aโ) xโ
All goals completed! ๐
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏฮฑ:Aฮฒ_in_image_exists:โ ฮฑ', f ฮฑ' = f ฮฑ := Exists.intro ฮฑ rflaโ:Point A := fun x โฆ ฮฑaโ:Point A := fun x โฆ choose ฮฒ_in_image_existshfa:f โ aโ = f โ aโ := funext fun x โฆ Eq.symm (choose_spec ฮฒ_in_image_exists)hha:h โ aโ = h โ aโ := H aโ aโ hfaโข h ฮฑ = (g โ f) ฮฑ
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏฮฑ:Aฮฒ_in_image_exists:โ ฮฑ', f ฮฑ' = f ฮฑ := Exists.intro ฮฑ rflaโ:Point A := fun x โฆ ฮฑaโ:Point A := fun x โฆ choose ฮฒ_in_image_existshfa:f โ aโ = f โ aโ := funext fun x โฆ Eq.symm (choose_spec ฮฒ_in_image_exists)hha:h โ aโ = h โ aโ := H aโ aโ hfah_eq_h_chosen:h ฮฑ = h (choose ฮฒ_in_image_exists) := congrFun hha ()โข h ฮฑ = (g โ f) ฮฑ
have g_eq_h_chosen : g (f ฮฑ) = h (choose ฮฒ_in_image_exists) := A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโโข โ g, h = g โ f
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏฮฑ:Aฮฒ_in_image_exists:โ ฮฑ', f ฮฑ' = f ฮฑ := Exists.intro ฮฑ rflaโ:Point A := fun x โฆ ฮฑaโ:Point A := fun x โฆ choose ฮฒ_in_image_existshfa:f โ aโ = f โ aโ := funext fun x โฆ Eq.symm (choose_spec ฮฒ_in_image_exists)hha:h โ aโ = h โ aโ := H aโ aโ hfah_eq_h_chosen:h ฮฑ = h (choose ฮฒ_in_image_exists) := congrFun hha ()โข (if ฮฒ_in_image : โ ฮฑ_1, f ฮฑ_1 = f ฮฑ then h (choose ฮฒ_in_image) else choice โฏ) = h (choose ฮฒ_in_image_exists)
All goals completed! ๐
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏฮฑ:Aฮฒ_in_image_exists:โ ฮฑ', f ฮฑ' = f ฮฑ := Exists.intro ฮฑ rflaโ:Point A := fun x โฆ ฮฑaโ:Point A := fun x โฆ choose ฮฒ_in_image_existshfa:f โ aโ = f โ aโ := funext fun x โฆ Eq.symm (choose_spec ฮฒ_in_image_exists)hha:h โ aโ = h โ aโ := H aโ aโ hfah_eq_h_chosen:h ฮฑ = h (choose ฮฒ_in_image_exists) := congrFun hha ()g_eq_h_chosen:g (f ฮฑ) = h (choose ฮฒ_in_image_exists) :=
id
(Eq.mpr (id (congrArg (fun _a โฆ _a = h (choose ฮฒ_in_image_exists)) (dif_pos ฮฒ_in_image_exists)))
(Eq.refl (h (choose ฮฒ_in_image_exists))))โข h ฮฑ = g (f ฮฑ)
A:TypeB:TypeC:Typeinstโ:Nonempty Cf:A โถ Bh:A โถ CH:โ (aโ aโ : Point A), f โ aโ = f โ aโ โ h โ aโ = h โ aโg:B โถ C := fun ฮฒ โฆ if ฮฒ_in_image : โ ฮฑ, f ฮฑ = ฮฒ then h (choose ฮฒ_in_image) else choice โฏฮฑ:Aฮฒ_in_image_exists:โ ฮฑ', f ฮฑ' = f ฮฑ := Exists.intro ฮฑ rflaโ:Point A := fun x โฆ ฮฑaโ:Point A := fun x โฆ choose ฮฒ_in_image_existshfa:f โ aโ = f โ aโ := funext fun x โฆ Eq.symm (choose_spec ฮฒ_in_image_exists)hha:h โ aโ = h โ aโ := H aโ aโ hfah_eq_h_chosen:h ฮฑ = h (choose ฮฒ_in_image_exists) := congrFun hha ()g_eq_h_chosen:g (f ฮฑ) = h (choose ฮฒ_in_image_exists) :=
id
(Eq.mpr (id (congrArg (fun _a โฆ _a = h (choose ฮฒ_in_image_exists)) (dif_pos ฮฒ_in_image_exists)))
(Eq.refl (h (choose ฮฒ_in_image_exists))))โข h ฮฑ = h (choose ฮฒ_in_image_exists)
All goals completed! ๐
2. A special case: Constant maps
A map that can be factored through \mathbf{1} is called a constant map.
We implement IsConstantMap in Lean as follows:
def IsConstantMap {A C : Type} (h : A โถ C) :=
โ (f : A โถ One) (g : One โถ C), h = g โ f
3. Choice problems
(a) Show that if there is an f with {g \circ f = h}, then h and g satisfy: For any a in A there is at least one b in B for which {h(a) = g(b)}.
(b) Does the converse hold? That is, if h and g satisfy the condition above, must there be a map f with {h = g \circ f}?
Solution: Exercise 2
We show that part (a) holds.
example {A B C : Type} {g : B โถ C} {h : A โถ C}
(hf : โ f : A โถ B, g โ f = h)
: โ a : A, โ b : B, h a = g b := A:TypeB:TypeC:Typeg:B โถ Ch:A โถ Chf:โ f, g โ f = hโข โ (a : A), โ b, h a = g b
A:TypeB:TypeC:Typeg:B โถ Ch:A โถ Chf:โ f, g โ f = ha:Aโข โ b, h a = g b
A:TypeB:TypeC:Typeg:B โถ Ch:A โถ Ca:Af:A โถ Bhf:g โ f = hโข โ b, h a = g b
A:TypeB:TypeC:Typeg:B โถ Ch:A โถ Ca:Af:A โถ Bhf:g โ f = hโข h a = g (f a)
A:TypeB:TypeC:Typeg:B โถ Ch:A โถ Ca:Af:A โถ Bhf:g โ f = hโข (g โ f) a = g (f a)
All goals completed! ๐
We show that the converse holds in part (b).
example {A B C : Type} {g : B โถ C} {h : A โถ C}
(H : โ a : A, โ b : B, h a = g b)
: โ f : A โถ B, g โ f = h := A:TypeB:TypeC:Typeg:B โถ Ch:A โถ CH:โ (a : A), โ b, h a = g bโข โ f, g โ f = h
A:TypeB:TypeC:Typeg:B โถ Ch:A โถ Cf_fun:A โ Bh_spec:โ (a : A), h a = g (f_fun a)โข โ f, g โ f = h
A:TypeB:TypeC:Typeg:B โถ Ch:A โถ Cf_fun:A โ Bh_spec:โ (a : A), h a = g (f_fun a)โข g โ f_fun = h
A:TypeB:TypeC:Typeg:B โถ Ch:A โถ Cf_fun:A โ Bh_spec:โ (a : A), h a = g (f_fun a)a:Aโข (g โ f_fun) a = h a
All goals completed! ๐
4. Two special cases of division: Sections and retractions
{A \xrightarrow{f} B} is a section of {B \xrightarrow{g} A} if {g \circ f = 1_A}.
See the original presentation of this definition of section in Article II.
5. Stacking or sorting
Draw the internal diagrams of all the sections of f.
Solution: Exercise 3
We label the elements in the first column of A as a_{11}, a_{12}, a_{13}, a_{14} and the elements in the second column of A as a_{21}, a_{22}; we label the element in the first column of B as b_1 and the element in the second column of B as b_2.
inductive A
| aโโ | aโโ | aโโ | aโโ | aโโ | aโโ
deriving Fintype
inductive B
| bโ | bโ
deriving Fintype
def f : A โถ B
| A.aโโ => B.bโ
| A.aโโ => B.bโ
| A.aโโ => B.bโ
| A.aโโ => B.bโ
| A.aโโ => B.bโ
| A.aโโ => B.bโ
Then the sections are
def sโ : B โถ A
| B.bโ => A.aโโ
| B.bโ => A.aโโ
example : f โ sโ = ๐ B := โข f โ sโ = ๐ B x:Bโข (f โ sโ) x = ๐ B x; โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ All goals completed! ๐
def sโ : B โถ A
| B.bโ => A.aโโ
| B.bโ => A.aโโ
example : f โ sโ = ๐ B := โข f โ sโ = ๐ B x:Bโข (f โ sโ) x = ๐ B x; โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ All goals completed! ๐
def sโ : B โถ A
| B.bโ => A.aโโ
| B.bโ => A.aโโ
example : f โ sโ = ๐ B := โข f โ sโ = ๐ B x:Bโข (f โ sโ) x = ๐ B x; โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ All goals completed! ๐
def sโ : B โถ A
| B.bโ => A.aโโ
| B.bโ => A.aโโ
example : f โ sโ = ๐ B := โข f โ sโ = ๐ B x:Bโข (f โ sโ) x = ๐ B x; โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ All goals completed! ๐
def sโ
: B โถ A
| B.bโ => A.aโโ
| B.bโ => A.aโโ
example : f โ sโ
= ๐ B := โข f โ sโ
= ๐ B x:Bโข (f โ sโ
) x = ๐ B x; โข (f โ sโ
) B.bโ = ๐ B B.bโโข (f โ sโ
) B.bโ = ๐ B B.bโ โข (f โ sโ
) B.bโ = ๐ B B.bโโข (f โ sโ
) B.bโ = ๐ B B.bโ All goals completed! ๐
def sโ : B โถ A
| B.bโ => A.aโโ
| B.bโ => A.aโโ
example : f โ sโ = ๐ B := โข f โ sโ = ๐ B x:Bโข (f โ sโ) x = ๐ B x; โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ All goals completed! ๐
def sโ : B โถ A
| B.bโ => A.aโโ
| B.bโ => A.aโโ
example : f โ sโ = ๐ B := โข f โ sโ = ๐ B x:Bโข (f โ sโ) x = ๐ B x; โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ All goals completed! ๐
def sโ : B โถ A
| B.bโ => A.aโโ
| B.bโ => A.aโโ
example : f โ sโ = ๐ B := โข f โ sโ = ๐ B x:Bโข (f โ sโ) x = ๐ B x; โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ โข (f โ sโ) B.bโ = ๐ B B.bโโข (f โ sโ) B.bโ = ๐ B B.bโ All goals completed! ๐