Documentation

Lean.Elab.MutualDef

Equations
    Instances For

      DefView plus header elaboration data and snapshot.

      Instances For
        @[reducible, inline]

        A mapping from FVarId to Set of FVarIds.

        Equations
          Instances For

            The let-recs may invoke each other. Example:

            let rec
              f (x : Nat) := g x + y
              g : NatNat
                | 0   => 1
                | x+1 => f x + z
            

            y is free variable in f, and z is a free variable in g. To close f and g, y and z must be in the closure of both. That is, we need to generate the top-level definitions.

            def f (y z x : Nat) := g y z x + y
            def g (y z : Nat) : NatNat
              | 0 => 1
              | x+1 => f y z x + z
            
            Instances For
              @[reducible, inline]
              Equations
                Instances For
                  Equations
                    Instances For
                      @[reducible, inline]
                      Equations
                        Instances For
                          Instances For
                            Instances For
                              @[reducible, inline]

                              Mapping from FVarId of mutually recursive functions being defined to "closure" expression.

                              Equations
                                Instances For
                                  Equations
                                    Instances For
                                      Equations
                                        Instances For
                                          Equations
                                            Instances For
                                              def Lean.Elab.Term.MutualClosure.main (sectionVars : Array Expr) (mainHeaders : Array DefViewElabHeader) (mainFVars mainVals : Array Expr) (letRecsToLift : List LetRecToLift) :
                                              • sectionVars: The section variables used in the mutual block.
                                              • mainHeaders: The elaborated header of the top-level definitions being defined by the mutual block.
                                              • mainFVars: The auxiliary variables used to represent the top-level definitions being defined by the mutual block.
                                              • mainVals: The elaborated value for the top-level definitions
                                              • letRecsToLift: The let-rec's definitions that need to be lifted
                                              Equations
                                                Instances For
                                                  Equations
                                                    Instances For
                                                      Equations
                                                        Instances For
                                                          Equations
                                                            Instances For
                                                              Equations
                                                                Instances For

                                                                  Note [Delayed-Assigned Metavariables in Free Variable Collection] #

                                                                  Nested declarations using let rec should compile correctly even when nested within expressions that are elaborated using delayed metavariable assignments, such as match expressions and tactic blocks. Previously, declaring a let rec within such an expression in the following fashion

                                                                  def f x :=
                                                                    let rec g :=
                                                                      match ... with
                                                                      | pat =>
                                                                        let rec h := ... g ...
                                                                        ... x ...
                                                                  

                                                                  where g depends on some free variable bound by f (like x above) would cause MutualClosure to fail to detect that transitive fvar dependency of h (which must pass it as an argument to g), leading to an unbound fvar in the body of h that was ultimately fed to the kernel. This occurred because MutualClosure processes let-recs from most to least nested. Initially, the body of g is an application of the delayed-assigned metavariable generated by match elaboration; the root metavariable of that delayed assignment is, in turn, assigned to an expression that refers to the mvar that will eventually be assigned to g once we process that declaration. Therefore, when we initially process the most-nested declaration h (before g), we cannot instantiate the match-expression mvar's delayed assignment (since the metavariable that will eventually be assigned to the yet-unprocessed g remains unassigned). Thus, we do not detect any of the fvar dependencies of g in the match body -- namely, that corresponding to x, which h should therefore also take as a parameter. This also caused a knock-on effect in certain situations, wherein h would compile as an axiom rather than as opaque, rendering f erroneously noncomputable.