Zulip Chat Archive

Stream: general

Topic: funext n times


Yury G. Kudryashov (Jan 03 2024 at 06:31):

I want to prove inside a metaprogram f = g, where f and g are n-ary functions to Prop. Is there a way to ask Lean to run funext and return a list of FVarIds and a new MVarId like docs#Lean.MVarId.intros does for intro?

Alex J. Best (Jan 03 2024 at 11:30):

You should be able to docs#Lean.MVarId.apply funext n times I guess, I don't know of a better way

Yury G. Kudryashov (Jan 03 2024 at 15:56):

I came up with (not tested yet):

def funext1 (mvarId : MVarId) (n : Option Name) : MetaM (FVarId × MVarId) := do
  let [mvarId']  mvarId.apply (mkConst `funext) | throwError "Expected one goal"
  mvarId'.intro <| n.getD ( mkFreshUserName `a)

def funextList (mvarId : MVarId) (names : List (Option Name)) : MetaM (List FVarId × MVarId) :=
  names.foldlM (fun fvarIds, mvarId name  do
    let fvarId, mvarId  funext1 mvarId name
    pure (fvarIds ++ [fvarId], mvarId)) ([], mvarId)

def funextN (mvarId : MVarId) (n : Nat) : MetaM (List FVarId × MVarId) :=
  funextList mvarId (.replicate n none)

Yury G. Kudryashov (Jan 03 2024 at 15:57):

Is there a way to write funextList so that it doesn't rebuild fvarIds every time? Should I use List.cons instead, then reverse? Or there is a better function?

Kyle Miller (Jan 03 2024 at 16:11):

Have it return Array FVarId and use fvarIds.push fvarId instead

Yury G. Kudryashov (Jan 03 2024 at 16:28):

Something like this?

def funext1 (mvarId : MVarId) (n : Option Name) : MetaM (FVarId × MVarId) := do
  let [mvarId']  mvarId.apply (mkConst `funext) | throwError "Expected one goal"
  mvarId'.intro <| n.getD ( mkFreshUserName `a)

def funextArray (mvarId : MVarId) (names : Array (Option Name)) : MetaM (Array FVarId × MVarId) :=
  names.foldlM (fun fvarIds, mvarId name  do
    let fvarId, mvarId  funext1 mvarId name
    pure (fvarIds.push fvarId, mvarId)) (.mkEmpty names.size, mvarId)

def funextN (mvarId : MVarId) (n : Nat) : MetaM (Array FVarId × MVarId) :=
  funextArray mvarId (.mkArray n none)

Kyle Miller (Jan 03 2024 at 16:36):

mkConst isn't right -- that doesn't set up universe level parameters correctly. You need docs#Lean.Meta.mkConstWithFreshMVarLevels (Mathlib gives docs#Lean.mkConst' for short, though it seems to be its own implementation)

Yury G. Kudryashov (Jan 03 2024 at 16:38):

I'll use&test it later today. Thanks!


Last updated: May 02 2025 at 03:31 UTC