Skip to content

Add constant unfolding heuristic based on definitional heights. - #22528

Open
GPRicci wants to merge 2 commits into
rocq-prover:masterfrom
GPRicci:conv-height-heuristic
Open

GPRicci wants to merge 2 commits into
rocq-prover:masterfrom
GPRicci:conv-height-heuristic

Conversation

@GPRicci

@GPRicci GPRicci commented Sep 24, 2026 •

Copy link
Copy Markdown

Adds an optional heuristic for the conversion of two constants.

  • Behind flag Kernel Conversion Height Heuristic
  • When a constant is defined, its definitional height h is computed and a strategy level equal to -h is set for it.
  • Over-approximates dependencies between constants. I.e. if c1 depends on c2 => h1 > h2.

Changes:

  • kernel/declarations.mli : Added typing flag to (de)activate heuristic. Added field to constant_body record to store computed heights.

  • kernel/environ.ml : Added function to compute definitional height and to store the height in a constant's body

  • kernel/safe_typing.ml : Lifted functions defined in kernel/environ.ml to safe environments.

  • library/global.ml : Globalized functions defined in kernel/safe_typing.ml

  • vernac/comDefinition.ml : When heuristic is active, do_definition computes height of constant, stores computed height, and sets strategy level.

  • vernac/vernacinterp.ml : When heuristic is active, transparent proof-ending commands (Defined) triggers the mechanics mentioned above. This allows constants defined interactively to profit from the heuristic.

  • vernac/vernacentries.ml : Register flag.

  • Added / updated test-suite.

  • Added changelog.
  • Added / updated documentation.
  • Updated documented syntax by running make doc_gram_rsts.

@coqbot-app coqbot-app Bot added the needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. label Sep 24, 2026
Comment thread vernac/comDefinition.ml Outdated
(match gref with
| ConstRef c ->
let def_height_c = Environ.constant_definitional_height (Global.env ()) c in
Global.set_constant_def_height c def_height_c;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be computed by the kernel and we should trust the height, in my opinion. (As usual limitations with functors apply.)

@GPRicci
GPRicci force-pushed the conv-height-heuristic branch from 26d026b to 5bcf719 Compare September 24, 2026 18:53
@GPRicci

GPRicci commented Sep 25, 2026 •

Copy link
Copy Markdown
Author

According to the CI logs, there are 7 tests failing:

FAILURES
    success/UnfoldDepHeuristic.v ... Error! (should be accepted)
    output/Arguments.v ... Error! (unexpected output)
    output/ArgumentsScope.v ... Error! (unexpected output)
    output/PrintSecDeps.v ... Error! (unexpected output)
    output/UnivBinders.v ... Error! (unexpected output)
    output/Utf8Impargs.v ... Error! (unexpected output)
    output/sort_poly_elab.v ... Error! (unexpected output)

The first one is the test that I added. a Fail Timeout ... command does not fail in the CI. Maybe the machine that runs it is faster than mine. So I suppose I could give fact a bigger argument.

I had a look at the other tests' outputs and there are indeed differences in outputs.
For example, in Arguments.v :

Definition pf (D1 C1 : Type) (f : D1 -> C1) (D2 C2 : Type) (g : D2 -> C2) :=
fun x => (f (fst x), g (snd x)).
Declare Scope foo_scope.
Declare Scope bar_scope.
Delimit Scope foo_scope with F.
Arguments pf {D1%_F C1%_type} f [D2 C2] g x : simpl never.
About pf.

When pf is defined in L12 with the heuristic active, it gets assigned strategy level (-2). So the output of About pf. in L18 shows
pf is transparent (level -2), but the .out file says pf is transparent only.

If I deactivate the flag, the messages coincide with what's recorded in the .out files. So I suppose I shouldn't change these files, seeing as the flag won't be active by default.
What do you think @ppedrot @SkySkimmer ?

@GPRicci
GPRicci force-pushed the conv-height-heuristic branch 5 times, most recently from f05407e to 52ac248 Compare September 28, 2026 07:08
@tabareau

Copy link
Copy Markdown
Contributor

@coqbot bench

@Janno

Janno commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

I am curious to see if this will run into the same problem that lead to the mathcomp regressions in #21514 (comment). I don't see a reason why it wouldn't, given that unfolding a term will decrease the depth and in case of a tie we'll ping-pong back and forth between the LHS and RHS. (I suspect this back and forth is also responsible for a lot of the slowdown in other projects in that PR but I have not confirmed that.)

I wonder if we can work around the problem by committing to a side in a way that is stable over delta reductions at the head of the term. If the heuristic chooses f for f ~ g and we get to f' ~ g through just delta steps at the head, we should not re-evaluate the heuristic but instead stick with the LHS. Explicit Strategy choices must still apply, of course. This should avoid the back and forth between the two sides and get us closer to the current performance profile. I am not sure how ugly it would be to implement but it seems possible, at least.

@coqbot-app

coqbot-app Bot commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

🏁 Bench results:

┌─────────────────────────┬───────────────────────┬─────────────────────────────────────┬────────────────────────┐
│                         │     user time [s]     │          CPU instructions           │ max resident mem [KB]  │
│                         │                       │                                     │                        │
│      package_name       │  NEW     OLD    PDIFF │      NEW            OLD       PDIFF │   NEW     OLD    PDIFF │
├─────────────────────────┼───────────────────────┼─────────────────────────────────────┼────────────────────────┤
│            rocq-runtime │ 451.52  449.62   0.42 │ 3407308298264  3405260660687   0.06 │  887824  870868   1.95 │
│               rocq-core │  11.00   10.94   0.55 │   74233304067    73750973975   0.65 │  596836  596304   0.09 │
│ rocq-mathcomp-ssreflect │   1.25    1.23   1.63 │    8222879874     8155914036   0.82 │  668200  664404   0.57 │
│                coq-core │   6.92    6.78   2.06 │   48480168314    48356440907   0.26 │  142892  142900  -0.01 │
│               rocq-elpi │  25.42   24.77   2.62 │  182696213561   176534972128   3.49 │  534336  527472   1.30 │
│     rocq-mathcomp-order │ 103.68   97.17   6.70 │  720318992296   665704743040   8.20 │ 1002016  989836   1.23 │
│      rocq-mathcomp-boot │  46.55   39.02  19.30 │  293707060725   224293275150  30.95 │  729492  718848   1.48 │
└─────────────────────────┴───────────────────────┴─────────────────────────────────────┴────────────────────────┘

INFO: failed to install
rocq-stdlib (in NEW)
coq-hott (in NEW)
rocq-mathcomp-finite-group (in NEW)

rocq-bignums (dependency rocq-stdlib failed)
coq-performance-tests-lite (dependency rocq-stdlib failed)
coq-engine-bench-lite (dependency rocq-stdlib failed)
rocq-mathcomp-algebra (dependency rocq-mathcomp-finite-group failed)
rocq-mathcomp-solvable (dependency rocq-mathcomp-finite-group failed)
rocq-mathcomp-field (dependency rocq-mathcomp-finite-group failed)
rocq-mathcomp-group-representation (dependency rocq-mathcomp-finite-group failed)
coq-mathcomp-odd-order (dependency rocq-mathcomp-finite-group failed)
rocq-mathcomp-analysis (dependency rocq-mathcomp-finite-group failed)
coq-math-classes (dependency rocq-stdlib failed)
coq-corn (dependency rocq-stdlib failed)
coq-compcert (dependency rocq-stdlib failed)
rocq-equations (dependency rocq-stdlib failed)
rocq-metarocq-utils (dependency rocq-stdlib failed)
rocq-metarocq-common (dependency rocq-stdlib failed)
rocq-metarocq-template (dependency rocq-stdlib failed)
rocq-metarocq-pcuic (dependency rocq-stdlib failed)
rocq-metarocq-safechecker (dependency rocq-stdlib failed)
rocq-metarocq-erasure (dependency rocq-stdlib failed)
rocq-metarocq-translations (dependency rocq-stdlib failed)
coq-color (dependency rocq-stdlib failed)
coq-coqprime (dependency rocq-stdlib failed)
coq-coqutil (dependency rocq-stdlib failed)
coq-bedrock2 (dependency rocq-stdlib failed)
coq-rewriter (dependency rocq-stdlib failed)
coq-fiat-core (dependency rocq-stdlib failed)
coq-fiat-parsers (dependency rocq-stdlib failed)
coq-fiat-crypto-with-bedrock (dependency rocq-stdlib failed)
coq-unimath (dependency rocq-stdlib failed)
coq-coquelicot (dependency rocq-stdlib failed)
coq-iris-examples (dependency rocq-stdlib failed)
coq-fourcolor (dependency rocq-mathcomp-finite-group failed)
coq-rewriter-perf-SuperFast (dependency rocq-stdlib failed)
coq-vst (dependency rocq-stdlib failed)
coq-category-theory (dependency rocq-stdlib failed)
coq-neural-net-interp-computed-lite (dependency rocq-stdlib failed)

🐢 Top 25 slow downs
┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                         TOP 25 SLOW DOWNS                                          │
│                                                                                                    │
│   OLD      NEW     DIFF     %DIFF      Ln             FILE                                         │
├────────────────────────────────────────────────────────────────────────────────────────────────────┤
│  0.00205    4.56  4.5530  222204.20%  2007  rocq-mathcomp-order/order/total_order_instances.v.html │
│ 0.000872   0.947  0.9464  108531.42%  2747  rocq-mathcomp-boot/boot/finset.v.html                  │
│ 0.000804   0.939  0.9377  116633.21%  2010  rocq-mathcomp-boot/boot/finset.v.html                  │
│ 0.000645   0.937  0.9367  145222.48%  2008  rocq-mathcomp-boot/boot/finset.v.html                  │
│ 0.000816   0.935  0.9341  114475.61%  2011  rocq-mathcomp-boot/boot/finset.v.html                  │
│ 0.000907   0.846  0.8450   93160.31%  2013  rocq-mathcomp-boot/boot/finset.v.html                  │
│ 0.000684   0.735  0.7340  107305.99%   270  rocq-mathcomp-boot/boot/finset.v.html                  │
│   0.0134   0.543  0.5296    3949.19%   277  rocq-mathcomp-boot/boot/fingraph.v.html                │
│ 0.000553   0.454  0.4532   81952.80%  2012  rocq-mathcomp-boot/boot/finset.v.html                  │
│  0.00116   0.344  0.3428   29452.23%  1939  rocq-mathcomp-order/order/total_order_instances.v.html │
│  0.00821   0.348  0.3401    4144.47%   934  rocq-mathcomp-boot/boot/fingraph.v.html                │
│ 0.000554   0.238  0.2375   42867.15%  2514  rocq-mathcomp-boot/boot/finset.v.html                  │
│  0.00341   0.178  0.1745    5117.63%   256  rocq-mathcomp-order/order/interval.v.html              │
│ 0.000997   0.154  0.1527   15312.14%  1941  rocq-mathcomp-order/order/total_order_instances.v.html │
│ 0.000538   0.104  0.1036   19259.85%  2016  rocq-mathcomp-boot/boot/finset.v.html                  │
│ 0.000320   0.103  0.1025   32026.56%  2291  rocq-mathcomp-boot/boot/finset.v.html                  │
│ 0.000363   0.103  0.1023   28185.67%   271  rocq-mathcomp-boot/boot/finset.v.html                  │
│  0.00241  0.0562  0.0537    2227.14%   910  rocq-mathcomp-boot/boot/fingraph.v.html                │
│     1.40    1.44  0.0483       3.46%    87  rocq-mathcomp-order/order/total_order.v.html           │
│     1.44    1.49  0.0457       3.17%   150  rocq-mathcomp-order/order/complemented_lattice.v.html  │
│    0.888   0.929  0.0414       4.67%     3  rocq-mathcomp-order/order/all_order.v.html             │
│ 0.000102  0.0341  0.0340   33302.94%    94  rocq-mathcomp-order/order/total_order_instances.v.html │
│    0.898   0.927  0.0294       3.27%   872  rocq-mathcomp-order/order/lattice.v.html               │
│    0.583   0.612  0.0287       4.92%     5  rocq-mathcomp-order/order/orderedzmod.v.html           │
│ 0.000383  0.0281  0.0278    7247.26%   105  rocq-mathcomp-boot/boot/prime.v.html                   │
└────────────────────────────────────────────────────────────────────────────────────────────────────┘
🐇 Top 25 speed ups
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                         TOP 25 SPEED UPS                                         │
│                                                                                                  │
│  OLD      NEW      DIFF     %DIFF    Ln             FILE                                         │
├──────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 0.0309   0.00139  -0.0295  -95.51%   208  rocq-mathcomp-boot/boot/ssrAC.v.html                   │
│ 0.0309   0.00179  -0.0291  -94.21%    40  rocq-mathcomp-boot/boot/binomial.v.html                │
│ 0.0483    0.0196  -0.0288  -59.51%  1065  rocq-mathcomp-order/order/lattice.v.html               │
│ 0.0285  0.000802  -0.0277  -97.19%   110  rocq-mathcomp-boot/boot/prime.v.html                   │
│ 0.0244   0.00166  -0.0227  -93.22%    84  rocq-mathcomp-boot/boot/fingraph.v.html                │
│ 0.0687    0.0473  -0.0214  -31.18%   145  rocq-mathcomp-order/order/interval.v.html              │
│ 0.0208  0.000322  -0.0205  -98.45%   154  rocq-mathcomp-boot/boot/choice.v.html                  │
│ 0.0205  0.000150  -0.0203  -99.27%    96  rocq-mathcomp-boot/boot/div.v.html                     │
│ 0.0196  0.000509  -0.0190  -97.40%   362  rocq-mathcomp-boot/boot/seq.v.html                     │
│ 0.0145  0.000220  -0.0143  -98.48%  1329  rocq-mathcomp-boot/boot/nmodule.v.html                 │
│ 0.0121  0.000398  -0.0117  -96.72%   924  rocq-mathcomp-boot/boot/eqtype.v.html                  │
│ 0.0253    0.0137  -0.0116  -45.83%  1447  rocq-mathcomp-boot/boot/fintype.v.html                 │
│ 0.0147   0.00310  -0.0116  -78.98%   866  rocq-mathcomp-order/order/total_order_instances.v.html │
│ 0.0119  0.000450  -0.0115  -96.22%   458  rocq-mathcomp-boot/boot/finset.v.html                  │
│ 0.0119  0.000498  -0.0114  -95.80%   554  rocq-mathcomp-boot/boot/tuple.v.html                   │
│ 0.0127   0.00143  -0.0113  -88.74%  1996  rocq-mathcomp-order/order/total_order_instances.v.html │
│ 0.0134   0.00236  -0.0111  -82.41%  2413  rocq-mathcomp-boot/boot/bigop.v.html                   │
│ 0.0118   0.00114  -0.0107  -90.32%  2245  rocq-mathcomp-boot/boot/bigop.v.html                   │
│ 0.0172   0.00679  -0.0104  -60.56%  2351  rocq-mathcomp-boot/boot/bigop.v.html                   │
│ 0.0105  0.000340  -0.0101  -96.75%   864  rocq-mathcomp-boot/boot/bigop.v.html                   │
│ 0.0103  0.000641  -0.0097  -93.78%    56  rocq-mathcomp-order/order/order_instances.v.html       │
│ 0.0102  0.000596  -0.0096  -94.17%  1222  rocq-mathcomp-boot/boot/seq.v.html                     │
│ 0.0102  0.000611  -0.0096  -94.01%   322  rocq-mathcomp-order/order/orderedzmod.v.html           │
│ 0.0143   0.00493  -0.0094  -65.51%  2185  rocq-mathcomp-boot/boot/bigop.v.html                   │
│ 0.0839    0.0746  -0.0093  -11.12%   677  rocq-mathcomp-order/order/interval.v.html              │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

@GPRicci
GPRicci force-pushed the conv-height-heuristic branch 2 times, most recently from 2659885 to aeeae80 Compare September 29, 2026 14:14
- Behind flag `Kernel Conversion Height Heuristic`
- When a constant is defined, its definitional height [h] is computed and stored.
- If the flag is active, a strategy level equal to [-h] is set for the constant.
- Over-approximates dependencies between constants. I.e. if [c1] depends on [c2] => h1 > h2.
…purposes.

- Updated some .out files to consider transparency levels shown when `About.` is run on definitions.
@GPRicci
GPRicci force-pushed the conv-height-heuristic branch from aeeae80 to ae60841 Compare September 29, 2026 14:21
@GPRicci
GPRicci marked this pull request as ready for review September 30, 2026 09:15
@GPRicci
GPRicci requested review from a team as code owners September 30, 2026 09:15
Comment thread kernel/safe_typing.ml
in
(kn, eff), senv

let set_constant_def_height kn dh senv =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be done after the fact, but at the very moment the constant body is created, so either from Constant_typing.infer_definition, or if you want to slightly tweak the type pconstant_body so that it's clear the height is empty at this point, somewhere around Safe_typing.add_constant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants