@@ -12,14 +12,31 @@ import Lean.Meta.Tactic.Grind.EMatchTheoremParam
1212import Lean.Meta.Tactic.Grind.MarkNestedSubsingletons
1313namespace Lean.Meta.Grind.Action
1414
15+ /-
16+ **Note** : The unique IDs created to instantiate theorems have the form `<prefix>.<num>`,
17+ where `<num>` corresponds to the instantiation order within a particular proof branch.
18+ Thus, by sorting the collected theorems using their corresponding unique IDs,
19+ we can construct an `instantiate` tactic that performs the instantiations using
20+ the original order.
21+
22+ **Note** : It is unclear at this point whether this is a good strategy or not.
23+ The order in which things are asserted affects the proof found by `grind`.
24+ Thus, preserving the original order should intuitively help ensure that the generated
25+ tactic script for the continuation still closes the goal when combined with the
26+ generated `instantiate` tactic. However, it does not guarantee that the
27+ script can be successfully replayed, since we are filtering out instantiations that do
28+ not appear in the final proof term. Recall that a theorem instance may
29+ contribute to the proof search even if it does not appear in the final proof term.
30+ -/
31+
1532structure CollectState where
1633 visited : Std.HashSet ExprPtr := {}
1734 collectedThms : Std.HashSet (Origin × EMatchTheoremKind) := {}
18- thms : Array EMatchTheorem := #[]
35+ idAndThms : Array (Name × EMatchTheorem) := #[]
1936
20- def collect (e : Expr) (map : EMatch.InstanceMap) : Array EMatchTheorem :=
37+ def collect (e : Expr) (map : EMatch.InstanceMap) : Array (Name × EMatchTheorem) :=
2138 let (_, s) := go e |>.run {}
22- s.thms
39+ s.idAndThms
2340where
2441 go (e : Expr) : StateM CollectState Unit := do
2542 if isMarkedSubsingletonApp e then
3552 if let some thm := map[uniqueId]? then
3653 let key := (thm.origin, thm.kind)
3754 unless (← get).collectedThms.contains key do
38- modify fun s => { s with collectedThms := s.collectedThms.insert key, thms := s.thms .push thm }
55+ modify fun s => { s with collectedThms := s.collectedThms.insert key, idAndThms := s.idAndThms .push (uniqueId, thm) }
3956 match e with
4057 | .lam _ d b _
4158 | .forallE _ d b _ => go d; go b
@@ -93,7 +110,10 @@ public def instantiate' : Action := fun goal kna kp => do
93110 | .closed seq =>
94111 if (← getConfig).trace then
95112 let proof ← instantiateMVars (mkMVar goal.mvarId)
96- let usedThms := collect proof map
113+ let usedIdAndThms := collect proof map
114+ -- **Note** : See note above. We want to sort here to reproduce the original instantiation order.
115+ let usedIdAndThms := usedIdAndThms.qsort fun (id₁, _) (id₂, _) => id₁.lt id₂
116+ let usedThms := usedIdAndThms.map (·.2 )
97117 let newSeq ← mkNewSeq goal usedThms seq (approx := false )
98118 if (← checkSeqAt saved? goal newSeq) then
99119 return .closed newSeq
0 commit comments