Skip to content

Commit c3a19fa

Browse files
authored
Ensure that auxiliary declarations on different branches have different names (#224)
1 parent f042486 commit c3a19fa

File tree

6 files changed

+66
-88
lines changed

6 files changed

+66
-88
lines changed

Aesop/Tree/AddRapp.lean

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,18 @@ def makeInitialGoal (goal : Subgoal) (mvars : UnorderedArraySet MVarId)
155155
unsafe def addRappUnsafe (r : AddRapp) : TreeM RappRef := do
156156
let originalSubgoals := r.goals
157157

158+
-- We update the rapp's `auxDeclNGen` to ensure that tactics on different
159+
-- branches of the search tree generate different names for auxiliary
160+
-- declarations.
161+
let auxDeclNGen ←
162+
match ← (← r.parent.get).parentRapp? with
163+
| none =>
164+
let (child, parent) := (← getDeclNGen).mkChild
165+
setDeclNGen parent
166+
pure child
167+
| some parentRapp => parentRapp.getChildAuxDeclNameGenerator
168+
let metaState := { r.postState with core.auxDeclNGen := auxDeclNGen }
169+
158170
let rref : RappRef ← IO.mkRef $ Rapp.mk {
159171
id := ← getAndIncrementNextRappId
160172
parent := r.parent
@@ -165,7 +177,7 @@ unsafe def addRappUnsafe (r : AddRapp) : TreeM RappRef := do
165177
scriptSteps? := r.scriptSteps?
166178
originalSubgoals := originalSubgoals.map (·.mvarId)
167179
successProbability := r.successProbability
168-
metaState := r.postState
180+
metaState
169181
introducedMVars := {} -- will be filled in later
170182
assignedMVars := {} -- will be filled in later
171183
}

Aesop/Tree/Data.lean

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,3 +906,17 @@ def provenGoal? (c : MVarCluster) : BaseIO (Option GoalRef) :=
906906
c.goals.findM? λ gref => return (← gref.get).state.isProven
907907

908908
end MVarCluster
909+
910+
911+
namespace RappRef
912+
913+
/-- Get a `DeclNameGenerator` for auxiliary declarations that can be used by
914+
children of this rapp. Successive calls to this function return
915+
`DeclNameGenerators` that are guaranteed to generate distinct names. -/
916+
def getChildAuxDeclNameGenerator (r : RappRef) : BaseIO DeclNameGenerator := do
917+
r.modifyGet λ r =>
918+
let (child, parent) := r.metaState.core.auxDeclNGen.mkChild
919+
let r := r.setMetaState $ { r.metaState with core.auxDeclNGen := parent }
920+
(child, r)
921+
922+
end RappRef

Aesop/Tree/ExtractProof.lean

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ When we assign a metavariable `m`, we must take some care:
3434
assignments, since they may additionally contain delayed-assigned
3535
metavariables which depend on the unassigned metavariables.
3636
37-
We also replay env modifications in a similar fashion. We assume that rules only
38-
add declarations to the environment.
37+
We also replay environment modifications -- e.g., auxiliary declarations added
38+
by a tactic -- in a similar fashion. To do this, we use
39+
`Environment.replayConsts`, so newly added constants are sent to the kernel
40+
again and environment extensions get a chance to replay their changes with
41+
`replay?`.
3942
4043
If the root goal is not proven, we extract the goals after safe rule
4144
applications. This means we proceed as above, but stop as soon as we reach the
@@ -51,11 +54,8 @@ local macro "throwPRError " s:interpolatedStr(term) : term =>
5154

5255
-- ## Copying Declarations
5356

54-
5557
private def copyEnvModifications (oldEnv newEnv : Environment) : CoreM Unit := do
56-
let env ← getEnv
57-
let env ← env.replayConsts oldEnv newEnv
58-
setEnv env
58+
setEnv $ ← (← getEnv).replayConsts oldEnv newEnv (skipExisting := true)
5959

6060
-- ## Copying Metavariables
6161

@@ -104,7 +104,7 @@ private def visitGoal (parentEnv : Environment) (g : Goal) :
104104
| NormalizationState.normal postNormGoal postState _ =>
105105
copyEnvModifications parentEnv postState.core.env
106106
copyExprMVar postState g.preNormGoal
107-
return (postNormGoal, g.children, ← getEnv)
107+
return (postNormGoal, g.children, postState.core.env)
108108
| NormalizationState.provenByNormalization postState _ =>
109109
copyEnvModifications parentEnv postState.core.env
110110
copyExprMVar postState g.preNormGoal

AesopTest/AuxDecl.lean

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/-
2+
Copyright (c) 2025 Jannis Limperg. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Jannis Limperg
5+
-/
6+
7+
import Aesop
8+
9+
/-
10+
This test case checks whether tactics that make use of auxiliary declarations,
11+
such as `omega` and `bv_decide`, work with Aesop. Auxiliary declarations are
12+
problematic because we can't allows tactics on different branches of the search
13+
tree to add auxiliary declarations with the same name.
14+
-/
15+
16+
theorem foo (m n : Nat) : n + m = m + n ∧ m + n = n + m := by
17+
fail_if_success aesop (config := { terminal := true })
18+
aesop (add safe (by omega))
19+
20+
local instance [Add α] [Add β] : Add (α × β) :=
21+
⟨λ (a, b) (a', b') => (a + a', b + b')⟩
22+
23+
theorem bar
24+
(fst snd fst_1 snd_1 fst_2 snd_2 w w_1 w_2 w_3 : BitVec 128)
25+
(left : w_1.uaddOverflow w_3 = true)
26+
(left_1 : w.uaddOverflow w_2 = true)
27+
(right : (w_1 + w_3).uaddOverflow 1#128 = true) :
28+
(fst_2, snd_2) = (fst, snd) + (fst_1, snd_1) := by
29+
aesop (add safe (by bv_decide))
30+
31+
theorem baz (a b : BitVec 1) : (a = 0 ∨ a = 1) ∧ (b = 0 ∨ b = 1) := by
32+
aesop (add safe 1000 (by bv_decide))

AesopTest/Environment.lean

Lines changed: 0 additions & 54 deletions
This file was deleted.

AesopTest/NormSimpUnchangedMVarAssigned.lean

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)