Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite does not find seeming exact match with primitive projections #18871

Open
andres-erbsen opened this issue Mar 30, 2024 · 5 comments
Open
Labels
kind: bug An error, flaw, fault or unintended behaviour. part: primitive records The primitive record and primitive projection mechanism. part: rewriting tactics The rewrite, autorewrite, rewrite_strat, and setoid_rewrite tactics. wellknown: unfolded primitive projections

Comments

@andres-erbsen
Copy link
Contributor

andres-erbsen commented Mar 30, 2024

Description of the problem

I got curious what the situation with primitive projections is like these days, so I tried out what it would be like to use this feature for pairs. In Ascii.v I hit what looks like a real footgun. A match-goal-with calling rewrite with the matched term then has the rewrite fail to find that term in the goal, and manually performing the same invocation of rewrite fails similarly. Almost 2/3 of stdlib (by cloc) still builds, though.

Small Coq file to illustrate the bug

match goal with
| [ |- context[(fst ?x, snd ?x)] ] =>
   rewrite <-(surjective_pairing x)
end. (* fails *)

Cherry-pick the linked commit for actual repro.

Version of Coq where this bug occurs

632031c

Last version of Coq where the bug did not occur

No response

@andres-erbsen andres-erbsen added part: primitive records The primitive record and primitive projection mechanism. kind: bug An error, flaw, fault or unintended behaviour. needs: triage The validity of this issue needs to be checked, or the issue itself updated. part: rewriting tactics The rewrite, autorewrite, rewrite_strat, and setoid_rewrite tactics. labels Mar 30, 2024
@SkySkimmer
Copy link
Contributor

SkySkimmer commented Apr 5, 2024

Classic unfolded vs folded primitive projection issue

Set Primitive Projections.

Record prod A B := pair { fst  :A ; snd : B }.
Arguments pair {_ _}.
Arguments fst {_ _}.
Arguments snd {_ _}.

Lemma surjective_pairing {A B} (p:prod A B) : p = pair (fst p) (snd p).
Proof. reflexivity. Qed.

Lemma surjective_pairing' {A B} (p:prod A B) : p = pair (fst p) (snd p).
Proof.
  cbv.
  Set Printing Unfolded Projection As Match.
  (* |- p = {| fst := let '{| fst := fst |} := p in fst; snd := let '{| snd := snd |} := p in snd |} *)
  match goal with
    |- context[pair (fst ?x) (snd ?x)] =>
      rewrite <-(surjective_pairing x)
  end.
  (* Found no subterm matching "{| fst := fst p; snd := snd p |}" in the current goal. *)

@SkySkimmer
Copy link
Contributor

cc @rlepigre @Janno

@andres-erbsen
Copy link
Contributor Author

Thank you for the triage. Let's create a well-known tag for it, maybe wellknown: unfolded primitive projections break tactics?

Also might be worth documenting Set Printing Unfolded Projection As Match, I had missed it so far and it seems like exactly the right tool to troubleshoot this kind of issues. Do you know what PR added it?

@SkySkimmer
Copy link
Contributor

It was added in #16994

@andres-erbsen
Copy link
Contributor Author

And I even commented, and there is documentation -- just without "Set" in front of the option name, evading my misguided search. 👍

@andres-erbsen andres-erbsen added wellknown: unfolded primitive projections and removed needs: triage The validity of this issue needs to be checked, or the issue itself updated. labels Apr 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug An error, flaw, fault or unintended behaviour. part: primitive records The primitive record and primitive projection mechanism. part: rewriting tactics The rewrite, autorewrite, rewrite_strat, and setoid_rewrite tactics. wellknown: unfolded primitive projections
Projects
None yet
Development

No branches or pull requests

2 participants