lean4-htt/tests/elab/addDecorationsWithoutPartial.lean
Garmelon 08eb78a5b2
chore: switch to new test/bench suite (#12590)
This PR sets up the new integrated test/bench suite. It then migrates
all benchmarks and some related tests to the new suite. There's also
some documentation and some linting.

For now, a lot of the old tests are left alone so this PR doesn't become
even larger than it already is. Eventually, all tests should be migrated
to the new suite though so there isn't a confusing mix of two systems.
2026-02-25 13:51:53 +00:00

82 lines
3.4 KiB
Text
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Lean
namespace Lean
namespace Expr
namespace ReplaceImpl'
abbrev cacheSize : USize := 8192
structure State where
keys : Array Expr -- Remark: our "unsafe" implementation relies on the fact that `()` is not a valid Expr
results : Array Expr
abbrev ReplaceM := StateM State
unsafe def cache (i : USize) (key : Expr) (result : Expr) : ReplaceM Expr := do
modify fun ⟨keys, results⟩ => { keys := keys.uset i key lcProof, results := results.uset i result lcProof };
pure result
unsafe def replaceUnsafeM (size : USize) (e : Expr) (f? : (e' : Expr) → sizeOf e' ≤ sizeOf e → Option Expr) : ReplaceM Expr := do
let rec visit (e : Expr) := do
let c ← get
let h := ptrAddrUnsafe e
let i := h % size
if ptrAddrUnsafe (c.keys.uget i lcProof) == h then
pure <| c.results.uget i lcProof
else match f? e lcProof with
| some eNew => cache i e eNew
| none => match e with
| Expr.forallE _ d b _ => cache i e <| e.updateForallE! (← visit d) (← visit b)
| Expr.lam _ d b _ => cache i e <| e.updateLambdaE! (← visit d) (← visit b)
| Expr.mdata _ b => cache i e <| e.updateMData! (← visit b)
| Expr.letE _ t v b _ => cache i e <| e.updateLetE! (← visit t) (← visit v) (← visit b)
| Expr.app f a => cache i e <| e.updateApp! (← visit f) (← visit a)
| Expr.proj _ _ b => cache i e <| e.updateProj! (← visit b)
| e => pure e
visit e
private def notAnExpr : Unit × Unit := ⟨⟨⟩, ⟨⟩⟩
unsafe def initCache : State :=
{ keys := Array.replicate cacheSize.toNat (cast lcProof notAnExpr), -- `notAnExpr` is not a valid `Expr`
results := Array.replicate cacheSize.toNat default }
unsafe def replaceUnsafe (e : Expr) (f? : (e' : Expr) → sizeOf e' ≤ sizeOf e → Option Expr) : Expr :=
(replaceUnsafeM cacheSize e f?).run' initCache
end ReplaceImpl'
local macro "dec " h:ident : term => `(by apply Nat.le_trans _ $h; simp +arith)
@[implemented_by ReplaceImpl'.replaceUnsafe]
def replace' (e0 : Expr) (f? : (e : Expr) → sizeOf e ≤ sizeOf e0 → Option Expr) : Expr :=
let rec go (e : Expr) (h : sizeOf e ≤ sizeOf e0) : Expr :=
match f? e h with
| some eNew => eNew
| none => match e with
| Expr.forallE _ d b _ => let d := go d (dec h); let b := go b (dec h); e.updateForallE! d b
| Expr.lam _ d b _ => let d := go d (dec h); let b := go b (dec h); e.updateLambdaE! d b
| Expr.mdata _ b => let b := go b (dec h); e.updateMData! b
| Expr.letE _ t v b _ => let t := go t (dec h); let v := go v (dec h); let b := go b (dec h); e.updateLetE! t v b
| Expr.app f a => let f := go f (dec h); let a := go a (dec h); e.updateApp! f a
| Expr.proj _ _ b => let b := go b (dec h); e.updateProj! b
| e => e
go e0 (Nat.le_refl ..)
end Expr
end Lean
open Lean
def addDecorations (e : Expr) : Expr :=
e.replace' fun expr h =>
match expr with
| Expr.forallE name type body data =>
let n := name.toString
let newType := addDecorations type
let newBody := addDecorations body
let rest := Expr.forallE name newType newBody data
some <| mkApp2 (mkConst `SlimCheck.NamedBinder) (mkStrLit n) rest
| _ => none
decreasing_by all_goals exact Nat.le_trans (by simp +arith) h