File: .lake/packages/lean4/src/lean/Lean/Meta/SynthInstance.lean

full_name: Lean.Meta.initFn._@..lake.packages.lean4.src.lean.Lean.Meta.SynthInstance._hyg.6
code: register_builtin_option synthInstance.maxHeartbeats : Nat := {
  defValue := 20000
  descr := "maximum amount of heartbeats per typeclass resolution problem. A heartbeat is number of (small) memory allocations (in thousands), 0 means no limit"
}
goal: IO (Lean.Option Nat)

full_name: Lean.Meta.synthInstance.maxHeartbeats
code: register_builtin_option synthInstance.maxHeartbeats : Nat := {
  defValue := 20000
  descr := "maximum amount of heartbeats per typeclass resolution problem. A heartbeat is number of (small) memory allocations (in thousands), 0 means no limit"
}
goal: Lean.Option Nat

full_name: Lean.Meta.initFn._@..lake.packages.lean4.src.lean.Lean.Meta.SynthInstance._hyg.47
code: register_builtin_option synthInstance.maxSize : Nat := {
  defValue := 128
  descr := "maximum number of instances used to construct a solution in the type class instance synthesis procedure"
}
goal: IO (Lean.Option Nat)

full_name: Lean.Meta.synthInstance.maxSize
code: register_builtin_option synthInstance.maxSize : Nat := {
  defValue := 128
  descr := "maximum number of instances used to construct a solution in the type class instance synthesis procedure"
}
goal: Lean.Option Nat

full_name: Lean.Meta.initFn._@..lake.packages.lean4.src.lean.Lean.Meta.SynthInstance._hyg.88
code: register_builtin_option backward.synthInstance.canonInstances : Bool := {
  defValue := true
  group    := "backward compatibility"
  descr := "use optimization that relies on 'morally canonical' instances during type class resolution"
}
goal: IO (Lean.Option Bool)

full_name: Lean.Meta.backward.synthInstance.canonInstances
code: register_builtin_option backward.synthInstance.canonInstances : Bool := {
  defValue := true
  group    := "backward compatibility"
  descr := "use optimization that relies on 'morally canonical' instances during type class resolution"
}
goal: Lean.Option Bool

full_name: Lean.Meta.SynthInstance.getMaxHeartbeats
code: def getMaxHeartbeats (opts : Options) : Nat 
goal: Nat

full_name: Lean.Meta.SynthInstance.Instance
code: structure Instance where
  val : Expr
  synthOrder : Array Nat
  deriving Inhabited
goal: Type

full_name: Lean.Meta.SynthInstance.instInhabitedInstance
code: structure Instance where
  val : Expr
  synthOrder : Array Nat
  deriving Inhabited
goal: Inhabited Lean.Meta.SynthInstance.Instance

full_name: Lean.Meta.SynthInstance.Instance.val
code: structure Instance where
  val : Expr
  synthOrder : Array Nat
  deriving Inhabited
goal: Lean.Expr

full_name: Lean.Meta.SynthInstance.Instance.synthOrder
code: structure Instance where
  val : Expr
  synthOrder : Array Nat
  deriving Inhabited
goal: Array Nat

full_name: Lean.Meta.SynthInstance.GeneratorNode.currInstanceIdx
code: structure GeneratorNode where
  mvar            : Expr
  key             : Expr
  mctx            : MetavarContext
  instances       : Array Instance
  currInstanceIdx : Nat
  /--
  `typeHasMVars := true` if type of `mvar` contains metavariables.
  We store this information to implement an optimization that relies on the fact
  that instances are "morally canonical."
  That is, we need to find at most one answer for this generator node if the type
  does not have metavariables.
  -/
  typeHasMVars    : Bool
  deriving Inhabited
goal: Nat

full_name: Lean.Meta.SynthInstance.GeneratorNode.key
code: structure GeneratorNode where
  mvar            : Expr
  key             : Expr
  mctx            : MetavarContext
  instances       : Array Instance
  currInstanceIdx : Nat
  /--
  `typeHasMVars := true` if type of `mvar` contains metavariables.
  We store this information to implement an optimization that relies on the fact
  that instances are "morally canonical."
  That is, we need to find at most one answer for this generator node if the type
  does not have metavariables.
  -/
  typeHasMVars    : Bool
  deriving Inhabited
goal: Lean.Expr

full_name: Lean.Meta.SynthInstance.GeneratorNode.typeHasMVars
code: structure GeneratorNode where
  mvar            : Expr
  key             : Expr
  mctx            : MetavarContext
  instances       : Array Instance
  currInstanceIdx : Nat
  /--
  `typeHasMVars := true` if type of `mvar` contains metavariables.
  We store this information to implement an optimization that relies on the fact
  that instances are "morally canonical."
  That is, we need to find at most one answer for this generator node if the type
  does not have metavariables.
  -/
  typeHasMVars    : Bool
  deriving Inhabited
goal: Bool

full_name: Lean.Meta.SynthInstance.GeneratorNode.instances
code: structure GeneratorNode where
  mvar            : Expr
  key             : Expr
  mctx            : MetavarContext
  instances       : Array Instance
  currInstanceIdx : Nat
  /--
  `typeHasMVars := true` if type of `mvar` contains metavariables.
  We store this information to implement an optimization that relies on the fact
  that instances are "morally canonical."
  That is, we need to find at most one answer for this generator node if the type
  does not have metavariables.
  -/
  typeHasMVars    : Bool
  deriving Inhabited
goal: Array Lean.Meta.SynthInstance.Instance

full_name: Lean.Meta.SynthInstance.GeneratorNode.mvar
code: structure GeneratorNode where
  mvar            : Expr
  key             : Expr
  mctx            : MetavarContext
  instances       : Array Instance
  currInstanceIdx : Nat
  /--
  `typeHasMVars := true` if type of `mvar` contains metavariables.
  We store this information to implement an optimization that relies on the fact
  that instances are "morally canonical."
  That is, we need to find at most one answer for this generator node if the type
  does not have metavariables.
  -/
  typeHasMVars    : Bool
  deriving Inhabited
goal: Lean.Expr

full_name: Lean.Meta.SynthInstance.GeneratorNode
code: structure GeneratorNode where
  mvar            : Expr
  key             : Expr
  mctx            : MetavarContext
  instances       : Array Instance
  currInstanceIdx : Nat
  /--
  `typeHasMVars := true` if type of `mvar` contains metavariables.
  We store this information to implement an optimization that relies on the fact
  that instances are "morally canonical."
  That is, we need to find at most one answer for this generator node if the type
  does not have metavariables.
  -/
  typeHasMVars    : Bool
  deriving Inhabited
goal: Type

full_name: Lean.Meta.SynthInstance.instInhabitedGeneratorNode
code: structure GeneratorNode where
  mvar            : Expr
  key             : Expr
  mctx            : MetavarContext
  instances       : Array Instance
  currInstanceIdx : Nat
  /--
  `typeHasMVars := true` if type of `mvar` contains metavariables.
  We store this information to implement an optimization that relies on the fact
  that instances are "morally canonical."
  That is, we need to find at most one answer for this generator node if the type
  does not have metavariables.
  -/
  typeHasMVars    : Bool
  deriving Inhabited
goal: Inhabited Lean.Meta.SynthInstance.GeneratorNode

full_name: Lean.Meta.SynthInstance.GeneratorNode.mctx
code: structure GeneratorNode where
  mvar            : Expr
  key             : Expr
  mctx            : MetavarContext
  instances       : Array Instance
  currInstanceIdx : Nat
  /--
  `typeHasMVars := true` if type of `mvar` contains metavariables.
  We store this information to implement an optimization that relies on the fact
  that instances are "morally canonical."
  That is, we need to find at most one answer for this generator node if the type
  does not have metavariables.
  -/
  typeHasMVars    : Bool
  deriving Inhabited
goal: Lean.MetavarContext

full_name: Lean.Meta.SynthInstance.ConsumerNode.mvar
code: structure ConsumerNode where
  mvar     : Expr
  key      : Expr
  mctx     : MetavarContext
  subgoals : List Expr
  size     : Nat -- instance size so far
  deriving Inhabited
goal: Lean.Expr

full_name: Lean.Meta.SynthInstance.instInhabitedConsumerNode
code: structure ConsumerNode where
  mvar     : Expr
  key      : Expr
  mctx     : MetavarContext
  subgoals : List Expr
  size     : Nat -- instance size so far
  deriving Inhabited
goal: Inhabited Lean.Meta.SynthInstance.ConsumerNode

full_name: Lean.Meta.SynthInstance.ConsumerNode.subgoals
code: structure ConsumerNode where
  mvar     : Expr
  key      : Expr
  mctx     : MetavarContext
  subgoals : List Expr
  size     : Nat -- instance size so far
  deriving Inhabited
goal: List Lean.Expr

full_name: Lean.Meta.SynthInstance.ConsumerNode
code: structure ConsumerNode where
  mvar     : Expr
  key      : Expr
  mctx     : MetavarContext
  subgoals : List Expr
  size     : Nat -- instance size so far
  deriving Inhabited
goal: Type

full_name: Lean.Meta.SynthInstance.ConsumerNode.size
code: structure ConsumerNode where
  mvar     : Expr
  key      : Expr
  mctx     : MetavarContext
  subgoals : List Expr
  size     : Nat -- instance size so far
  deriving Inhabited
goal: Nat

full_name: Lean.Meta.SynthInstance.ConsumerNode.key
code: structure ConsumerNode where
  mvar     : Expr
  key      : Expr
  mctx     : MetavarContext
  subgoals : List Expr
  size     : Nat -- instance size so far
  deriving Inhabited
goal: Lean.Expr

full_name: Lean.Meta.SynthInstance.ConsumerNode.mctx
code: structure ConsumerNode where
  mvar     : Expr
  key      : Expr
  mctx     : MetavarContext
  subgoals : List Expr
  size     : Nat -- instance size so far
  deriving Inhabited
goal: Lean.MetavarContext

full_name: Lean.Meta.SynthInstance.Waiter.consumerNode
code: inductive Waiter where
  | consumerNode : ConsumerNode → Waiter
  | root         : Waiter
goal: Lean.Meta.SynthInstance.ConsumerNode → Lean.Meta.SynthInstance.Waiter

full_name: Lean.Meta.SynthInstance.Waiter
code: inductive Waiter where
  | consumerNode : ConsumerNode → Waiter
  | root         : Waiter
goal: Type

full_name: Lean.Meta.SynthInstance.Waiter.root
code: inductive Waiter where
  | consumerNode : ConsumerNode → Waiter
  | root         : Waiter
goal: Lean.Meta.SynthInstance.Waiter

full_name: Lean.Meta.SynthInstance.Waiter.isRoot
code: def Waiter.isRoot : Waiter → Bool
  
goal: Lean.Meta.SynthInstance.Waiter → Bool

full_name: Lean.Meta.SynthInstance.MkTableKey.State
code: structure State where
  nextIdx : Nat := 0
  lmap    : HashMap LMVarId Level := {}
  emap    : HashMap MVarId Expr := {}
  mctx    : MetavarContext
goal: Type

full_name: Lean.Meta.SynthInstance.MkTableKey.State.lmap
code: structure State where
  nextIdx : Nat := 0
  lmap    : HashMap LMVarId Level := {}
  emap    : HashMap MVarId Expr := {}
  mctx    : MetavarContext
goal: Lean.HashMap Lean.LMVarId Lean.Level

full_name: Lean.Meta.SynthInstance.MkTableKey.State.nextIdx
code: structure State where
  nextIdx : Nat := 0
  lmap    : HashMap LMVarId Level := {}
  emap    : HashMap MVarId Expr := {}
  mctx    : MetavarContext
goal: Nat

full_name: Lean.Meta.SynthInstance.MkTableKey.State.emap
code: structure State where
  nextIdx : Nat := 0
  lmap    : HashMap LMVarId Level := {}
  emap    : HashMap MVarId Expr := {}
  mctx    : MetavarContext
goal: Lean.HashMap Lean.MVarId Lean.Expr

full_name: Lean.Meta.SynthInstance.MkTableKey.State.mctx
code: structure State where
  nextIdx : Nat := 0
  lmap    : HashMap LMVarId Level := {}
  emap    : HashMap MVarId Expr := {}
  mctx    : MetavarContext
goal: Lean.MetavarContext

full_name: Lean.Meta.SynthInstance.MkTableKey.M
code: abbrev M 
goal: Type

full_name: Lean.Meta.SynthInstance.MkTableKey.instMonadMCtxM
code: @[always_inline]
instance : MonadMCtx M 
goal: Lean.MonadMCtx Lean.Meta.SynthInstance.MkTableKey.M

full_name: Lean.Meta.SynthInstance.MkTableKey.normLevel
code: partial def normLevel (u : Level) : M Level 
goal: Lean.Meta.SynthInstance.MkTableKey.M Lean.Level

full_name: Lean.Meta.SynthInstance.MkTableKey.normExpr
code: partial def normExpr (e : Expr) : M Expr 
goal: Lean.Meta.SynthInstance.MkTableKey.M Lean.Expr

full_name: Lean.Meta.SynthInstance.mkTableKey
code: /-- Remark: `mkTableKey` assumes `e` does not contain assigned metavariables. -/
def mkTableKey [Monad m] [MonadMCtx m] (e : Expr) : m Expr 
goal: m Lean.Expr

full_name: Lean.Meta.SynthInstance.instInhabitedAnswer
code: structure Answer where
  result     : AbstractMVarsResult
  resultType : Expr
  size       : Nat
  deriving Inhabited
goal: Inhabited Lean.Meta.SynthInstance.Answer

full_name: Lean.Meta.SynthInstance.Answer.result
code: structure Answer where
  result     : AbstractMVarsResult
  resultType : Expr
  size       : Nat
  deriving Inhabited
goal: Lean.Meta.AbstractMVarsResult

full_name: Lean.Meta.SynthInstance.Answer.resultType
code: structure Answer where
  result     : AbstractMVarsResult
  resultType : Expr
  size       : Nat
  deriving Inhabited
goal: Lean.Expr

full_name: Lean.Meta.SynthInstance.Answer
code: structure Answer where
  result     : AbstractMVarsResult
  resultType : Expr
  size       : Nat
  deriving Inhabited
goal: Type

full_name: Lean.Meta.SynthInstance.Answer.size
code: structure Answer where
  result     : AbstractMVarsResult
  resultType : Expr
  size       : Nat
  deriving Inhabited
goal: Nat

full_name: Lean.Meta.SynthInstance.TableEntry.answers
code: structure TableEntry where
  waiters : Array Waiter
  answers : Array Answer := #[]
goal: Array Lean.Meta.SynthInstance.Answer

full_name: Lean.Meta.SynthInstance.TableEntry
code: structure TableEntry where
  waiters : Array Waiter
  answers : Array Answer := #[]
goal: Type

full_name: Lean.Meta.SynthInstance.TableEntry.waiters
code: structure TableEntry where
  waiters : Array Waiter
  answers : Array Answer := #[]
goal: Array Lean.Meta.SynthInstance.Waiter

full_name: Lean.Meta.SynthInstance.Context.maxResultSize
code: structure Context where
  maxResultSize : Nat
  maxHeartbeats : Nat
goal: Nat

full_name: Lean.Meta.SynthInstance.Context
code: structure Context where
  maxResultSize : Nat
  maxHeartbeats : Nat
goal: Type

full_name: Lean.Meta.SynthInstance.Context.maxHeartbeats
code: structure Context where
  maxResultSize : Nat
  maxHeartbeats : Nat
goal: Nat

full_name: Lean.Meta.SynthInstance.State.result?
code: /--
  Remark: the SynthInstance.State is not really an extension of `Meta.State`.
  The field `postponed` is not needed, and the field `mctx` is misleading since
  `synthInstance` methods operate over different `MetavarContext`s simultaneously.
  That being said, we still use `extends` because it makes it simpler to move from
  `M` to `MetaM`.
-/
structure State where
  result?        : Option AbstractMVarsResult    := none
  generatorStack : Array GeneratorNode           := #[]
  resumeStack    : Array (ConsumerNode × Answer) := #[]
  tableEntries   : HashMap Expr TableEntry       := {}
goal: Option Lean.Meta.AbstractMVarsResult

full_name: Lean.Meta.SynthInstance.State.generatorStack
code: /--
  Remark: the SynthInstance.State is not really an extension of `Meta.State`.
  The field `postponed` is not needed, and the field `mctx` is misleading since
  `synthInstance` methods operate over different `MetavarContext`s simultaneously.
  That being said, we still use `extends` because it makes it simpler to move from
  `M` to `MetaM`.
-/
structure State where
  result?        : Option AbstractMVarsResult    := none
  generatorStack : Array GeneratorNode           := #[]
  resumeStack    : Array (ConsumerNode × Answer) := #[]
  tableEntries   : HashMap Expr TableEntry       := {}
goal: Array Lean.Meta.SynthInstance.GeneratorNode

full_name: Lean.Meta.SynthInstance.State.tableEntries
code: /--
  Remark: the SynthInstance.State is not really an extension of `Meta.State`.
  The field `postponed` is not needed, and the field `mctx` is misleading since
  `synthInstance` methods operate over different `MetavarContext`s simultaneously.
  That being said, we still use `extends` because it makes it simpler to move from
  `M` to `MetaM`.
-/
structure State where
  result?        : Option AbstractMVarsResult    := none
  generatorStack : Array GeneratorNode           := #[]
  resumeStack    : Array (ConsumerNode × Answer) := #[]
  tableEntries   : HashMap Expr TableEntry       := {}
goal: Lean.HashMap Lean.Expr Lean.Meta.SynthInstance.TableEntry

full_name: Lean.Meta.SynthInstance.State.resumeStack
code: /--
  Remark: the SynthInstance.State is not really an extension of `Meta.State`.
  The field `postponed` is not needed, and the field `mctx` is misleading since
  `synthInstance` methods operate over different `MetavarContext`s simultaneously.
  That being said, we still use `extends` because it makes it simpler to move from
  `M` to `MetaM`.
-/
structure State where
  result?        : Option AbstractMVarsResult    := none
  generatorStack : Array GeneratorNode           := #[]
  resumeStack    : Array (ConsumerNode × Answer) := #[]
  tableEntries   : HashMap Expr TableEntry       := {}
goal: Array (Lean.Meta.SynthInstance.ConsumerNode × Lean.Meta.SynthInstance.Answer)

full_name: Lean.Meta.SynthInstance.State
code: /--
  Remark: the SynthInstance.State is not really an extension of `Meta.State`.
  The field `postponed` is not needed, and the field `mctx` is misleading since
  `synthInstance` methods operate over different `MetavarContext`s simultaneously.
  That being said, we still use `extends` because it makes it simpler to move from
  `M` to `MetaM`.
-/
structure State where
  result?        : Option AbstractMVarsResult    := none
  generatorStack : Array GeneratorNode           := #[]
  resumeStack    : Array (ConsumerNode × Answer) := #[]
  tableEntries   : HashMap Expr TableEntry       := {}
goal: Type

full_name: Lean.Meta.SynthInstance.SynthM
code: abbrev SynthM 
goal: Type

full_name: Lean.Meta.SynthInstance.checkSystem
code: def checkSystem : SynthM Unit 
goal: Lean.Meta.SynthInstance.SynthM Unit

full_name: Lean.Meta.SynthInstance.instInhabitedSynthM
code: instance : Inhabited (SynthM α) 
goal: Inhabited (Lean.Meta.SynthInstance.SynthM α)

full_name: Lean.Meta.SynthInstance.getInstances
code: /-- Return globals and locals instances that may unify with `type` -/
def getInstances (type : Expr) : MetaM (Array Instance) 
goal: Lean.MetaM (Array Lean.Meta.SynthInstance.Instance)

full_name: Lean.Meta.SynthInstance.mkGeneratorNode?
code: def mkGeneratorNode? (key mvar : Expr) : MetaM (Option GeneratorNode) 
goal: Lean.MetaM (Option Lean.Meta.SynthInstance.GeneratorNode)

full_name: Lean.Meta.SynthInstance.newSubgoal
code: /--
  Create a new generator node for `mvar` and add `waiter` as its waiter.
  `key` must be `mkTableKey mctx mvarType`. -/
def newSubgoal (mctx : MetavarContext) (key : Expr) (mvar : Expr) (waiter : Waiter) : SynthM Unit 
goal: Lean.Meta.SynthInstance.SynthM Unit

full_name: Lean.Meta.SynthInstance.findEntry?
code: def findEntry? (key : Expr) : SynthM (Option TableEntry) 
goal: Lean.Meta.SynthInstance.SynthM (Option Lean.Meta.SynthInstance.TableEntry)

full_name: Lean.Meta.SynthInstance.getEntry
code: def getEntry (key : Expr) : SynthM TableEntry 
goal: Lean.Meta.SynthInstance.SynthM Lean.Meta.SynthInstance.TableEntry

full_name: Lean.Meta.SynthInstance.mkTableKeyFor
code: /--
  Create a `key` for the goal associated with the given metavariable.
  That is, we create a key for the type of the metavariable.

  We must instantiate assigned metavariables before we invoke `mkTableKey`. -/
def mkTableKeyFor (mctx : MetavarContext) (mvar : Expr) : SynthM Expr 
goal: Lean.Meta.SynthInstance.SynthM Lean.Expr

full_name: Lean.Meta.SynthInstance.SubgoalsResult
code: /-- See `getSubgoals` and `getSubgoalsAux`

   We use the parameter `j` to reduce the number of `instantiate*` invocations.
   It is the same approach we use at `forallTelescope` and `lambdaTelescope`.
   Given `getSubgoalsAux args j subgoals instVal type`,
   we have that `type.instantiateRevRange j args.size args` does not have loose bound variables. -/
structure SubgoalsResult where
  subgoals     : List Expr
  instVal      : Expr
  instTypeBody : Expr
goal: Type

full_name: Lean.Meta.SynthInstance.SubgoalsResult.instVal
code: /-- See `getSubgoals` and `getSubgoalsAux`

   We use the parameter `j` to reduce the number of `instantiate*` invocations.
   It is the same approach we use at `forallTelescope` and `lambdaTelescope`.
   Given `getSubgoalsAux args j subgoals instVal type`,
   we have that `type.instantiateRevRange j args.size args` does not have loose bound variables. -/
structure SubgoalsResult where
  subgoals     : List Expr
  instVal      : Expr
  instTypeBody : Expr
goal: Lean.Expr

full_name: Lean.Meta.SynthInstance.SubgoalsResult.instTypeBody
code: /-- See `getSubgoals` and `getSubgoalsAux`

   We use the parameter `j` to reduce the number of `instantiate*` invocations.
   It is the same approach we use at `forallTelescope` and `lambdaTelescope`.
   Given `getSubgoalsAux args j subgoals instVal type`,
   we have that `type.instantiateRevRange j args.size args` does not have loose bound variables. -/
structure SubgoalsResult where
  subgoals     : List Expr
  instVal      : Expr
  instTypeBody : Expr
goal: Lean.Expr

full_name: Lean.Meta.SynthInstance.SubgoalsResult.subgoals
code: /-- See `getSubgoals` and `getSubgoalsAux`

   We use the parameter `j` to reduce the number of `instantiate*` invocations.
   It is the same approach we use at `forallTelescope` and `lambdaTelescope`.
   Given `getSubgoalsAux args j subgoals instVal type`,
   we have that `type.instantiateRevRange j args.size args` does not have loose bound variables. -/
structure SubgoalsResult where
  subgoals     : List Expr
  instVal      : Expr
  instTypeBody : Expr
goal: List Lean.Expr

full_name: Lean.Meta.SynthInstance.getSubgoals
code: /--
  `getSubgoals lctx localInsts xs inst` creates the subgoals for the instance `inst`.
  The subgoals are in the context of the free variables `xs`, and
  `(lctx, localInsts)` is the local context and instances before we added the free variables to it.

  This extra complication is required because
    1- We want all metavariables created by `synthInstance` to share the same local context.
    2- We want to ensure that applications such as `mvar xs` are higher order patterns.

  The method `getGoals` create a new metavariable for each parameter of `inst`.
  For example, suppose the type of `inst` is `forall (x_1 : A_1) ... (x_n : A_n), B x_1 ... x_n`.
  Then, we create the metavariables `?m_i : forall xs, A_i`, and return the subset of these
  metavariables that are instance implicit arguments, and the expressions:
    - `inst (?m_1 xs) ... (?m_n xs)` (aka `instVal`)
    - `B (?m_1 xs) ... (?m_n xs)` -/
def getSubgoals (lctx : LocalContext) (localInsts : LocalInstances) (xs : Array Expr) (inst : Instance) : MetaM SubgoalsResult 
goal: Lean.MetaM Lean.Meta.SynthInstance.SubgoalsResult

full_name: Lean.Meta.SynthInstance.tryResolve
code: /--
  Try to synthesize metavariable `mvar` using the instance `inst`.
  Remark: `mctx` is set using `withMCtx`.
  If it succeeds, the result is a new updated metavariable context and a new list of subgoals.
  A subgoal is created for each instance implicit parameter of `inst`. -/
def tryResolve (mvar : Expr) (inst : Instance) : MetaM (Option (MetavarContext × List Expr)) 
goal: Lean.MetaM (Option (Lean.MetavarContext × List Lean.Expr))

full_name: Lean.Meta.SynthInstance.tryAnswer
code: /--
  Assign a precomputed answer to `mvar`.
  If it succeeds, the result is a new updated metavariable context and a new list of subgoals. -/
def tryAnswer (mctx : MetavarContext) (mvar : Expr) (answer : Answer) : SynthM (Option MetavarContext) 
goal: Lean.Meta.SynthInstance.SynthM (Option Lean.MetavarContext)

full_name: Lean.Meta.SynthInstance.wakeUp
code: /-- Move waiters that are waiting for the given answer to the resume stack. -/
def wakeUp (answer : Answer) : Waiter → SynthM Unit
  
goal: Lean.Meta.SynthInstance.Waiter → Lean.Meta.SynthInstance.SynthM Unit

full_name: Lean.Meta.SynthInstance.isNewAnswer
code: def isNewAnswer (oldAnswers : Array Answer) (answer : Answer) : Bool 
goal: Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.SynthInstance.0.Lean.Meta.SynthInstance.mkAnswer
code: private def mkAnswer (cNode : ConsumerNode) : MetaM Answer 
goal: Lean.MetaM Lean.Meta.SynthInstance.Answer

full_name: Lean.Meta.SynthInstance.addAnswer
code: /--
  Create a new answer after `cNode` resolved all subgoals.
  That is, `cNode.subgoals == []`.
  And then, store it in the tabled entries map, and wakeup waiters. -/
def addAnswer (cNode : ConsumerNode) : SynthM Unit 
goal: Lean.Meta.SynthInstance.SynthM Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.SynthInstance.0.Lean.Meta.SynthInstance.hasUnusedArguments
code: /--
  Return `true` if a type of the form `(a_1 : A_1) → ... → (a_n : A_n) → B` has an unused argument `a_i`.

  Remark: This is syntactic check and no reduction is performed.
-/
private def hasUnusedArguments : Expr → Bool
  
goal: Lean.Expr → Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.SynthInstance.0.Lean.Meta.SynthInstance.removeUnusedArguments?
code: /--
  If the type of the metavariable `mvar` has unused argument, return a pair `(α, transformer)`
  where `α` is a new type without the unused arguments and the `transformer` is a function for coverting a
  solution with type `α` into a value that can be assigned to `mvar`.
  Example: suppose `mvar` has type `(a : A) → (b : B a) → (c : C a) → D a c`, the result is the pair
  ```
  ((a : A) → (c : C a) → D a c,
   fun (f : (a : A) → (c : C a) → D a c) (a : A) (b : B a) (c : C a) => f a c
  )
  ```

  This method is used to improve the effectiveness of the TC resolution procedure. It was suggested and prototyped by
  Tomas Skrivan. It improves the support for instances of type `a : A → C` where `a` does not appear in class `C`.
  When we look for such an instance it is enough to look for an instance `c : C` and then return `fun _ => c`.

  Tomas' approach makes sure that instance of a type like `a : A → C` never gets tabled/cached. More on that later.
  At the core is this method. it takes an expression E and does two things:

  The modification to TC resolution works this way: We are looking for an instance of `E`, if it is tabled
  just get it as normal, but if not first remove all unused arguments producing `E'`. Now we look up the table again but
  for `E'`. If it exists, use the transformer to create E. If it does not exists, create a new goal `E'`.
-/
private def removeUnusedArguments? (mctx : MetavarContext) (mvar : Expr) : MetaM (Option (Expr × Expr)) 
goal: Lean.MetaM (Option (Lean.Expr × Lean.Expr))

full_name: Lean.Meta.SynthInstance.consume
code: /-- Process the next subgoal in the given consumer node. -/
def consume (cNode : ConsumerNode) : SynthM Unit 
goal: Lean.Meta.SynthInstance.SynthM Unit

full_name: Lean.Meta.SynthInstance.getTop
code: def getTop : SynthM GeneratorNode 
goal: Lean.Meta.SynthInstance.SynthM Lean.Meta.SynthInstance.GeneratorNode

full_name: Lean.Meta.SynthInstance.modifyTop
code: @[inline] def modifyTop (f : GeneratorNode → GeneratorNode) : SynthM Unit 
goal: Lean.Meta.SynthInstance.SynthM Unit

full_name: Lean.Meta.SynthInstance.generate
code: /-- Try the next instance in the node on the top of the generator stack. -/
def generate : SynthM Unit 
goal: Lean.Meta.SynthInstance.SynthM Unit

full_name: Lean.Meta.SynthInstance.getNextToResume
code: def getNextToResume : SynthM (ConsumerNode × Answer) 
goal: Lean.Meta.SynthInstance.SynthM (Lean.Meta.SynthInstance.ConsumerNode × Lean.Meta.SynthInstance.Answer)

full_name: Lean.Meta.SynthInstance.resume
code: /--
  Given `(cNode, answer)` on the top of the resume stack, continue execution by using `answer` to solve the
  next subgoal. -/
def resume : SynthM Unit 
goal: Lean.Meta.SynthInstance.SynthM Unit

full_name: Lean.Meta.SynthInstance.step
code: def step : SynthM Bool 
goal: Lean.Meta.SynthInstance.SynthM Bool

full_name: Lean.Meta.SynthInstance.getResult
code: def getResult : SynthM (Option AbstractMVarsResult) 
goal: Lean.Meta.SynthInstance.SynthM (Option Lean.Meta.AbstractMVarsResult)

full_name: Lean.Meta.SynthInstance.synth
code: partial def synth : SynthM (Option AbstractMVarsResult) 
goal: Lean.Meta.SynthInstance.SynthM (Option Lean.Meta.AbstractMVarsResult)

full_name: Lean.Meta.SynthInstance.main
code: def main (type : Expr) (maxResultSize : Nat) : MetaM (Option AbstractMVarsResult) 
goal: Lean.MetaM (Option Lean.Meta.AbstractMVarsResult)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.SynthInstance.0.Lean.Meta.preprocess
code: private def preprocess (type : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.SynthInstance.0.Lean.Meta.preprocessArgs
code: private partial def preprocessArgs (type : Expr) (i : Nat) (args : Array Expr) (outParamsPos : Array Nat) : MetaM (Array Expr) 
goal: Lean.MetaM (Array Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.SynthInstance.0.Lean.Meta.preprocessOutParam
code: private def preprocessOutParam (type : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.SynthInstance.0.Lean.Meta.assignOutParams
code: private def assignOutParams (type : Expr) (result : Expr) : MetaM Bool 
goal: Lean.MetaM Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.SynthInstance.0.Lean.Meta.applyAbstractResult?
code: /--
Auxiliary function for converting the `AbstractMVarsResult` returned by `SynthIntance.main` into an `Expr`.
-/
private def applyAbstractResult? (type : Expr) (abstResult? : Option AbstractMVarsResult) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.SynthInstance.0.Lean.Meta.applyCachedAbstractResult?
code: /--
Auxiliary function for converting a cached `AbstractMVarsResult` returned by `SynthIntance.main` into an `Expr`.
This function tries to avoid the potentially expensive `check` at `applyCachedAbstractResult?`.
-/
private def applyCachedAbstractResult? (type : Expr) (abstResult? : Option AbstractMVarsResult) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.SynthInstance.0.Lean.Meta.cacheResult
code: /-- Helper function for caching synthesized type class instances. -/
private def cacheResult (cacheKey : SynthInstanceCacheKey) (abstResult? : Option AbstractMVarsResult) (result? : Option Expr) : MetaM Unit 
goal: Lean.MetaM Unit

full_name: Lean.Meta.synthInstance?
code: def synthInstance? (type : Expr) (maxResultSize? : Option Nat := none) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.trySynthInstance
code: /--
  Return `LOption.some r` if succeeded, `LOption.none` if it failed, and `LOption.undef` if
  instance cannot be synthesized right now because `type` contains metavariables. -/
def trySynthInstance (type : Expr) (maxResultSize? : Option Nat := none) : MetaM (LOption Expr) 
goal: Lean.MetaM (Lean.LOption Lean.Expr)

full_name: Lean.Meta.throwFailedToSynthesize
code: def throwFailedToSynthesize (type : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.synthInstance
code: def synthInstance (type : Expr) (maxResultSize? : Option Nat := none) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.SynthInstance.0.Lean.Meta.synthPendingImp
code: @[export lean_synth_pending]
private def synthPendingImp (mvarId : MVarId) : MetaM Bool 
goal: Lean.MetaM Bool

full_name: Lean.Meta.initFn._@..lake.packages.lean4.src.lean.Lean.Meta.SynthInstance._hyg.9951
code: builtin_initialize
  registerTraceClass `Meta.synthPending
  registerTraceClass `Meta.synthInstance
  registerTraceClass `Meta.synthInstance.instances (inherited := true)
  registerTraceClass `Meta.synthInstance.tryResolve (inherited := true)
  registerTraceClass `Meta.synthInstance.answer (inherited := true)
  registerTraceClass `Meta.synthInstance.resume (inherited := true)
  registerTraceClass `Meta.synthInstance.unusedArgs
  registerTraceClass `Meta.synthInstance.newAnswer
goal: IO Unit