Skip to content

Commit ef06ac5

Browse files
authored
Merge pull request #966 from LPCIC/revamp-ltac-API
ltac: API for simple tactics
2 parents 8066ba8 + 8996165 commit ef06ac5

26 files changed

+957
-266
lines changed

.nix/config.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ let master = [
1414
"trakt"
1515
];
1616
rocq-common-bundles = {
17-
rocq-elpi.override.elpi-version = "3.4.2";
17+
rocq-elpi.override.elpi-version = "v3.6.1";
1818
hierarchy-builder.override.version = "master";
1919
rocq-elpi-tests.job = true;
2020
rocq-elpi-tests-stdlib.job = true;
2121
};
2222
coq-common-bundles = listToAttrs (forEach master (p:
2323
{ name = p; value.override.version = "master"; }))
2424
// {
25-
coq-elpi.override.elpi-version = "3.4.2";
25+
coq-elpi.override.elpi-version = "v3.6.1";
2626

2727
mathcomp-boot.job = true;
2828
mathcomp-fingroup.job = true;

Changelog.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Unreleased
22

3+
Requires Elpi 3.6.0 and Rocq 9.0, 9.1 or 9.2.
4+
35
### HOAS:
46
- Fix explicitly declared goals are considered reachable, even if they
57
do not occur in the proof term
@@ -13,6 +15,12 @@
1315
- New `coq.env.section-contents` listing the contents of sections.
1416
- New `coq.ltac.call-mltac` to call code defined via `TACTIC EXTEND` directives
1517
in OCaml.
18+
- New `coq.ltac.call-simple-mltac` for tactics not changing the proof context
19+
- New `coq.ltac.call-simple-ltac1` for tactics not changing the proof context
20+
- Rename `coq.ltac.collect-goals` -> `coq.ltac.collect-sealed-goals`
21+
- New `coq.ltac.collect-simple-goals` for goals in the current proof context
22+
- Change `coq.ltac.call-ltac1` also gives a diagnostic
23+
- Change `coq.ltac.call` also gives a diagnostic
1624

1725
# [3.2.0] 19/09/2025
1826

apps/coercion/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ coercion _ X Ty {{ @sig lp:Ty lp:P }} Solution :- std.do! [
6161
Solution = {{ @exist lp:Ty lp:P lp:X1 _ }},
6262
% we call the solver
6363
coq.ltac.collect-goals Solution [G] [],
64-
coq.ltac.open (coq.ltac.call-ltac1 "my_solver") G [],
64+
coq.ltac.open (x\y\coq.ltac.call-ltac1 "my_solver" x y ok) G [],
6565
].
6666
6767
}}.

apps/coercion/tests/test_open.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ coercion _ X Ty {{ @sig lp:Ty lp:P }} Solution :- std.do! [
1212
Solution = {{ @exist lp:Ty lp:P lp:X1 _ }},
1313
% we call the solver
1414
coq.ltac.collect-goals Solution [G] [],
15-
coq.ltac.open (coq.ltac.call-ltac1 "my_solver") G [],
15+
coq.ltac.open (x\y\coq.ltac.call-ltac1 "my_solver" x y ok) G [],
1616
].
1717

1818
}}.

apps/derive/elpi/eqbcorrect.elpi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ search-eqcorrect-apply (eqb.inductive _ _) [] C R C R.
128128

129129
func run-solver sealed-goal, string ->.
130130
run-solver G Name :-
131-
if (coq.ltac.open (coq.ltac.call Name []) G []) true
131+
if (coq.ltac.open (g\gl\coq.ltac.call Name [] g gl ok) G []) true
132132
((@holes! => coq.sealed-goal->string G SG),
133133
std.fatal-error {calc ( "solver " ^ Name ^ " fails on goal:\n" ^ SG )}).
134134

builtin-doc/coq-builtin.elpi

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,7 +1634,7 @@ kind ltac1-tactic type.
16341634
% Level can be left unspecified and defaults to 0
16351635
external type coq.ltac.fail int -> variadic any (func).
16361636

1637-
% [coq.ltac.collect-goals T Goals ShelvedGoals]
1637+
% [coq.ltac.collect-sealed-goals T Goals ShelvedGoals]
16381638
% Turns the holes in T into Goals.
16391639
% Goals are closed with nablas.
16401640
% ShelvedGoals are goals which can be solved by side effect (they occur
@@ -1643,11 +1643,23 @@ external type coq.ltac.fail int -> variadic any (func).
16431643
% (a
16441644
% fold_left over the terms, letin body comes before the type).
16451645
%
1646-
external func coq.ltac.collect-goals term -> list sealed-goal,
1647-
list sealed-goal.
1646+
external func coq.ltac.collect-sealed-goals term -> list sealed-goal,
1647+
list sealed-goal.
16481648

1649-
% [coq.ltac.call-mltac PluginName BlockName BlockIndex G GL] Calls OCaml
1650-
% code bound via TACTIC EXTEND. For example the
1649+
1650+
func coq.ltac.collect-goals term -> list sealed-goal, list sealed-goal.
1651+
coq.ltac.collect-goals T GA GB :- coq.ltac.collect-sealed-goals T GA GB.
1652+
1653+
1654+
% [coq.ltac.collect-simple-goals T Goals ShelvedGoals] Like
1655+
% coq.ltac.collect-sealed-goals turns the holes in T into
1656+
% Goals but fails if the goals do not live in the current proof context.
1657+
%
1658+
external func coq.ltac.collect-simple-goals term -> list goal,
1659+
list sealed-goal.
1660+
1661+
% [coq.ltac.call-mltac PluginName BlockName BlockIndex G GL Diagnostic]
1662+
% Calls OCaml code bound via TACTIC EXTEND. For example the
16511663
% OCaml code for lia looks like:
16521664
%
16531665
% DECLARE PLUGIN "rocq-runtime.plugins.micromega"
@@ -1665,13 +1677,27 @@ external func coq.ltac.collect-goals term -> list sealed-goal,
16651677
% numbering
16661678
% starts from 0. Also, each block has a name, "Lia" in this case.
16671679
%
1680+
% When the diagnostic is (error Msg), then GL is not set.
1681+
%
16681682
% Supported attributes:
16691683
% - @no-tc! (default false, do not infer typeclasses)
16701684
external func coq.ltac.call-mltac string, string, int,
1671-
goal -> list sealed-goal.
1685+
goal -> list sealed-goal, diagnostic.
16721686

1673-
% [coq.ltac.call-ltac1 Tac G GL] Calls Ltac1 tactic Tac on goal G (passing
1674-
% the arguments of G, see coq.ltac.call for a handy wrapper).
1687+
% [coq.ltac.call-simple-mltac PluginName BlockName BlockIndex G GL
1688+
% Diagnostic] Like coq.ltac.call-mltac but Tac is not allowed to
1689+
% generate new goals GL in different contexts. For example "intro" does
1690+
% not
1691+
% obey this restriction.
1692+
%
1693+
% Supported attributes:
1694+
% - @no-tc! (default false, do not infer typeclasses)
1695+
external func coq.ltac.call-simple-mltac string, string, int,
1696+
goal -> list goal, diagnostic.
1697+
1698+
% [coq.ltac.call-ltac1 Tac G GL ...] Calls Ltac1 tactic Tac on goal G
1699+
% (passing the arguments of G, see coq.ltac.call for a handy wrapper).
1700+
% It accepts one diagnostic argument, defaults to ok if omitted.
16751701
% Tac can either be a string (the tactic name), or a value
16761702
% of type ltac1-tactic, see the tac argument constructor
16771703
% and the ltac_tactic:(...) syntax to pass arguments to
@@ -1681,9 +1707,24 @@ external func coq.ltac.call-mltac string, string, int,
16811707
% "Ltac name := body", it cannot be a builtin one. For example
16821708
% "Ltac myapply x := apply x." lets one call apply by running
16831709
% coq.ltac.call-ltac1 "myapply" G GL.
1710+
%
1711+
% When the diagnostic is (error Msg), then GL is not set.
1712+
%
1713+
% Supported attributes:
1714+
% - @no-tc! (default false, do not infer typeclasses)
1715+
external func coq.ltac.call-ltac1 any, goal -> list sealed-goal,
1716+
diagnostic.. .
1717+
1718+
% [coq.ltac.call-simple-ltac1 Tac G GL Diagnostic] Like coq.ltac.call-ltac1
1719+
% but Tac is not allowed to
1720+
% generate new goals GL in different contexts. For example "intro" does
1721+
% not
1722+
% obey this restriction.
1723+
%
16841724
% Supported attributes:
16851725
% - @no-tc! (default false, do not infer typeclasses)
1686-
external func coq.ltac.call-ltac1 any, goal -> list sealed-goal.
1726+
external func coq.ltac.call-simple-ltac1 any, goal -> list goal,
1727+
diagnostic.
16871728

16881729
% [coq.ltac.id-free? ID G]
16891730
% Fails if ID is already used in G. Note that ids which are taken are

0 commit comments

Comments
 (0)