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.reify- 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
The translation monad: ReaderT over MetaM with our Context.
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 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 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.pi.
Equations
- LeanCert.Meta.mkExprPi = Lean.Meta.mkAppM `LeanCert.Core.Expr.pi #[]
Instances For
Constant Extraction #
Lean stores numbers as complex hierarchies of type classes (OfNat.ofNat,
Rat.cast, etc.). We need a pattern matcher that digs out the actual number.
Attempt to parse a Lean Expr as a constant rational number. Handles various encodings: Nat literals, Int literals, OfNat, Neg, etc.
Try to match a numeric expression.
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
- Check if it's a constant number
- Check if it's a known arithmetic operator (+, *, -, /)
- Check if it's a known transcendental (sin, cos, exp, log, etc.)
- Fail if unrecognized
Try to match the expression against known patterns.
Build a power expression using repeated multiplication. pow(base, k) = base * base * ... * base (k times) or 1 if k = 0.
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
- LeanCert.Meta.reify e = Lean.Meta.lambdaTelescope e fun (vars : Array Lean.Expr) (body : Lean.Expr) => have ctx := { vars := vars }; ReaderT.run (LeanCert.Meta.toLeanCertExpr body) ctx
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.