Zulip Chat Archive
Stream: lean4
Topic: get explicit args
Patrick Massot (Feb 04 2023 at 16:38):
Is there a version of docs4#Lean.Expr.getAppArgs that returns only explicit arguments? I understand the def of getAppargs but I don't know how to access this info. Working in MetaM is ok.
Arthur Paulino (Feb 04 2023 at 16:49):
Hm, do you mean to get explicit arguments from a telescoped lambda? Applications don't have the implicit/explicit dichotomy
Patrick Massot (Feb 04 2023 at 16:51):
I was indeed looking around the telescope stuff. I have a proof term that applies a lemma and I want to get the exprs corresponding to explicit arguments of the lemma.
Arthur Paulino (Feb 04 2023 at 16:55):
I'm not on my PC right now and I don't remember if the lambda telescope retrieves the binder info's. But that's something you can accumulate while traversing an expression
Patrick Massot (Feb 04 2023 at 16:55):
I guess I could get the type of the head app, try to get binder info there and then select the app arguments based on that but it feels very clunky.
Jannis Limperg (Feb 06 2023 at 13:44):
The telescope gives you FVarId
s and the LocalDecl
s corresponding to these FVarId
s have a BinderInfo
field. This should tell you whether the argument was explicit or implicit.
Arthur Paulino (Feb 06 2023 at 13:51):
I think Patrick doesn't need a monadic telescope. Is there a pure one? (pretty amazing how I've already forgotten the MetaM
API)
Jannis Limperg (Feb 06 2023 at 13:56):
The telescope functions are all monadic. I guess one could define a pure one for local variables which returns an explicit LocalContext
. But almost every higher-level function on Expr
s needs MetaM
anyway to interpret potential metavariables, so I don't think there's much of a point.
Patrick Massot (Feb 06 2023 at 16:06):
Thanks Jannis. My question wasn't limited to FVarId. What I ended up using was: first some non-monadic function collecting indices of explicit arguments in a forall telescope
private def explicitIndicesAux : (all : Expr) → (exArgs : Array Nat) → Nat → Array Nat
| forallE _ _ body BinderInfo.default, as, n => explicitIndicesAux body (as.push n) (n+1)
| forallE _ _ body _, as, n => explicitIndicesAux body as (n+1)
| _, as, _ => as
/-- Get the indices of explicit arguments of a forall telescope. -/
def explicitIndices (all : Expr) := explicitIndicesAux all #[] 0
and then when I see a app
telescope I infer its type using inferType
and instantiateMVars
(this is one of those pairs of functions that should always be called together if you want to use the result in any way...), use the above function and pick the arguments from docs4#Lean.Expr.getAppArgs that live at those indices. I feels super weird but I don't see another way to work around the fact that Expr.app
has no binder info.
Arthur Paulino (Feb 06 2023 at 16:37):
Expr.app
encodes stuff like f x (g y)
. How would it keep binder information when there's no binders?
Jannis Limperg (Feb 06 2023 at 17:10):
This general approach sounds fine to me; I would have done it similarly. I would, however, implement explicitIndices
in terms of forallBoundedTelescope
where the bound is the number of arguments n
in your application f x1 ... xn
. This ensures that explicitIndices
catches explicit arguments even when the type of f
is, for example, a definition T := forall X1 ... Xn, U
, which your explicitIndices
would treat as having zero explicit arguments.
Patrick Massot (Feb 06 2023 at 18:23):
Jannis, if this is really quick for your, I'd be interested in seeing an implementation using forallBoundedTelescope
.
Jannis Limperg (Feb 06 2023 at 18:37):
Sure!
import Lean
open Lean Lean.Meta
/--
Given a type `e = ∀ (x₁ : X₁) ... (xₙ : Xₙ), U`, extract those `i` such that
`xᵢ` is an explicit argument.
-/
def explicitIndices (e : Expr) (n : Nat) : MetaM (Array Nat) :=
forallBoundedTelescope e n λ args _ => do
let mut indices := Array.mkEmpty n
for h : i in [:args.size] do
if (← (args[i]'h.2).fvarId!.getDecl).binderInfo == .default then
indices := indices.push i
return indices
def T := ∀ (x₁ : Nat) {x₂ : Nat} (x₃ : Nat) [x₄ : DecidableEq Nat] (x₅ : Nat), Nat
#eval explicitIndices (.const ``T []) 4
Patrick Massot (Feb 06 2023 at 18:46):
Thanks!
Last updated: Dec 20 2023 at 11:08 UTC