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_strat stack overflows on trivial goals #17501

Open
JasonGross opened this issue Apr 18, 2023 · 6 comments
Open

rewrite_strat stack overflows on trivial goals #17501

JasonGross opened this issue Apr 18, 2023 · 6 comments
Labels
kind: bug An error, flaw, fault or unintended behaviour. part: rewriting tactics The rewrite, autorewrite, rewrite_strat, and setoid_rewrite tactics.

Comments

@JasonGross
Copy link
Member

JasonGross commented Apr 18, 2023

Description of the problem

Require Import Coq.Setoids.Setoid.

Axiom mul_0_r : forall n : nat, n * 0 = 0.
Local Hint Rewrite mul_0_r : mydb.
Goal forall x, x * 0 = 0.
  intros.
  rewrite_strat (topdown (try (hints mydb))). (* stack overflow *)

What's going on here? I could have sworn that rewrite_strat wasn't this dysfunctional....

Coq Version

8.16

@JasonGross JasonGross added kind: bug An error, flaw, fault or unintended behaviour. part: rewriting tactics The rewrite, autorewrite, rewrite_strat, and setoid_rewrite tactics. labels Apr 18, 2023
@JasonGross JasonGross added this to To Do in autorewrite --> rewrite_strat via automation Apr 18, 2023
@JasonGross
Copy link
Member Author

Seems to have something to do with try.

@SkySkimmer
Copy link
Contributor

topdown @rewstrategy := fix @ident. (choice @rewstrategy (progress (subterms @ident))) ; try @ident
so when the strategy does nothing but doesn't fail it's non terminating
Stack overflow is at least as reasonable as not terminating IMO

@JasonGross
Copy link
Member Author

JasonGross commented Apr 18, 2023

Perhaps, but repeat idtac doesn't loop

Maybe a better definition would be
topdown @rewstrategy := fix @ident. try ((choice (progress @rewstrategy) (progress (subterms @ident))) ; @ident)
?

@SkySkimmer
Copy link
Contributor

repeat idtac doesn't loop because repeat has an implicit progress

A lot of strategies already imply progress IIUC so adding useless progress might not be very efficient. Also the parentheses aren't balanced so I'm not 100% sure what you intend.

@JasonGross
Copy link
Member Author

Parentheses fixed, sorry.

As far as efficiency goes, this is easy fix by making iterated progress a no-op: have the return state of each tactic be | Failure of exn | Id | Success of (progress_kind * new_goal * proof) where progress_kind is either "definitely made progress" or "unknown if progress". Then progress only does something interesting on "unknown if progress", turning it either into "definitely progress made" or Failure. Similarly, try just turns Failure into Id, while sequencing with anything non-Id turns "definitely progress" into "unknown if progress".

But I guess I don't have global vision about whether or not it's better to bake in progress vs try. I lean towards baking in try for anything that looks like a looping construct?

@JasonGross
Copy link
Member Author

I do think the design should make it relatively hard to trigger infinite loops / stack overflows, if feasible. The user never wants to write code that does this, so if we can make more expressions mean something that is not "stack overflow" without needing special cases, that seems better

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: rewriting tactics The rewrite, autorewrite, rewrite_strat, and setoid_rewrite tactics.
Development

No branches or pull requests

2 participants