import Mathlib.MeasureTheory.Order.Lattice import Mathlib.Probability.Kernel.Composition.Prod import Mathlib.Probability.Kernel.Composition.CompProd import Mathlib.MeasureTheory.MeasurableSpace.Embedding import Lean.Elab.Tactic.Location import Lean.Meta.DecLevel import Lean.Meta.Transform import Lean.Util.Recognizers import Lean.Meta.Tactic.Replace import Lean.Meta.Tactic.Rewrite import Mathlib.Probability.Kernel.Deterministic /-! # Standalone extraction for `finisherKernelUnlift` Definitions are copied verbatim; theorem proofs are replaced by `sorry`. Auto-generated by Referee. -/ set_option quotPrecheck false -- Namespace stubs (so later `open`s resolve). namespace Finset end Finset namespace Lean end Lean namespace Lean.Meta end Lean.Meta namespace ProbabilityTheory end ProbabilityTheory namespace ProbabilityTheory.Kernel end ProbabilityTheory.Kernel -- ═══ ForMathlib.MeasureTheory.Order.Lattice ═══ section open Finset variable {α δ : Type*} [MeasurableSpace δ] [SemilatticeInf α] {m : MeasurableSpace α} [MeasurableInf₂ α] attribute [to_dual existing] MeasurableInf₂ end -- ═══ Tactic.EqLift.Tactic.Kernel.Utils ═══ section public meta section open Lean Meta ProbabilityTheory Elab Term /-- Extract `(X, Y, u, v)` from an expression of type `Kernel X Y`. -/ def getTypesFromKernel (κ : Expr) : MetaM (Expr × Expr × Level × Level) := do let κType ← inferType κ match κType.getAppFn with | Expr.const ``Kernel univs => let args := κType.getAppArgs if args.size < 2 then throwError "Kernel type with insufficient arguments: {κType}." let X := args[0]! let Y := args[1]! let xLevel := univs[0]! let yLevel := univs[1]! return (X, Y, xLevel, yLevel) | _ => throwError "Expected a kernel type, got: {κType}." /-- Build a measurable equivalence for `e` into universe `maxLvl` (recursive on products). -/ partial def constructMeasurableEquiv (e : Expr) (eLevel maxLvl : Level) : MetaM Expr := do let ewhnf ← whnf e match ewhnf.getAppFn with | Expr.const ``PUnit _ | Expr.const ``Unit _ => mkAppOptM' (Expr.const `MeasurableEquiv.punit [maxLvl, eLevel]) #[] | Expr.const ``Prod univs => let args := ewhnf.getAppArgs let X := args[0]! let Y := args[1]! let xLevel := univs[0]! let yLevel := univs[1]! let ex ← constructMeasurableEquiv X xLevel maxLvl let ey ← constructMeasurableEquiv Y yLevel maxLvl let res ← mkAppOptM' (Expr.const ``MeasurableEquiv.prodCongr [maxLvl, xLevel, maxLvl, yLevel]) #[none, none, none, none, none, none, none, none, ex, ey] return res | _ => mkAppOptM' (Expr.const ``MeasurableEquiv.ulift [eLevel, maxLvl]) #[e, none] end end -- ═══ Tactic.EqLift.Tactic.Kernel.KernelUnlift ═══ section public meta section open Lean Meta Parser.Tactic ProbabilityTheory ProbabilityTheory.Kernel /-- Constructs the finisher proof that concludes the unlifting after rewriting the equalities. -/ def finisherKernelUnlift (_ _ lhs rhs : Expr) (maxLvl : Level) : MetaM Expr := do let (X, Y, xLvl, yLvl) ← getTypesFromKernel lhs let ex ← constructMeasurableEquiv X xLvl maxLvl let ey ← constructMeasurableEquiv Y yLvl maxLvl let lift_congr_expr ← mkAppM ``lift_congr #[ex, ey, lhs, rhs] mkAppM ``Iff.symm #[lift_congr_expr] end end