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

Trying to understand behavior of whd under universe polymorphism + primitive projections #756

Open
patrick-nicodemus opened this issue Jan 27, 2025 · 7 comments

Comments

@patrick-nicodemus
Copy link
Contributor

patrick-nicodemus commented Jan 27, 2025

Edit: Gaetan helped me narrow down the cause, see below.

I am wondering if you can help me figure out this strange behavior.
I created a Coq project with no standard library linked in and one of my dependencies is the coq-HoTT library https://github.com/HoTT/Coq-HoTT.

I have slightly different versions of the same code.

From elpi Require Import elpi.
Record A := { p : Type }.
From HoTT Require Overture.
(* Record A := { p : Type }. *)

Elpi Tactic simplify. 
Elpi Accumulate lp:{{
        
    solve (goal _Ctx _Trigger Type _Proof _ as G) GL :-
        coq.say Type,
        whd1 Type Typea,
        refine {{ _ : lp:Typea }} G GL.
}}.

Inductive Unit := tt.
Definition a : A := {| p := Unit |}.
Goal p a.
Proof.
    elpi simplify.

The tactic elpi simplify works in the expected way. However if I define the record after I load the HoTT library (as in the commented line) the tactic fails. Do you have any idea why this might be the case?

@SkySkimmer
Copy link
Collaborator

The global settings in https://github.com/HoTT/Coq-HoTT/blob/master/theories/Basics/Settings.v are possible causes. You can try each instead of the Require to see what happens.

@patrick-nicodemus
Copy link
Contributor Author

@SkySkimmer Thanks very much, that helps a lot.

From elpi Require Import elpi.
Require Import Ltac.
Set Universe Polymorphism.
Set Primitive Projections.
Record A := { p : Type }.
Elpi Tactic simplify. 
Elpi Accumulate lp:{{
        
    solve (goal _Ctx _Trigger Type _Proof _ as G) GL :-
        coq.say Type,
        whd1 Type Typea,
        refine {{ _ : lp:Typea }} G GL.
}}.

Inductive Unit := tt.
Definition a : A := {| p := Unit |}.
Goal p a.
Proof.
    elpi simplify.

These flags both effect the behavior of the code. With just Set Universe Polymorphism, the Elpi representation of p a is

 [pglobal (const «p») «minimize.406», 
  pglobal (const «a») «minimize.406»]

and the whd is match a with | {| p := p0 |} => p0 end.

With both of the flags mentioned above, the Elpi representation of p a is

app [primitive (proj minimize.p 0), pglobal (const «a») «minimize.427»]

and whd doesn't change the term.
So I can see specifically what's causing it but I still don't really understand what's happening here. I did read the Elpi code for whd here but I don't understand what's failing.

@patrick-nicodemus patrick-nicodemus changed the title Importing a library has side effects that mess with Elpi tactics Trying to understand behavior of whd under universe polymorphism + primitive projections Jan 27, 2025
@SkySkimmer
Copy link
Collaborator

p a is already the normal form when p is a primitive projection (assuming you don't want to unfold a)

@patrick-nicodemus
Copy link
Contributor Author

patrick-nicodemus commented Jan 27, 2025

Okay, that makes sense. I can understand that point of view. But, also, if I change the definition of simplify to:

    solve (goal _Ctx _Trigger Type _Proof _ as G) GL :-
        coq.say Type,
        coq.reduction.lazy.whd Type Typea,
        refine {{ _ : lp:Typea }} G GL.

it does simplify p a to Unit. Is this to be expected, or is lazy.whd supposed to have a different behavior?

@gares
Copy link
Contributor

gares commented Jan 27, 2025

You could try to write Elpi Trace Browser. just before calling elpi simplify, ignore the instructions that are printed.
Once elpi simplify terminates in vscode you can open the elpi tracer panel, open /tmp/traced.tmp.json (be sure to disable syntax highlighting in the elpi-lang extension setting).

Sorry, it is a bit clumsy, but should let you see all the steps and pinpoint the problem.

If the above does not work, you can also try Elpi Trace. but the output is plain text, much harder to navigate.

@patrick-nicodemus
Copy link
Contributor Author

@gares Thanks, I get the usage of the browser now.

As I step through the code I see that whd-indc defined for global inductives but there's no analogous clause for polymorphic global inductives. Is this intentional or an oversight?

whd-indc A GR KA :- whd A [] VA C, !, not(var VA), VA = global (indc GR), KA = C.

@gares
Copy link
Contributor

gares commented Jan 28, 2025

An oversight.

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

No branches or pull requests

3 participants