Skip to content

Add Constr.map_with_full_binders to Ltac2#22062

Open
JasonGross wants to merge 2 commits into
rocq-prover:masterfrom
JasonGross:ltac2-map-with-binders
Open

Add Constr.map_with_full_binders to Ltac2#22062
JasonGross wants to merge 2 commits into
rocq-prover:masterfrom
JasonGross:ltac2-map-with-binders

Conversation

@JasonGross

@JasonGross JasonGross commented May 23, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds Constr.map_with_full_binders to Ltac2, which maps a function f on the immediate subterms of a constr, using in_context / in_context_letin to traverse under binders so that f operates on well-typed terms in proper contexts
  • For Fix/CoFix, all mutual binders are opened (via nested in_context calls) before processing each body
  • The function is not recursive; the caller controls recursion by passing a recursive f

Named to match the OCaml-side map_constr_with_full_binders (in termops.ml), which similarly provides the full binder context rather than just a de Bruijn shift like Constr.map_with_binders.

Stacked on #22060 (Constr.in_context_prod and Constr.in_context_letin).

Signature

Ltac2 map_with_full_binders (f : constr -> constr) (c : constr) : constr

Behavior

For each constructor kind:

  • Lambda/Prod: applies f to the binder type, uses in_context to open the binder, applies f to the body, then rebuilds
  • LetIn: applies f to type and value, uses in_context_letin to open the binder, applies f to the body, then rebuilds
  • Fix/CoFix: applies f to each binder type, then for each body opens all mutual binders via nested in_context calls, applies f, strips the lambda wrappers, and rebuilds
  • App, Cast, Case, Proj, Array: applies f to each sub-constr
  • Rel, Var, Meta, Evar, Sort, Constant, Ind, Constructor, Uint63, Float, String: returned unchanged

This is analogous to the existing Constr.Unsafe.map but uses in_context to ensure f sees well-typed terms with proper binder scoping, rather than operating on raw de Bruijn terms.

Test plan

  • Added test-suite/ltac2/map_with_full_binders.v with tests for identity mapping and transformations through Lambda, Prod, LetIn, App, and Fix

🤖 Generated with Claude Code

@JasonGross JasonGross requested a review from a team as a code owner May 23, 2026 21:30
@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 May 23, 2026
@JasonGross JasonGross changed the title Add Constr.map_with_binders to Ltac2 Add Constr.map_in_context to Ltac2 May 23, 2026
@JasonGross JasonGross force-pushed the ltac2-map-with-binders branch from ae36c10 to c84f772 Compare May 23, 2026 23:37
@JasonGross JasonGross added request: full CI Use this label when you want your next push to trigger a full CI. part: ltac2 Issues and PRs related to the (in development) Ltac2 tactic langauge. kind: enhancement Enhancement to an existing user-facing feature, tactic, etc. and removed needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. labels May 25, 2026
JasonGross and others added 2 commits May 27, 2026 21:02
Add a new Unsafe.in_context primitive that extends the proof context
with either a LocalAssum (when body_opt is None) or LocalDef (when
body_opt is Some) and returns a (binder, body) pair.

Three Ltac2 wrappers use this primitive:
- in_context: wraps the result in Lambda (same behavior as the old external)
- in_context_prod: wraps the result in Prod
- in_context_letin: wraps the result in LetIn

The old constr_in_context external is kept for backward compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ers to Ltac2

Unsafe.map_with_full_binders maps a function on the immediate subterms of a
constr, using Unsafe.in_context to traverse under binders so that the
mapped function operates on well-typed terms in proper contexts.

The safe Constr.map_with_full_binders wrapper checks the result with
Unsafe.check and raises on failure.

Since Unsafe.in_context returns (binder, body) directly, there is no
need for strip_lambda/strip_prod/strip_letin helpers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@JasonGross JasonGross force-pushed the ltac2-map-with-binders branch from c84f772 to 75011a8 Compare May 27, 2026 21:02
@coqbot-app coqbot-app Bot removed the request: full CI Use this label when you want your next push to trigger a full CI. label May 27, 2026
@JasonGross JasonGross changed the title Add Constr.map_in_context to Ltac2 Add Constr.map_with_full_binders to Ltac2 May 27, 2026
@SkySkimmer SkySkimmer added the needs: discussion Further discussion is needed. label Jun 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind: enhancement Enhancement to an existing user-facing feature, tactic, etc. needs: discussion Further discussion is needed. part: ltac2 Issues and PRs related to the (in development) Ltac2 tactic langauge.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants