Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bd89247
Adding proof reconstruction scaffold
felipeperet Mar 7, 2026
4c8b5c4
Removing tactic script approach
felipeperet Mar 7, 2026
3045abc
Including reconstruction trace in optimizeEnv
felipeperet Mar 7, 2026
b096f4b
Removing rewriteTrace from OptimizeEnv
felipeperet Mar 8, 2026
17f711b
Proof certificate generation and propagation in optimization pipeline
felipeperet Mar 9, 2026
b16724b
Indentation
felipeperet Mar 9, 2026
c84cb03
Importing Test module for proof reconstruction
felipeperet Mar 9, 2026
50b7b2e
Fallback when proof certificate type does not match goal
felipeperet Mar 10, 2026
c85933b
compose proof certificates for nested rewrites via congrArg
felipeperet Mar 11, 2026
2344b53
ci: re-run tests
felipeperet Mar 11, 2026
b5ce0bc
test: simplify cache lookup
felipeperet Mar 11, 2026
3ea6942
selective cache bypass for proof reconstruction
felipeperet Mar 11, 2026
5777d52
track stripped proofs explicitly to reduce unnecessary re-optimization
felipeperet Mar 11, 2026
67f7963
fix ambiguity when searching for argument index at buildCongrArgFromP…
felipeperet Mar 13, 2026
ede8eef
fix: annotate proof argument position to survive unfolding
felipeperet Mar 13, 2026
7d3bf1b
fix: restrict proof propagation to fvar-free expressions in cache
felipeperet Mar 14, 2026
a93ba4b
remove unnecessary try/catch in annotateProofWithPosFromEnd
felipeperet Mar 14, 2026
21cc1b4
bridge for proof certificates composition
felipeperet Mar 15, 2026
8532e65
test: removing try-catch fallback in proof reconstruction
felipeperet Mar 15, 2026
0d7a59e
testOptimize support for proof reconstruction
felipeperet Mar 16, 2026
13555b8
test: removing macRecDepth from testOptimize
felipeperet Mar 16, 2026
982370b
scope maxRecDepth to blaster tactic and specific deep tests
felipeperet Mar 16, 2026
cd280b1
proof reconstruction for commutativity and reorder-rewrite composition
felipeperet Mar 18, 2026
1a31f4a
setting maxRecDepth for optimizeNatSub testOptimize
felipeperet Mar 18, 2026
df148fd
proof certificate for Nat.add constant propagation
felipeperet Mar 18, 2026
d8ef2c9
fix testOptimize proof reconstruction semantics
felipeperet Mar 18, 2026
e25b2fa
test: refactor optimizeTestImp proof verification
felipeperet Mar 18, 2026
89b2972
proof reconstruction for Nat.add/sub rewrites
felipeperet Mar 18, 2026
1c53990
test: avoid unnecessary allocations in optimizeAppAux and Eq.refl
felipeperet Mar 18, 2026
30a4f8b
proof reconstruction support for multi-arg rewrites
felipeperet Mar 19, 2026
e2eb89b
documentation
felipeperet Mar 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Blaster.lean
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
import Blaster.Command
import Blaster.Logging
import Blaster.Optimize
import Blaster.Reconstruct
import Blaster.Smt
import Blaster.StateMachine
26 changes: 21 additions & 5 deletions Blaster/Command/Tactic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,28 @@ def blasterTacticImp : Tactic := fun stx =>
let sOpts ← parseSolveOptions opts default
let (goal, nbQuantifiers) ← revertHypotheses (← getMainGoal)
let env := {(default : TranslateEnv) with optEnv.options.solverOptions := sOpts}
let ((result, optExpr), _) ←
withTheReader Core.Context (fun ctx => { ctx with maxHeartbeats := 0 }) $ do
IO.setNumHeartbeats 0
Translate.main (← goal.getType >>= instantiateMVars') (logUndetermined := false) |>.run env
let ((result, (optExpr, proof)), _) ←
withTheReader Core.Context
(fun ctx => { ctx with maxHeartbeats := 0, maxRecDepth := max ctx.maxRecDepth 4096 }) $ do
IO.setNumHeartbeats 0
Translate.main (← goal.getType >>= instantiateMVars') (logUndetermined := false) |>.run env
match result with
| .Valid => goal.admit -- TODO: replace with proof reconstruction
| .Valid =>
match proof with
| some p =>
-- verify certificate type matches goal before assigning
let goalType ← goal.getType
let pType ← inferType p
if (← isDefEq pType goalType) then
goal.assign p
else
logWarning "blaster: proof reconstruction failed, closing with admit"
goal.admit
| none =>
try goal.refl
catch _ =>
logWarning "blaster: proof reconstruction failed, closing with admit"
goal.admit
| .Falsified cex => throwTacticEx `blaster goal "Goal was falsified (see counterexample above)"
| .Undetermined =>
-- Replace the goal with the optimized expression
Expand Down
2 changes: 1 addition & 1 deletion Blaster/Optimize.lean
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@

import Blaster.Optimize.Basic
import Blaster.Optimize.Lemmas
import Blaster.Optimize.Types
203 changes: 139 additions & 64 deletions Blaster/Optimize/Basic.lean

Large diffs are not rendered by default.

46 changes: 27 additions & 19 deletions Blaster/Optimize/Env.lean
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import Lean
import Blaster.Command.Options
import Blaster.Optimize.Expr
import Blaster.Optimize.MatchInfo
import Blaster.Optimize.Opaque
import Blaster.Optimize.Types
import Blaster.Smt.Term
import Blaster.Command.Options

open Lean Meta Blaster.Smt Blaster.Options

Expand Down Expand Up @@ -83,7 +84,7 @@ inductive MatchEntry where
deriving Repr

abbrev HypothesisMap := Std.HashMap Lean.Expr Lean.Expr
abbrev RewriteCacheMap := Std.HashMap Lean.Expr Lean.Expr
abbrev RewriteCacheMap := Std.HashMap Lean.Expr OptimizeResult
abbrev MatchEntryMap := Std.HashMap Lean.Expr MatchEntry -- with key corresponding to a match pattern
abbrev MatchContextMap := Std.HashMap Lean.Expr MatchEntryMap -- with key corresponding to a match discriminator
abbrev EqualityMap := Std.HashMap Lean.Expr Lean.Expr -- with key corresponding to expression to be replaced.
Expand Down Expand Up @@ -289,6 +290,11 @@ structure OptimizeEnv where
-/
restart : Bool

/-- Set of expressions whose proof certificates were stripped during caching
due to containing free variables in a global context.
-/
strippedProofExprs : Std.HashSet Lean.Expr

/-- local declaration context -/
ctx : LocalDeclContext

Expand All @@ -307,6 +313,7 @@ instance : Inhabited OptimizeEnv where
memCache := default,
options := default,
restart := false,
strippedProofExprs := Std.HashSet.emptyWithCapacity,
ctx := default
}

Expand Down Expand Up @@ -612,20 +619,20 @@ def isInFunApp : TranslateEnvT Bool :=
return (← get).optEnv.options.inFunApp

@[always_inline, inline]
def findGlobalCache (a : Expr) : TranslateEnvT (Option Expr) := do
def findGlobalCache (a : Expr) : TranslateEnvT (Option OptimizeResult) := do
return (← get).optEnv.globalRewriteCache.get? a

@[always_inline, inline]
def findLocalCache (a : Expr) : TranslateEnvT (Option Expr) := do
def findLocalCache (a : Expr) : TranslateEnvT (Option OptimizeResult) := do
return (← get).optEnv.localRewriteCache.get? a

/-- Update global rewrite cache with `a := b`. -/
def updateGlobalRewriteCache (a : Expr) (b : Expr) : TranslateEnvT Unit := do
modify (fun env => { env with optEnv.globalRewriteCache := env.optEnv.globalRewriteCache.insert a b })
def updateGlobalRewriteCache (a : Expr) (r : OptimizeResult) : TranslateEnvT Unit := do
modify (fun env => { env with optEnv.globalRewriteCache := env.optEnv.globalRewriteCache.insert a r })

/-- Update local rewrite cache with `a := b`. -/
def updateLocalRewriteCache (a : Expr) (b : Expr) : TranslateEnvT Unit := do
modify (fun env => { env with optEnv.localRewriteCache := env.optEnv.localRewriteCache.insert a b })
def updateLocalRewriteCache (a : Expr) (r : OptimizeResult) : TranslateEnvT Unit := do
modify (fun env => { env with optEnv.localRewriteCache := env.optEnv.localRewriteCache.insert a r })

/-- Update synthesize decidable instance cache with `a := b`. -/
@[always_inline, inline]
Expand Down Expand Up @@ -655,29 +662,30 @@ def withSynthInstanceCache (a : Expr) (f: Unit → TranslateEnvT (Option Expr))
@[always_inline, inline]
def mkExpr (a : Expr) (cacheResult := true) : TranslateEnvT Expr := do
match (← findGlobalCache a) with
| some a' => return a'
| some r => return r.optExpr
| none => do
if cacheResult then updateGlobalRewriteCache a a
if cacheResult then updateGlobalRewriteCache a ⟨a, none⟩
return a

/-- Return `true` only when both hypothesisMap and matchInContext are empty and isRefHyp flag is not set -/
@[always_inline, inline]
def isGlobalContext : TranslateEnvT Bool := do
let ⟨_, ⟨_, _, _, _, _, _, _, _, hypothesisContext, matchInContext, _, _, _, _⟩⟩ ← get
let ⟨_, ⟨_, _, _, _, _, _, _, _, hypothesisContext, matchInContext, _, _, _, _, _⟩⟩ ← get
return hypothesisContext.hypothesisMap.size == 0 && matchInContext.size == 0

/-- Perform the following:
- When isGlobal
- Add entry `a := b` to `globalRewriteCache`
- Add entry `a := r` to `globalRewriteCache`
- Otherwise
- Add entry `a := b` to `localRewriteCache`
- Add entry `a := r` to `localRewriteCache`
-/
@[always_inline, inline]
def updateOptimizeEnvCache (a : Expr) (b : Expr) (isGlobal : Bool) : TranslateEnvT Unit := do
-- trace[Optimize.cacheExpr] "cacheExpr {← ppExpr a} ===> {← ppExpr b}"
def updateOptimizeEnvCache (a : Expr) (r : OptimizeResult) (isGlobal : Bool) :
TranslateEnvT Unit := do
-- trace[Optimize.cacheExpr] "cacheExpr {← ppExpr a} ===> {← ppExpr r.optExpr}"
if isGlobal
then updateGlobalRewriteCache a b
else updateLocalRewriteCache a b
then updateGlobalRewriteCache a r
else updateLocalRewriteCache a r

/-- Perform the following:
- When isGlobal
Expand All @@ -690,7 +698,7 @@ def updateOptimizeEnvCache (a : Expr) (b : Expr) (isGlobal : Bool) : TranslateEn
- Otherwise `none`
-/
@[always_inline, inline]
def isInOptimizeCache? (a : Expr) (isGlobal : Bool) : TranslateEnvT (Option Expr) := do
def isInOptimizeCache? (a : Expr) (isGlobal : Bool) : TranslateEnvT (Option OptimizeResult) := do
if isGlobal
then findGlobalCache a
else findLocalCache a
Expand Down Expand Up @@ -1712,7 +1720,7 @@ where
An error is triggered if no corresponding entry can be found in `recFunMap`.
-/
def hasRecFunInst? (instApp : Expr) : TranslateEnvT (Option Expr) := do
let ⟨_, ⟨_, _, _, _, _,recFunInstCache,_,recFunMap, _, _, _, _, _, _⟩⟩ ← get
let ⟨_, ⟨_, _, _, _, _,recFunInstCache,_,recFunMap, _, _, _, _, _, _, _⟩⟩ ← get
match recFunInstCache.get? instApp with
| some fbody =>
-- retrieve function application from recFunMap
Expand Down
Loading
Loading