Metaprogram for Reifying Lean Expressions to LeanCert AST #
This module provides metaprogramming infrastructure to translate Lean kernel
expressions (e.g., fun (x : ℝ) => x + 2) into LeanCert.Core.Expr terms
(e.g., Expr.add (Expr.var 0) (Expr.const 2)).
Main definitions #
LeanCert.Meta.Context- Context tracking free variables and their de Bruijn indicesLeanCert.Meta.TranslateM- The translation monadLeanCert.Meta.toLeanCertExpr- Main recursive translation functionLeanCert.Meta.reifyWithReport- Entry point that handles lambda expressions
Usage #
#leancert_reflect (fun x => x * x + 1)
-- Output: Expr.add (Expr.mul (Expr.var 0) (Expr.var 0)) (Expr.const 1)
Context for the translation. Stores fvars of the lambda being traversed.
vars[0] corresponds to var 0, vars[1] to var 1, etc.
Array of free variables from the lambda telescope
Instances For
Mutable bookkeeping for one reification pass.
Definitions delta-reduced while exposing supported arithmetic.
- remainingUnfoldSteps : ℕ
Remaining delta-reduction steps. This prevents recursive wrappers from making reification diverge.
Instances For
The translation monad: a read-only variable context plus bounded
reification bookkeeping over MetaM.
Equations
Instances For
Look up a Free Variable in the context. Returns its de Bruijn index if found.
Equations
- LeanCert.Meta.findVarIdx? e = do let ctx ← read pure (Array.findIdx? (fun (x : Lean.Expr) => x == e) ctx.vars)
Instances For
Helper Functions: AST Constructors #
These functions build LeanCert.Core.Expr syntax trees. They construct Lean
expressions that represent LeanCert AST terms.
Build LeanCert.Core.Expr.const q for a rational number.
Equations
- LeanCert.Meta.mkExprConst q = do let ratExpr ← Lean.Meta.mkAppM `Rat.divInt #[Lean.toExpr q.num, Lean.toExpr ↑q.den] Lean.Meta.mkAppM `LeanCert.Core.Expr.const #[ratExpr]
Instances For
ToExpr instance for ℚ (rationals)
Equations
- LeanCert.Meta.instToExprRat_leanCert = { toExpr := fun (q : ℚ) => Lean.mkApp2 (Lean.mkConst `Rat.divInt) (Lean.toExpr q.num) (Lean.toExpr ↑q.den), toTypeExpr := Lean.mkConst `Rat }
Build LeanCert.Core.Expr.var idx for a variable index.
Equations
- LeanCert.Meta.mkExprVar idx = Lean.Meta.mkAppM `LeanCert.Core.Expr.var #[Lean.toExpr idx]
Instances For
Build LeanCert.Core.Expr.add e1 e2.
Equations
- LeanCert.Meta.mkExprAdd e1 e2 = Lean.Meta.mkAppM `LeanCert.Core.Expr.add #[e1, e2]
Instances For
Build LeanCert.Core.Expr.mul e1 e2.
Equations
- LeanCert.Meta.mkExprMul e1 e2 = Lean.Meta.mkAppM `LeanCert.Core.Expr.mul #[e1, e2]
Instances For
Build LeanCert.Core.Expr.neg e.
Equations
- LeanCert.Meta.mkExprNeg e = Lean.Meta.mkAppM `LeanCert.Core.Expr.neg #[e]
Instances For
Build subtraction through the named Expr.sub wrapper.
Expr.sub is definitionally implemented by addition and negation, so the
executable evaluator is unchanged. Preserving the wrapper until bridge
normalization lets Expr.eval_sub recover the user's lhs - rhs syntax and
is essential for general root goals lhs = rhs.
Equations
- LeanCert.Meta.mkExprSub e1 e2 = Lean.Meta.mkAppM `LeanCert.Core.Expr.sub #[e1, e2]
Instances For
Build LeanCert.Core.Expr.inv e.
Equations
- LeanCert.Meta.mkExprInv e = Lean.Meta.mkAppM `LeanCert.Core.Expr.inv #[e]
Instances For
Build LeanCert.Core.Expr.sin e.
Equations
- LeanCert.Meta.mkExprSin e = Lean.Meta.mkAppM `LeanCert.Core.Expr.sin #[e]
Instances For
Build LeanCert.Core.Expr.cos e.
Equations
- LeanCert.Meta.mkExprCos e = Lean.Meta.mkAppM `LeanCert.Core.Expr.cos #[e]
Instances For
Build LeanCert.Core.Expr.exp e.
Equations
- LeanCert.Meta.mkExprExp e = Lean.Meta.mkAppM `LeanCert.Core.Expr.exp #[e]
Instances For
Build LeanCert.Core.Expr.log e.
Equations
- LeanCert.Meta.mkExprLog e = Lean.Meta.mkAppM `LeanCert.Core.Expr.log #[e]
Instances For
Build LeanCert.Core.Expr.atan e.
Equations
- LeanCert.Meta.mkExprAtan e = Lean.Meta.mkAppM `LeanCert.Core.Expr.atan #[e]
Instances For
Build LeanCert.Core.Expr.arsinh e.
Equations
- LeanCert.Meta.mkExprArsinh e = Lean.Meta.mkAppM `LeanCert.Core.Expr.arsinh #[e]
Instances For
Build LeanCert.Core.Expr.atanh e.
Equations
- LeanCert.Meta.mkExprAtanh e = Lean.Meta.mkAppM `LeanCert.Core.Expr.atanh #[e]
Instances For
Build LeanCert.Core.Expr.sinc e.
Equations
- LeanCert.Meta.mkExprSinc e = Lean.Meta.mkAppM `LeanCert.Core.Expr.sinc #[e]
Instances For
Build LeanCert.Core.Expr.erf e.
Equations
- LeanCert.Meta.mkExprErf e = Lean.Meta.mkAppM `LeanCert.Core.Expr.erf #[e]
Instances For
Build LeanCert.Core.Expr.sqrt e.
Equations
- LeanCert.Meta.mkExprSqrt e = Lean.Meta.mkAppM `LeanCert.Core.Expr.sqrt #[e]
Instances For
Build absolute value as sqrt (e * e).
Equations
- LeanCert.Meta.mkExprAbs e = do let __do_lift ← LeanCert.Meta.mkExprMul e e LeanCert.Meta.mkExprSqrt __do_lift
Instances For
Build LeanCert.Core.Expr.sinh e.
Equations
- LeanCert.Meta.mkExprSinh e = Lean.Meta.mkAppM `LeanCert.Core.Expr.sinh #[e]
Instances For
Build LeanCert.Core.Expr.cosh e.
Equations
- LeanCert.Meta.mkExprCosh e = Lean.Meta.mkAppM `LeanCert.Core.Expr.cosh #[e]
Instances For
Build LeanCert.Core.Expr.tanh e.
Equations
- LeanCert.Meta.mkExprTanh e = Lean.Meta.mkAppM `LeanCert.Core.Expr.tanh #[e]
Instances For
Build LeanCert.Core.Expr.namedConst c.
Equations
- LeanCert.Meta.mkExprNamedConst c = Lean.Meta.mkAppM `LeanCert.Core.Expr.namedConst #[c]
Instances For
Build LeanCert.Core.Expr.namedConst .pi.
Equations
- LeanCert.Meta.mkExprPi = LeanCert.Meta.mkExprNamedConst (Lean.mkConst `LeanCert.Core.MathConst.pi)
Instances For
Build LeanCert.Core.Expr.namedConst .eulerMascheroni.
Equations
- LeanCert.Meta.mkExprEulerMascheroni = LeanCert.Meta.mkExprNamedConst (Lean.mkConst `LeanCert.Core.MathConst.eulerMascheroni)
Instances For
Build max(a,b) via (a + b + |b - a|) / 2 in existing Expr constructors.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Build min(a,b) via (a + b - |b - a|) / 2 in existing Expr constructors.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Constant Extraction #
Numeric parsing is shared in LeanCert.Meta.Numeral.toRat?.
Main Reification Loop #
The recursive function that traverses the Lean expression tree and builds the corresponding LeanCert AST.
Main recursive translation from Lean.Expr to LeanCert.Core.Expr (as Lean.Expr).
Logic:
- Check if it's a variable in our context
- Try to match a known operator/function (+, *, -, /, sin, cos, exp, etc.)
- Check if it's a numeric constant (ℕ, ℤ, ℚ literals and casts)
- Reduce with whnf and retry
- Unfold definitions and retry
Important: Step 2 (operator matching) must come before step 3 (numeric constant).
Otherwise toRat? eagerly constant-folds compound expressions like ↑(-2 : ℤ) + 3
into const(1), losing the syntactic structure needed by the bridge converter.
With operators first, this reifies as add(const(-2), const(3)) which the bridge
can match against the goal.
Try to match the expression against known patterns.
Unary head-symbol handlers.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Binary head-symbol handlers.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Table for unary operations.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Table for binary operations with direct AST constructors.
Equations
- LeanCert.Meta.toLeanCertExpr.binaryTable = [(`HAdd.hAdd, LeanCert.Meta.mkExprAdd), (`HMul.hMul, LeanCert.Meta.mkExprMul)]
Instances For
Last two arguments of an application (if present).
Equations
Instances For
Rich unsupported-expression diagnostics (head symbol + arity).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Build a power expression using repeated multiplication. pow(base, k) = base * base * ... * base (k times) or 1 if k = 0.
Build base ^ z for integer z using Expr.pow + Expr.inv.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Build base ^ (n/2) for integer numerator n (half-integers).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Try to decompose e as max a b using definitional equality.
This is robust against internal projection names changing across
Mathlib versions.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Try to decompose e as min a b using definitional equality.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Entry Point #
The main entry point that strips the leading lambda and initializes the context.
Entry point: Takes a lambda fun x y ... => body and returns the LeanCert AST.
This function uses lambdaTelescope to introduce the lambda-bound variables
as free variables, then translates the body with those variables tracked in
the context.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Testing Infrastructure #
Elaborate a term and reify it to a LeanCert expression. Useful for debugging the reification process.
Equations
- One or more equations did not get rendered due to their size.