Zulip Chat Archive

Stream: new members

Topic: sequence w/ many variables


Holly Liu (Aug 24 2021 at 01:42):

i'm wondering how one could create a sequence like so: σ₁^{a₁} * σ₂^{b₁} * σ₁^{a₂} * σ₂^{b₂} ... σ₁^{aₙ} * σ₂^{bₙ} where all a₁, b₁, ..., aₙ, bₙ are nonzero integers and only a₁, bₙ may be zero and σ₁, σ₂ : braid_group 2.
i was thinking of inductively doing it but run into the problem of using a separate variable for each a₁, b₁, ..., aₙ, bₙ.
specifically i'm trying to prove that every 3-braid, for some integer n ≥ 0, can be written in this form, though i'm not sure if braid groups affect this problem with variables specifically.

Scott Morrison (Aug 24 2021 at 02:27):

It sounds like you want to create a function from lists of pairs of integers to the 3-strand braid group

Scott Morrison (Aug 24 2021 at 02:28):

(which can just be defined by induction on the list)

Scott Morrison (Aug 24 2021 at 02:28):

and then proving that this function is surjective

Scott Morrison (Aug 24 2021 at 02:28):

(and even surjective when restricted to the subtype with the zero-ness conditions you specified)

Scott Morrison (Aug 24 2021 at 02:28):

(also --- yay braid groups :-)

Yakov Pechersky (Aug 24 2021 at 02:36):

import data.zmod.basic
import group_theory.presented_group
import group_theory.free_group
import data.equiv.mul_add
import algebra.group_power


def alt {S : Type*} :   S  S  free_group S
| 0 _ _ := 1
| (n+1) s t := free_group.of s * alt n t s

def artin_tits_rels (S : Type*) (m : S  S  ) :
  set (free_group S) :=
{g |  s t, g = (alt (m s t) s t)⁻¹ * (alt (m t s) t s)}

/-- Artin-Tits groups.  Traditionally we require that
`∀ s t, m s t = m t s` but the hypothesis isn't used in the definition. -/
abbreviation artin_tits (S : Type*) (m : S  S  ) :=
presented_group (artin_tits_rels S m)

abbreviation braid_group (n : ) :=
artin_tits (fin (n - 1))
  (λ i j, if abs ((i : ) - j) = 1 then 3 else 2)

example (σ₁ σ₂ x : braid_group 2) :
   (la lb : list ) (a0 b0 : ), (list.zip_with (*)
    ((a0 :: (la.map nat.succ)).map (λ k, σ₁ ^ k))
    ((b0 :: (lb.map nat.succ)).map (λ k, σ₂ ^ k)).reverse).prod = x :=
sorry

Yakov Pechersky (Aug 24 2021 at 02:37):

Is that the statement you're trying to prove?

Yakov Pechersky (Aug 24 2021 at 02:37):

Whoops, sorry, this is missing an quantifier. Fixed

Scott Morrison (Aug 24 2021 at 02:51):

You presumably don't want σ₁ σ₂ as variables here, but rather the fixed generators.

Yakov Pechersky (Aug 24 2021 at 02:55):

of 0 and of 1, I take it?

Holly Liu (Aug 24 2021 at 18:36):

thanks for the help!

Yakov Pechersky said:

example (σ₁ σ₂ x : braid_group 2) :
   (la lb : list ) (a0 b0 : ), (list.zip_with (*)
    ((a0 :: (la.map nat.succ)).map (λ k, σ₁ ^ k))
    ((b0 :: (lb.map nat.succ)).map (λ k, σ₂ ^ k)).reverse).prod = x :=
sorry

sorry for the late reply. i was wondering if list.zip_with (*) is just saying a list multiplied by a list is also a list?

Eric Wieser (Aug 24 2021 at 18:43):

docs#list.zip_with

Holly Liu (Aug 24 2021 at 18:48):

yes but what does putting the (*) next to it mean?

Kyle Miller (Aug 24 2021 at 18:50):

hint:

#check (*)

(though this shows some metavariables, but it gives a hint of what it is)

Kyle Miller (Aug 24 2021 at 18:58):

I can't find where it's described in the Lean documentation, but putting an operator in parentheses gives you the operator as a function. You can also do some limited partial application of operators (called sections in Haskell), like (*2) for the multiplication-by-two function. Lean only has "right sections," no "left sections."

Yakov Pechersky (Aug 24 2021 at 18:59):

((*) 2) is the left section

Kyle Miller (Aug 24 2021 at 18:59):

"left section" is a name for the notation itself, so I'm not sure I'd call it a left section, but it's definitely semantically equivalent (and why it's OK that lean doesn't have left sections).

Yakov Pechersky (Aug 24 2021 at 19:00):

Fair point

Yakov Pechersky (Aug 24 2021 at 19:02):

list.zip_with (*) is basically the element-wide product of the elements of two lists.

Yakov Pechersky (Aug 24 2021 at 19:02):

Up to the length of the shortest of the two

Yakov Pechersky (Aug 24 2021 at 19:03):

list.zip_with f xs ys is provably equal to (list.zip xs ys).map (uncurry f)

Yakov Pechersky (Aug 24 2021 at 19:03):

docs#function.uncurry, docs#list.map_uncurry_zip_eq_zip_with

Kyle Miller (Aug 24 2021 at 19:08):

You can tell someone is a Haskeller (or functional programmer) if they reach for zips and maps and such so readily :smile:

Eric Wieser (Aug 24 2021 at 19:08):

(*) is notation for has_mul.mul and is defeq to (λ x y, x * y)

Holly Liu (Aug 24 2021 at 19:13):

Yakov Pechersky said:

Up to the length of the shortest of the two

so you just truncate the rest of it?

Kyle Miller (Aug 24 2021 at 19:18):

I just want to throw out another way of stating what you're wanting to prove.

import data.zmod.basic
import group_theory.presented_group
import group_theory.free_group
import data.equiv.mul_add
import algebra.group_power

def alt {S : Type*} :   S  S  free_group S
| 0 _ _ := 1
| (n+1) s t := free_group.of s * alt n t s

def artin_tits_rels (S : Type*) (m : S  S  ) :
  set (free_group S) :=
{g |  s t, g = (alt (m s t) s t)⁻¹ * (alt (m t s) t s)}

/-- Artin-Tits groups.  Traditionally we require that
`∀ s t, m s t = m t s` but the hypothesis isn't used in the definition. -/
abbreviation artin_tits (S : Type*) (m : S  S  ) :=
presented_group (artin_tits_rels S m)

abbreviation braid_group (n : ) :=
artin_tits (fin (n - 1))
  (λ i j, if abs ((i : ) - j) = 1 then 3 else 2)

section three_braids

def σ₁ : braid_group 3 := presented_group.of 0

def σ₂ : braid_group 3 := presented_group.of 1

def three_braid_of : list   braid_group 3
| [] := 1
| [m] := σ₁ ^ m
| (m :: n :: rest) := σ₁ ^ m * σ₂ ^ n * three_braid_of rest

example : three_braid_of [1,2,-1] = σ₁ * σ₂^2 * σ₁^-1 := rfl

example (x : braid_group 3) :  (l : list ), three_braid_of l = x :=
sorry

-- Or:
example : function.surjective three_braid_of :=
sorry

end three_braids

Kyle Miller (Aug 24 2021 at 19:19):

Holly Liu said:

Yakov Pechersky said:

Up to the length of the shortest of the two

so you just truncate the rest of it?

He's telling you a technical detail about how zip_with works. You may as well assume la and lb in the example have the same length because of this.

Kyle Miller (Aug 24 2021 at 19:26):

(I updated the code I just posted to use the integers instead of natural numbers, and to include an example of three_braid_of.)

Note that it does not include conditions on the list of integers. I'm not sure why you want this theorem exactly -- what's your larger goal?

Eric Rodriguez (Aug 24 2021 at 19:36):

Kyle Miller said:

You can tell someone is a Haskeller (or functional programmer) if they reach for zips and maps and such so readily :smile:

(There was one time I was tempted to write flip ($) in Lean.)

what would flip ($) do? :shock:

Holly Liu (Aug 24 2021 at 19:38):

oh so the code with la,lb is multiplying σ1a1,...σ1an\sigma_1^{a_1}, ... \sigma_1^{a_n} to σ2b1,...,σ2bn\sigma_2^{b_1}, ..., \sigma_2^{b_n}. that makes more sense. i was just curious if lean implements list.prod to lose elements when multiplying two differently lengthed lists together.
right now i'm just trying to code some exercises in a braid textbook. ultimately the original goal was to code enough of braid groups to PR it although that seems unlikely for now.

Eric Wieser (Aug 24 2021 at 19:43):

docs#list.prod only acts on a single list not on two lists

Eric Wieser (Aug 24 2021 at 19:43):

@Eric Rodriguez: I would imagine flip ($) = function.eval, docs#function.eval

Holly Liu (Aug 24 2021 at 19:45):

oh oops, i think i meant list.zip_with (*)

Eric Wieser (Aug 24 2021 at 19:54):

Lean is quite unforgiving if you type something different to what you mean ;).


Last updated: Dec 20 2023 at 11:08 UTC