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

full_name: Lean.Meta.ArgsPacker.Unary.packType
code: def packType (xs : Array Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.Unary.pack.go
code: /--
Create a unary application by packing the given arguments using `PSigma.mk`.
The `type` should be the the expected type of the packed argument, as created with `packType`.
-/
partial def pack (type : Expr) (args : Array Expr) : Expr 
goal: Lean.Expr

full_name: Lean.Meta.ArgsPacker.Unary.pack
code: /--
Create a unary application by packing the given arguments using `PSigma.mk`.
The `type` should be the the expected type of the packed argument, as created with `packType`.
-/
partial def pack (type : Expr) (args : Array Expr) : Expr 
goal: Lean.Expr

full_name: Lean.Meta.ArgsPacker.Unary.unpack
code: /--
Unpacks a unary packed argument created with `Unary.pack`.

Throws an error if the expression is not of that form.
-/
def unpack (arity : Nat) (e : Expr) : MetaM (Array Expr) 
goal: Lean.MetaM (Array Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.ArgsPacker.0.Lean.Meta.ArgsPacker.Unary.mkTupleElems
code: /--
  Given a (dependent) tuple `t` (using `PSigma`) of the given arity.
  Return an array containing its "elements".
  Example: `mkTupleElems a 4` returns `#[a.1, a.2.1, a.2.2.1, a.2.2.2]`.
  -/
private def mkTupleElems (t : Expr) (arity : Nat) : Array Expr 
goal: Array Lean.Expr

full_name: Lean.Meta.ArgsPacker.Unary.uncurryType
code: /--
Given a type `t` of the form `(x : A) → (y : B[x]) → … → (z : D[x,y]) → R[x,y,z]`
returns the curried type `(x : A ⊗' B ⊗' … ⊗' D) → R[x.1, x.2.1, x.2.2]`.
-/
def uncurryType (varNames : Array Name) (type : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.ArgsPacker.0.Lean.Meta.ArgsPacker.Unary.casesOn
code: /--
Iterated `PSigma.casesOn`:
Given `e : a ⊗' b ⊗' …` (where `e` is `FVarId`), a type `codomain[e]` of level `u`, and
`alt : (x : a) → (y : b) → … → codomain`, uses `PSigma.casesOn` to invoke `alt` on `e`.
-/
private def casesOn (varNames : List Name) (e : Expr) (u : Level) (codomain : Expr) (alt : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.Unary.uncurry
code: /--
Given expression `e` of type `(x : A) → (y : B[x]) → … → (z : D[x,y]) → R[x,y,z]`
returns an expression of type `(x : A ⊗' B ⊗' … ⊗' D) → R[x.1, x.2.1, x.2.2]`.
-/
def uncurry (varNames : Array Name) (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.ArgsPacker.0.Lean.Meta.ArgsPacker.Unary.curryType.go
code: /-- Given `(A ⊗' B ⊗' … ⊗' D) → R` (non-dependent) `R`, return `A → B → … → D → R` -/
private def curryType (varNames : Array Name) (type : Expr) :
    MetaM Expr 
goal: List Lean.Name → Lean.Expr → Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.ArgsPacker.0.Lean.Meta.ArgsPacker.Unary.curryType
code: /-- Given `(A ⊗' B ⊗' … ⊗' D) → R` (non-dependent) `R`, return `A → B → … → D → R` -/
private def curryType (varNames : Array Name) (type : Expr) :
    MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.ArgsPacker.0.Lean.Meta.ArgsPacker.Unary.curry
code: /--
Given expression `e` of type `(x : A ⊗' B ⊗' … ⊗' D) → R[x]`
return expression of type `(x : A) → (y : B) → … → (z : D) → R[(x,y,z)]`
-/
private partial def curry (varNames : Array Name) (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.ArgsPacker.0.Lean.Meta.ArgsPacker.Unary.curry.go
code: /--
Given expression `e` of type `(x : A ⊗' B ⊗' … ⊗' D) → R[x]`
return expression of type `(x : A) → (y : B) → … → (z : D) → R[(x,y,z)]`
-/
private partial def curry (varNames : Array Name) (e : Expr) : MetaM Expr 
goal: List Lean.Name → Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.Mutual.packType
code: /-- Given types `#[t₁, t₂,…]`, returns the type `t₁ ⊕' t₂ …`. -/
def packType (ds : Array Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.ArgsPacker.0.Lean.Meta.ArgsPacker.Mutual.unpackType
code: /-- Given type `A ⊕' B ⊕' … ⊕' D`, return `[A, B, …, D]` -/
private def unpackType (n : Nat) (type : Expr) : MetaM (List Expr) 
goal: Lean.MetaM (List Lean.Expr)

full_name: Lean.Meta.ArgsPacker.Mutual.pack.go
code: /--
If `arg` is the argument to the `fidx`th of the `argsPacker.numFuncs` in the recursive group,
then `mk` packs that argument in `PSum.inl` and `PSum.inr` constructors
to create the mutual-packed argument of type `domain`.
-/
def pack (numFuncs : Nat) (domain : Expr) (fidx : Nat) (arg : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.Mutual.pack
code: /--
If `arg` is the argument to the `fidx`th of the `argsPacker.numFuncs` in the recursive group,
then `mk` packs that argument in `PSum.inl` and `PSum.inr` constructors
to create the mutual-packed argument of type `domain`.
-/
def pack (numFuncs : Nat) (domain : Expr) (fidx : Nat) (arg : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.Mutual.unpack
code: /--
Unpacks a mutually packed argument created with `Mutual.mk` returning the
argument and function index.

Throws an error if the expression is not of that form.
-/
def unpack (numFuncs : Nat) (expr : Expr) : MetaM (Nat × Expr) 
goal: Lean.MetaM (Nat × Lean.Expr)

full_name: Lean.Meta.ArgsPacker.Mutual.mkCodomain
code: /--
Given unary types `(x : Aᵢ) → Rᵢ[x]`, and `(x : A₁ ⊕ A₂ …)`, calculate the packed codomain
```
match x with | inl x₁ => R₁[x₁] | inr x₂ => R₂[x₂] | …
```
This function assumes (and does not check) that `Rᵢ` all have the same level.
-/
def mkCodomain (types : Array Expr) (x : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.Mutual.mkCodomain.go
code: /--
Given unary types `(x : Aᵢ) → Rᵢ[x]`, and `(x : A₁ ⊕ A₂ …)`, calculate the packed codomain
```
match x with | inl x₁ => R₁[x₁] | inr x₂ => R₂[x₂] | …
```
This function assumes (and does not check) that `Rᵢ` all have the same level.
-/
def mkCodomain (types : Array Expr) (x : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.Mutual.uncurryType
code: def uncurryType (types : Array Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.Mutual.uncurryTypeND
code: def uncurryTypeND (types : Array Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.ArgsPacker.0.Lean.Meta.ArgsPacker.Mutual.casesOn
code: private def casesOn (x : Expr) (codomain : Expr) (alts : List Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.Mutual.uncurry
code: /--
Given unary expressions `e₁`, `e₂` with types `(x : A) → R₁[x]`
and `(z : C) → R₂[z]`, returns an expression of type
```
(x : A ⊕' C) → (match x with | .inl x => R₁[x] | .inr R₂[z])
```
-/
def uncurry (es : Array Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.Mutual.uncurryND
code: /--
Given unary expressions `e₁`, `e₂` with types `(x : A) → R`
and `(z : C) → R`, returns an expression of type
```
(x : A ⊕' C) → R
```
-/
def uncurryND (es : Array Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.Mutual.curryType
code: def curryType (n : Nat) (type : Expr) : MetaM (Array Expr) 
goal: Lean.MetaM (Array Lean.Expr)

full_name: Lean.Meta.ArgsPacker.numFuncs
code: /-- The number of functions being packed -/
def numFuncs (argsPacker : ArgsPacker) : Nat 
goal: Nat

full_name: Lean.Meta.ArgsPacker.arities
code: /-- The arities of the functions being packed -/
def arities (argsPacker : ArgsPacker) : Array Nat 
goal: Array Nat

full_name: Lean.Meta.ArgsPacker.pack
code: def pack (argsPacker : ArgsPacker) (domain : Expr) (fidx : Nat) (args : Array Expr)
    : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.unpack
code: /--
Given the packed argument of a (possibly) mutual and (possibly) nary call,
return the function index that is called and the arguments individually.

We expect precisely the expressions produced by `pack`, with manifest
`PSum.inr`, `PSum.inl` and `PSigma.mk` constructors, and thus take them apart
rather than using projectinos.
-/
def unpack (argsPacker : ArgsPacker) (e : Expr) : MetaM (Nat × Array Expr) 
goal: Lean.MetaM (Nat × Array Lean.Expr)

full_name: Lean.Meta.ArgsPacker.uncurryType
code: /--
Given types `(x : A) → (y : B[x]) → R₁[x,y]` and `(z : C) → R₂[z]`, returns the type uncurried type
```
(x : (A ⊗ B) ⊕ C) → (match x with | .inl (x, y) => R₁[x,y] | .inr R₂[z]
```
-/
def uncurryType (argsPacker : ArgsPacker) (types : Array Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.uncurry
code: /--
Given expressions `e₁`, `e₂` with types `(x : A) → (y : B[x]) → R₁[x,y]`
and `(z : C) → R₂[z]`, returns an expression of type
```
(x : (A ⊗ B) ⊕ C) → (match x with | .inl (x, y) => R₁[x,y] | .inr R₂[z]
```
-/
def uncurry (argsPacker : ArgsPacker) (es : Array Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.uncurryND
code: /--
Given expressions `e₁`, `e₂` with types `(x : A) → (y : B[x]) → R`
and `(z : C) → R`, returns an expression of type
```
(x : (A ⊗ B) ⊕ C) → R
```
-/
def uncurryND (argsPacker : ArgsPacker) (es : Array Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.curryProj
code: /--
Given expression `e` of type `(x : a₁ ⊗' b₁ ⊕' a₂ ⊗' d₂ …) → e[x]`, uncurries the expression and
projects to the `i`th function of type,
```
((x : aᵢ) → (y : bᵢ) → e[.inr….inl (x,y)])
```
-/
def curryProj (argsPacker : ArgsPacker) (e : Expr) (i : Nat) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.ArgsPacker.curryType
code: /--
Given type `(x : a ⊗' b ⊕' c ⊗' d) → R` (non-dependent), return types
```
#[(x: a) → (y : b) → R, (x : c) → (y : d) → R]
```
-/
def curryType (argsPacker : ArgsPacker) (t : Expr) : MetaM (Array Expr) 
goal: Lean.MetaM (Array Lean.Expr)

full_name: Lean.Meta.ArgsPacker.curry
code: /--
Given expression `e` of type `(x : a ⊗' b ⊕' c ⊗' d) → e[x]`, wraps that expression
to produce an expression of the isomorphic type
```
((x: a) → (y : b) → e[.inl (x,y)]) ∧ ((x : c) → (y : d) → e[.inr (x,y)])
```
-/
def curry (argsPacker : ArgsPacker) (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.ArgsPacker.0.Lean.Meta.ArgsPacker.withCurriedDecl
code: /--
Given type `(a ⊗' b ⊕' c ⊗' d) → e`, brings `a → b → e` and `c → d → e`
into scope as fresh local declarations and passes their FVars to the continuation `k`.
The `name` is used to form the variable names; uses `name1`, `name2`, … if there are multiple.
-/
private def withCurriedDecl {α} (argsPacker : ArgsPacker) (name : Name) (type : Expr)
    (k : Array Expr → MetaM α) : MetaM α 
goal: Lean.MetaM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.ArgsPacker.0.Lean.Meta.ArgsPacker.withCurriedDecl.go
code: /--
Given type `(a ⊗' b ⊕' c ⊗' d) → e`, brings `a → b → e` and `c → d → e`
into scope as fresh local declarations and passes their FVars to the continuation `k`.
The `name` is used to form the variable names; uses `name1`, `name2`, … if there are multiple.
-/
private def withCurriedDecl {α} (argsPacker : ArgsPacker) (name : Name) (type : Expr)
    (k : Array Expr → MetaM α) : MetaM α 
goal: List Lean.Expr → Array Lean.Expr → Lean.MetaM α

full_name: Lean.Meta.ArgsPacker.curryParam
code: /--
Given `value : type` where `type` is
```
(m : a ⊗' b ⊕' c ⊗' d → s) → r[m]
```
brings `m1 : a → b → s` and `m2 : c → d → s` into scope. The continuation receives

 * FVars for `m1`…
 * `e[m]`
 * `t[m]`

where `m : a ⊗' b ⊕' c ⊗' d → s` is the uncurried form of `m1` and `m2`.

The variable names `m1` and `m2` are taken from the paramter name in `t`, with numbers added
unless `numFuns = 1`
-/
def curryParam {α} (argsPacker : ArgsPacker) (value : Expr) (type : Expr)
    (k : Array Expr → Expr → Expr → MetaM α) : MetaM α 
goal: Lean.MetaM α