@@ -242,6 +242,34 @@ private def casesWithTrace (mvarId : MVarId) (major : Expr) : GoalM (List MVarId
242242 saveCases declName false
243243 cases mvarId major
244244
245+ structure SplitCandidateAnchors where
246+ /-- Pairs `(anchor, split)` -/
247+ candidates : Array (UInt64 × Expr)
248+ /-- Number of digits (≥ 4) sufficient for distinguishing anchors. We usually display only the first `numDigits`. -/
249+ numDigits : Nat
250+
251+ /--
252+ Returns case-split candidates. Case-splits that are tagged as `.resolved` or `.notReady` are skipped.
253+ Applies additional `filter` if provided.
254+ -/
255+ def getSplitCandidateAnchors (filter : Expr → GoalM Bool := fun _ => return true ) : GoalM SplitCandidateAnchors := do
256+ let candidates := (← get).split.candidates
257+ let candidates ← candidates.toArray.mapM fun c => do
258+ let e := c.getExpr
259+ let anchor ← getAnchor e
260+ let status ← checkSplitStatus c
261+ return (e, status, anchor)
262+ let candidates ← candidates.filterM fun (e, status, _) => do
263+ -- **Note** : we ignore case-splits that are not ready or have already been resolved.
264+ -- We may consider adding an option for including "not-ready" splits in the future.
265+ if status matches .resolved | .notReady then return false
266+ filter e
267+ -- **TODO** : Add an option for including propositions that are only considered when using `+splitImp`
268+ -- **TODO** : Add an option for including terms whose type is an inductive predicate or type
269+ let candidates := candidates.map fun (e, _, anchor) => (anchor, e)
270+ let (candidates, numDigits) := truncateAnchors candidates
271+ return { candidates, numDigits }
272+
245273namespace Action
246274
247275/--
@@ -325,9 +353,10 @@ Remark: `numCases` and `isRec` are computed using `checkSplitStatus`.
325353private def splitCore (c : SplitInfo) (numCases : Nat) (isRec : Bool)
326354 (stopAtFirstFailure : Bool)
327355 (compress : Bool) : Action := fun goal _ kp => do
356+ let traceEnabled := (← getConfig).trace
328357 let mvarId ← goal.mkAuxMVar
329358 let cExpr := c.getExpr
330- let (mvarIds, goal) ← GoalM.run goal do
359+ let (( mvarIds, numDigits) , goal) ← GoalM.run goal do
331360 let gen ← getGeneration cExpr
332361 let genNew := if numCases > 1 || isRec then gen+1 else gen
333362 saveSplitDiagInfo cExpr genNew numCases c.source
@@ -339,8 +368,12 @@ private def splitCore (c : SplitInfo) (numCases : Nat) (isRec : Bool)
339368 casesMatch mvarId cExpr
340369 else
341370 casesWithTrace mvarId (← mkCasesMajor cExpr)
371+ let numDigits ← if traceEnabled then
372+ pure (← getSplitCandidateAnchors).numDigits
373+ else
374+ pure 0
375+ return (mvarIds, numDigits)
342376 let subgoals := mvarIds.map fun mvarId => { goal with mvarId }
343- let traceEnabled := (← getConfig).trace
344377 let mut seqNew : Array (List (TSyntax `grind)) := #[]
345378 let mut stuckNew : Array Goal := #[]
346379 for subgoal in subgoals do
@@ -369,9 +402,7 @@ private def splitCore (c : SplitInfo) (numCases : Nat) (isRec : Bool)
369402 if stuckNew.isEmpty then
370403 if traceEnabled then
371404 let anchor ← goal.withContext <| getAnchor cExpr
372- -- **TODO** : compute the exact number of digits
373- let numDigits := 4
374- let anchorPrefix := anchor >>> (64 - 16 )
405+ let anchorPrefix := anchor >>> (64 - 4 *numDigits.toUInt64)
375406 let hexnum := mkNode `hexnum #[mkAtom (anchorToString numDigits anchorPrefix)]
376407 let cases ← `(grind| cases #$hexnum)
377408 return .closed (← mkCasesResultSeq cases seqNew compress)
0 commit comments