Zulip Chat Archive
Stream: lean4
Topic: Implicit arguments in getAppArgs
Moritz Doll (May 23 2023 at 21:36):
Given variable {a b : ℕ} and the term a = b if I elaborate this term with elabTerm and then apply Lean.Expr.getAppArgs' (same for unprimed and the second component of Lean.Expr.getAppFnArgs) it yields #[ℕ, a, b], but I would expect #[a, b]. Is there some way to get rid of implicit arguments?
Kyle Miller (May 23 2023 at 21:39):
Are you specifically wanting to process equalities? docs4#Lean.Expr.eq? lets you get the type, LHS, and RHS as a tuple
Moritz Doll (May 23 2023 at 21:43):
Unfortunately not. Background is that I resumed porting congrm and for matching the pattern I of course only want to deal with the explicit arguments
Kyle Miller (May 23 2023 at 21:44):
I think there's a function used by other congr meta code to get detailed information about every function argument.
Kyle Miller (May 23 2023 at 21:45):
here's a place it's used in mathlib code: https://github.com/leanprover-community/mathlib4/blob/master/Mathlib/Tactic/Congr!.lean#LL540C16-L540C31
Kyle Miller (May 23 2023 at 21:47):
You can filter the arguments by which ones have a paramInfo.binderInfo == .default
Moritz Doll (May 23 2023 at 22:06):
thanks, there is actually ParamInfo.isExplicit
Moritz Doll (May 23 2023 at 22:07):
which does the exact equality check
Moritz Doll (May 23 2023 at 22:32):
Ok, making progress, but still not quite there. In the function below I consistently get that the length of pinfo is zero:
def _root_.Lean.Expr.getExplicitArgs (f : Expr) : MetaM (Array Expr) := do
let args := f.getAppArgs
let pinfo := (← Lean.Meta.getFunInfoNArgs f args.toList.length).paramInfo
logInfo s!"all arguments: {← args.mapM ppExpr} and num patternInfos: {pinfo.toList.length}"
return (pinfo.zip args).filterMap (λ arg => if arg.1.isExplicit then some arg.2 else none)
Mario Carneiro (May 23 2023 at 22:35):
Moritz Doll (May 23 2023 at 22:42):
There you go:
import Lean.Meta.FunInfo
import Lean.Elab.Tactic
open Lean Parser Tactic Elab Tactic Meta
def _root_.Lean.Expr.getExplicitArgs (f : Expr) : MetaM (Array Expr) := do
let args := f.getAppArgs
let pinfo := (← Lean.Meta.getFunInfoNArgs f args.toList.length).paramInfo
logInfo s!"all arguments: {← args.mapM ppExpr} and patternInfos: {pinfo.toList.length}"
return (pinfo.zip args).filterMap (λ arg => if arg.1.isExplicit then some arg.2 else none)
syntax (name := prettyExpr) "prettyExpr " term : tactic
elab_rules : tactic | `(tactic| prettyExpr $expr:term) => withMainContext do
let _foo ← (← elabTerm expr none).getExplicitArgs
return
-- Testing for implicit arguments in function application
example (a b c : α) (h : b = c) : a = b ↔ a = c := by
prettyExpr (_ = _)
prettyExpr ((· = · ) _ _)
prettyExpr (@Eq _ _)
sorry
Mario Carneiro (May 23 2023 at 22:46):
looks like you need to pass the head of the function, that is f.getAppFn, to getFunInfoNArgs instead of f
Moritz Doll (May 23 2023 at 22:49):
yes that works, thanks. What is the reason for (_ = _) having three arguments, but ((· = · ) _ _) having two?
Mario Carneiro (May 23 2023 at 22:51):
the first one is @Eq _ _ _ and the second one is (fun x y => @Eq _ x y) _ _
Kyle Miller (May 23 2023 at 23:33):
Rather than args.toList.length you can do args.size. And just in case you ever need it (if you don't also need the array of arguments), there's Lean.Expr.getAppNumArgs.
Moritz Doll (May 24 2023 at 00:03):
I knew about getAppNumArgs, but not Array.size, thanks
Last updated: May 02 2025 at 03:31 UTC