Documentation

Lean.Elab.MutualInductive

Elaborator framework for (mutual) inductives #

This module defines the framework for elaborating (mutually recursive) inductive types. Commands such as inductive and structure plug into this framework, and the framework orchestrates their mutual elaboration.

The main entry point for new inductive commands are the @[builtin_inductive_elab]/@[inductive_elab] attributes, which register a handler for a given decl syntax.

The main entry point to elaboration are the functions

For mutual ... end in particular:

See the docstring on Lean.Elab.Command.InductiveElabDescr for an overview of the framework.

View of a constructor. Only ref, modifiers, declName, and declId are required by the mutual inductive elaborator itself.

  • ref : Syntax

    Syntax for the whole constructor.

  • modifiers : Modifiers
  • declName : Name

    Fully qualified name of the constructor.

  • declId : Syntax

    Syntax for the name of the constructor, used to apply terminfo. If the source is synthetic, terminfo is not applied.

  • binders : Syntax

    For handler use. The inductive uses it for the binders to the constructor.

  • type? : Option Syntax

    For handler use. The inductive command uses it for the resulting type for the constructor.

Instances For
    Equations
    Instances For
      Instances For

        A view for generic inductive types.

        Instances For
          Equations
          • One or more equations did not get rendered due to their size.
          Instances For

            Elaborated header for an inductive type before fvars for each inductive are added to the local context.

            Instances For

              The elaborated header with the indFVar registered for this inductive type.

              Instances For

                An intermediate step for mutual inductive elaboration. See InductiveElabDescr

                • finalize : TermElabM Unit

                  Finalize the inductive type, after they are all added to the environment, after auxiliary definitions are added, and after computed fields are registered. The levelParams, params, and replaceIndFVars arguments of prefinalize are still valid here.

                Instances For

                  An intermediate step for mutual inductive elaboration. See InductiveElabDescr.

                  Instances For
                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For

                      An intermediate step for mutual inductive elaboration. See InductiveElabDescr.

                      Instances For

                        Descriptor for a command processor that elaborates an inductive type.

                        Elaboration occurs in the following steps:

                        • Every command has its mkInductiveView evaluated, producing InductiveViews and callbacks for the next steps (all recorded in InductiveElabStep1).
                        • Each InductiveView gets elaborated, creating ElabHeaderResults, and the local contexts are unified into a single one with a consistent set of parameters between each inductive.
                        • Each callback is called to elaborate each inductives' constructors and some additional callbacks (all recorded in InductiveElabStep2).
                        • Fvars are collected from the constructors and from the InductiveStep2.collectUsedFVars callbacks. This is used to compute the final set of scoped variables that should be used as additional parameters.
                        • Universe levels are checked. Commands can give custom errors using InductiveStep2.checkUniverses.
                        • Elaboration of constructors is finalized, with additional tasks done by each InductiveStep2.finalizeTermElab.
                        • The inductive family is added to the environment and is checked by the kernel.
                        • Attributes and other finalization activities are performed, including those defined by InductiveStep2.prefinalize and InductiveStep3.finalize.
                        Instances For

                          Registers an inductive type elaborator for the given syntax node kind.

                          Commands registered using this attribute are allowed to be used together in mutual blocks with other inductive type commands. This attribute is mostly used internally for inductive and structure.

                          An inductive type elaborator should have type Lean.Elab.Command.InductiveElabDescr.

                          Returns true if the syntax participates in the mutual inductive elaborator. These do not need to be commands. In fact inductive and structure are registered on the Lean.Parser.Command.inductive and Lean.Parser.Command.structure syntaxes.

                          Equations
                          Instances For

                            Initializes the elaborator associated to the given syntax.

                            Equations
                            • One or more equations did not get rendered due to their size.
                            Instances For
                              Equations
                              • One or more equations did not get rendered due to their size.
                              Instances For
                                Equations
                                • One or more equations did not get rendered due to their size.
                                Instances For
                                  def Lean.Elab.Command.withCtorRef {m : TypeType} {α : Type} [Monad m] [MonadRef m] (views : Array InductiveView) (ctorName : Name) (k : m α) :
                                  m α

                                  Executes k using the Syntax reference associated with constructor ctorName.

                                  Equations
                                  • One or more equations did not get rendered due to their size.
                                  Instances For
                                    def Lean.Elab.Command.InductiveView.withTypeRef {m : TypeType} {α : Type} [Monad m] [MonadRef m] (view : InductiveView) (k : m α) :
                                    m α

                                    Runs k with the resulting type as the ref or, if that's not available, with the view's ref.

                                    Equations
                                    Instances For
                                      def Lean.Elab.Command.withViewTypeRef {m : TypeType} {α : Type} [Monad m] [MonadRef m] (views : Array InductiveView) (k : m α) :
                                      m α
                                      Equations
                                      • One or more equations did not get rendered due to their size.
                                      Instances For

                                        Execute k with updated binder information for xs. Any x that is explicit becomes implicit.

                                        Equations
                                        • One or more equations did not get rendered due to their size.
                                        Instances For

                                          Index-to-parameter promotion #

                                          The basic convention for inductive is that the binders before the colon in a type former correspond to the type parameters, and the pi types after the colon correspond to the indices.

                                          Indices that are fixed across all occurrences of the type former can potentially be promoted to be parameters instead. Motivations:

                                          Recall that when an inductive type declaration Declaration.inductDecl is sent to the kernel, every constructor is provided its full type, including the inductive parameters. The inductDecl declaration itself specifies how many parameters there are (nparams), and the first nparams parameters of a constructor are the parameters for the inductive type.

                                          The function fixedIndicesToParams determines by how much nparams can be increased without resulting in an invalid inductive type declaration. We say the indices that become parameters this way are promoted. Only a prefix of indices can be promoted because of this.

                                          Note that it currently does not do any constructor parameter reordering. If the parameter for an index does not appear in the correct position in a constructor for it to be an inductive type parameter, it is not promoted. That said, the inductive command itself has some capacity for reordering in Lean.Elab.Command.reorderCtorArgs.

                                          Promotion can be disabled with set_option inductive.autoPromoteIndices false.

                                          Level metavariable inference #

                                          Terminology: Given the inductive type former I : ... -> Sort u, we call Sort u the resulting universe of I and u the resulting universe level of I.

                                          After constructor elaboration, inductive type declarations still often have universe level metavariables. They may appear anywhere:

                                          The resulting universe has a strong bearing on what sort of inference we can do:

                                          There are certain cases where we choose to infer Prop for the resulting universe. Recall that an inductive type is a syntactic subsingleton if any two terms of that type are definitionally equal. Syntactic subsingletons can eliminate into Type, hence can be pattern matched. This justifies setting the resulting universe Prop if a type is "obviously" meant to be an inductive predicate. Roughly, we say an inductive type is "obviously" meant to be an inductive predicate if the type is not recursive, has exactly one constructor, the constructor has at least one field, and every field is Prop. See isPropCandidate for further explanation.

                                          From now on, we will talk only about inductive types in Type or above.

                                          There are a number of considerations for inference:

                                          Collecting the constraints, these rules imply the only assignments considered are:

                                          Otherwise we do not assign ?a, and we leave it to the "declaration has metavariables" error to report it.

                                          There are also other considerations to make the inference more effective. If the resulting universe is of the form max ?m 1, we want to isolate ?m as the metavariable to solve for. The simplifyResultingUniverse u procedure is a heavy hammer to reliably extract the "generic part" of the resulting universe level that is suitable for the inference procedures, without the fragility of matching on specific patterns. It gives a universe level u' ≤ u such that u' and u are equivalent "at infinity", which means u' = u for all sufficiently high assignments of the parameters or metavariables. In general, we only attempt solving for any universe levels at each stage if u' is of the form r + k where r is a parameter, metavariable, or zero, since in other cases solutions are not unique.

                                          High-level inference algorithm:

                                          Examples are in tests/lean/run/inductive_univ.lean.

                                          def Lean.Elab.Command.replaceIndFVars (numParams : Nat) (oldFVars calls : Array Expr) :
                                          Equations
                                          • One or more equations did not get rendered due to their size.
                                          Instances For
                                            Equations
                                            • One or more equations did not get rendered due to their size.
                                            Instances For
                                              Equations
                                              • One or more equations did not get rendered due to their size.
                                              Instances For
                                                Equations
                                                • One or more equations did not get rendered due to their size.
                                                Instances For

                                                  Returns true if all elements of the mutual block (Lean.Parser.Command.mutual) are inductive declarations.

                                                  Equations
                                                  Instances For

                                                    Elaborates a mutual block, assuming the commands satisfy Lean.Elab.Command.isMutualInductive.

                                                    Equations
                                                    • One or more equations did not get rendered due to their size.
                                                    Instances For