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

Created rewrite tactic #746

Merged
merged 8 commits into from
Jan 23, 2025
Merged

Created rewrite tactic #746

merged 8 commits into from
Jan 23, 2025

Conversation

patrick-nicodemus
Copy link
Contributor

I have created a simple rewriting tactic that Enrico suggested on the Zulip would be a good fit for the eltac repo.

@patrick-nicodemus
Copy link
Contributor Author

Some comments Enrico made on the Zulip:

  • coq.typecheck works for any term, no need to check if Eq is a proof variable or a gref
  • the copy clause needs to be quantified on J
  • nested_forall must exist somewhere, I usually call it "saturate"
  • you should be able to write _ istead of {{ _ }}, holes in Elpi are holes in Coq

I will address these.

@patrick-nicodemus
Copy link
Contributor Author

patrick-nicodemus commented Jan 19, 2025

Okay, comments fixed.
N. b. - I call coq.typecheck Eq' Ty' ok right after coq.saturate to get the type of the term Eq', but it seems like
it might be more efficient to have coq.saturate compute the type of Eq' as it's traversing the chain of nested products.

Copy link
Contributor

@gares gares left a comment

Choose a reason for hiding this comment

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

Thanks for your contribution, please take a look at my comments

Comment on lines 39 to 43
% Eq is a direct Gallina term or a gref and we will infer its type
% from context
coq.typecheck Eq Ty ok;
% Eq is a reference to a declared variable in the context
std.mem Ctx (decl Eq _ Ty)),
Copy link
Contributor

Choose a reason for hiding this comment

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

The LHS of ; should suffice since Ctx is loaded hence you are really running Ctx => coq.typecheck ... and that knows the type of proof variables.

% First, introduce a rule that causes "copy" to act as a function
% sending a type T to the same type, but with all
% subterms of T unifiable with Q to be replaced with a fresh constant x.
pi x\ (pi J\ copy J x :- coq.unify-leq Q J ok) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like a good introduction to the power of copy etc, thanks for providing it.

But this implementation of rewrite is known to be a "bad rewrite" since it is too smart, eg lets you rewrite with commutativity of addition on a goal like 2 * x = .. that has no addition in it. I recommend at least writing a comment about this, or write a more complex line that compares the key verbatim, see for
example

bind-list [app [C| AS] |VS] T R :- key C, !,
pi x\
(pi L X\ bind (app[C|L]) X :- get-option "unif:greedy" tt, unify-list-eq L AS, X = x, !) =>
(pi L X\ bind (app[C|L]) X :- not (get-option "unif:greedy" tt),unify-list-eq L AS, X = x) =>
bind-list VS T (R x).
or the ssreflect section in the Coq manual for keyd matching.

Comment on lines 27 to 29
(fun _ S (a\
fun _ {{ @eq lp:S lp:P lp:Q }} (_\ A a )
))
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
(fun _ S (a\
fun _ {{ @eq lp:S lp:P lp:Q }} (_\ A a )
))
{{ fun a (e : @eq lp:S lp:P lp:Q) => lp:(A a) }}

Also shouldn't Q be a ?

@gares gares merged commit eab6181 into LPCIC:master Jan 23, 2025
71 of 74 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants