leanprover-community / mathlib4

The math library of Lean 4

Home Page:https://leanprover-community.github.io/mathlib4_docs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`unexpected bound variable` error in `simp`

semorrison opened this issue · comments

In Mathlib/Algebra/Group/Hom/Instances.lean on the bump/nightly-2024-03-13 branch (and probably later bump/v4.8.0, or even thereafter master, we have a

      simp [zpow_add_one]
      simp [mul_comm]

and combining this into a single simp call as

      simp [zpow_add_one, mul_comm]

generates an error unexpected bound variable #0. This is almost certainly a bug, and hopefully someone can work on minimizing it to a no imports example.

It seems that this issue is already present on master (and thus shouldn't block the bump I guess?). I am having real trouble minimising. Here's the issue on current master:

import Mathlib.Algebra.Group.Hom.Basic
import Mathlib.Algebra.GroupPower.Basic

universe uM uN

variable {M : Type uM} {N : Type uN} {G : Type} -- both universes needed

-- this instance needed
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul_assoc := sorry
  one_mul := sorry
  mul_one := sorry
  mul_comm := sorry

-- failing to extract, but I'm surprised `simp only [mul_comm]` hangs Lean.
example {M} [MulOneClass M] [CommGroup G] :
    let zpow : ℤ → (M →* G) → (M →* G) := fun n f => { toFun := fun x => f x ^ n, map_one' := sorry, map_mul' := sorry }
    ∀ (n : ℕ) (a : M →* G), zpow (Int.ofNat (Nat.succ n)) a = a * zpow (Int.ofNat n) a := by
--  simp only [mul_comm] -- hangs. Is this to be expected?
  sorry

-- {M} needed! Note that we now have an `M✝: Type uM` and `M: Type u_1`
instance MonoidHom.commGroup {M} [MulOneClass M] [CommGroup G] : CommGroup (M →* G) where
  mul_assoc := sorry
  one_mul := sorry
  mul_one := sorry
  mul_comm := sorry
  div_eq_mul_inv := sorry
  mul_left_inv := sorry
  zpow := fun n f =>
    { toFun := fun x => f x ^ n,
      map_one' := sorry,
      map_mul' := sorry }
  zpow_zero' := sorry
  zpow_succ' := fun n f => by
    simp only [Int.ofNat_eq_coe, zpow_coe_nat]
    ext x
    dsimp only
    -- If I try any of: extracting the goal, replacing `{ toFun := fun x => f x ^ Nat.succ n, map_one' := ⋯ }`
    -- by `foo` with `let foo := { toFun := fun x => f x ^ Nat.succ n, map_one' := ⋯ }`, removing universes uM and uN,
    -- removing the monoid instance above, or removing the {M} in the type of this instance, then the issue disappears.
    simp only [mul_comm] -- error: "unexpected bound variable #1"
    sorry
  zpow_neg' := sorry

It's maybe something to do with there being a variable M and a variable M-dagger? Should simp only [mul_comm] hang? I know it theoretically might put Lean into a loop, but example (a b : ℕ) : b * a = 37 := by simp only [mul_comm] doesn't hang Lean.

structure MonoidHom (M : Type _) (N : Type _) [Mul M] [Mul N] where
  toFun : M → N
  map_mul' : ∀ x y, toFun (x * y) = toFun x * toFun y

class CommMagma (G : Type _) extends Mul G where
  mul_comm : ∀ a b : G, a * b = b * a

set_option quotPrecheck false
infixr:25 " →*' " => MonoidHom

instance [Mul M] [Mul N] : CoeFun (M →*' N) (fun _ => M → N) where
  coe := MonoidHom.toFun

open CommMagma

-- -- this instance needed
instance MonoidHom.commMonoid [Mul M] [Mul N] :
    CommMagma (M →*' N) where
  mul := fun f g => { toFun := fun x => f x * g x, map_mul' := sorry }
  mul_comm := sorry

example {M} [Mul M] [Mul G] [Pow G ℤ] :
    let zpow : ℤ → (M →*' G) → (M →*' G) := fun n f => { toFun := fun x => f x ^ n, map_mul' := sorry }
    ∀ (n : ℕ) (a : M →*' G), zpow (Int.ofNat (Nat.succ n)) a = a * zpow (Int.ofNat n) a := by
  -- simp only [Int.ofNat_eq_coe, zpow_coe_nat]
  simp only [mul_comm] -- hangs. Is this to be expected?
  sorry

I can get the timeout here

Mathlib free

structure MonoidHom (M : Type _) (N : Type _) [Mul M] [Mul N] where
  toFun : M → N
  map_mul' : ∀ x y, toFun (x * y) = toFun x * toFun y

class CommMagma (G : Type _) extends Mul G where
  mul_comm : ∀ a b : G, a * b = b * a

set_option quotPrecheck false
infixr:25 " →*' " => MonoidHom

instance [Mul M] [Mul N] : CoeFun (M →*' N) (fun _ => M → N) where
  coe := MonoidHom.toFun

open CommMagma

-- -- this instance needed
instance MonoidHom.commMonoid [Mul M] [Mul N] :
    CommMagma (M →*' N) where
  mul := fun f g => { toFun := fun x => f x * g x, map_mul' := sorry }
  mul_comm := sorry

example {M} [Mul M] [Mul G] [Pow G Int] :
    let zpow : Int → (M →*' G) → (M →*' G) := fun n f => { toFun := fun x => f x ^ n, map_mul' := sorry }
    ∀ (n : Nat) (a : M →*' G), zpow (Int.ofNat (Nat.succ n)) a = a * zpow (Int.ofNat n) a := by
  simp only [Int.ofNat_eq_coe] -- commenting out this line makes simp loop
  simp only [mul_comm] -- unexpected bound variable 2 
  sorry

This issue should probably now be migrated to the Lean repo. What is the protocol here @semorrison ?

As they are in different organisations we can't migrate: it just needs a new issue.