lean4-htt/tests/elab/grind_ematch_diag.lean
Leonardo de Moura 897e556d90
feat: add E-matching diagnostics to grind (#13558)
This PR adds the option `grind.ematch.diagnostics`, which tracks how
E-matching theorem instances depend on each other. When enabled, `grind`
records, for every new theorem instance, the set of previous instances
whose generated terms participated in the match. This produces a
hyper-graph `{thm_1, ..., thm_n} => thm` describing the provenance of
each instantiation.

The hyper-graph is stored in `Grind.Result` so downstream tooling can
inspect it. The trace class `trace.grind.ematch.diagnostics.compact`
prints a compact textual view of the hyper-graph, restricted to
constant-name origins. Example output:

```
  [grind.ematch.diagnostics.compact] ️ instances
    [inst] [] => th1
    [inst] [th1] => th3
    [inst] [th1] => th2
    [inst] [th2, th3] => th4
    [inst] [th4] => th5
```

The implementation stores an `ematchDiagSource` field on each `ENode`
and threads a `withEmatchDiagSource` reader through fact assertion so
that newly internalized terms inherit the origin of the instance that
produced them. During E-matching, `Choice` collects the sources of every
matched argument, and the resulting set becomes the predecessor set of
the new instance.
2026-04-29 12:17:55 +00:00

32 lines
809 B
Text

set_option grind.ematch.diagnostics true
set_option warn.sorry false
opaque p1 : Nat → Prop
opaque p2 : Nat → Prop
opaque p3 : Nat → Prop
opaque p4 : Nat → Prop
opaque p5 : Nat → Prop
opaque p6 : Nat → Prop
@[grind →] theorem th1 {x} : p1 x → p2 x := sorry
@[grind →] theorem th2 {x} : p2 x → p3 x := sorry
@[grind →] theorem th3 {x} : p2 x → p4 x := sorry
theorem th4 {x} : p3 x → p4 x → p5 x := sorry
grind_pattern th4 => p3 x, p4 x
@[grind →] theorem th5 {x} : p5 x → p6 x := sorry
set_option trace.grind.ematch.diagnostics.compact true
/--
trace: [grind.ematch.diagnostics.compact] ✅️ instances
[inst] [] => th1
[inst] [th1] => th3
[inst] [th1] => th2
[inst] [th2, th3] => th4
[inst] [th4] => th5
-/
#guard_msgs in
example : p1 a → p6 a := by
grind