Skip to content

Reversible coercions#15693

Merged
coqbot-app[bot] merged 4 commits intorocq-prover:masterfrom
gares:reverse-coercions
May 3, 2022
Merged

Reversible coercions#15693
coqbot-app[bot] merged 4 commits intorocq-prover:masterfrom
gares:reverse-coercions

Conversation

@gares
Copy link
Copy Markdown
Member

@gares gares commented Feb 16, 2022

Intro:
This PR implements a feature along the lines of https://arxiv.org/abs/1103.3320 where any term t (even a type) can be elaborated to another term s whenever t ~c~> t' via regular a coercion path c (even of length 0) and t' <~rc~ s via a reversible coercion path rc. Reversible coercions are coercions that are also equipped with canonical inference. The elaboration is obtained by solving the unification problem c t ==?== rc ?s (t' is c t, rc is a canonical projection).

As a result a function f taking a record argument (eg an eqType) can be passed a naked type (eg nat) and be elaborated to f nat_eqType (in this case c has length 0, t' is nat already). In the usual coercion jargon this is Sortclass >-> eqType which cannot be a type theoretic function (you can't match on inhabitants of Type), hence the unification and its hints are defining how this "coercion" is computed.

In the presence of a hierarchy with a diamond (made of left right bottom top), a function can expect the left structure and be passed the an inhabitant of the right structure, since that term can be directly coerced to the bottom structure and enriched back (reverse coerced) to the left one. We try to compute the pushout if it exists, that is, if bottom has a coercion to a simpler structure lower (bottom inherits lower), we don't coerce to lower and enrich back to left (we try to lose as little information as possible via direct coercions).

       top
   /        \
left      right
  \          /
     bottom
      |
     lower

TODO:

  • fix the trace: add a constructor that means (fun _ => the_new_term)
  • attribute syntax, then filter the reverse path search using only allowed (flagged as reverse) coercions
  • tests for parameters
  • doc
  • changelog

MAYBE another PR:

  • interleave regular coercions and reverse coercions as in (x : R) >-> S <~< T to enrich x to T lowering it down first to S.

Overlays to be merged after the PR

Overlays to be merged before the PR

Overlays to be merged in sync with the PR

CC @CohenCyril @pi8027 @SkySkimmer

@SkySkimmer
Copy link
Copy Markdown
Contributor

@coqbot-app
Copy link
Copy Markdown
Contributor

coqbot-app bot commented Feb 16, 2022

🔴 CI failure at commit 246cc44 without any failure in the test-suite

✔️ Corresponding job for the base commit 3786a4a succeeded

❔ Ask me to try to extract a minimal test case that can be added to the test-suite

🏃 @coqbot ci minimize will minimize the following target: ci-elpi
  • You can also pass me a specific list of targets to minimize as arguments.

@SkySkimmer
Copy link
Copy Markdown
Contributor

Quite high compatibility (elpi is testing the absence of this feature)

@coqbot-app
Copy link
Copy Markdown
Contributor

coqbot-app bot commented Feb 17, 2022

🔴 CI failure at commit 246cc44 without any failure in the test-suite

✔️ Corresponding job for the base commit 3786a4a succeeded

❔ Ask me to try to extract a minimal test case that can be added to the test-suite

🏃 @coqbot ci minimize will minimize the following target: ci-elpi
  • You can also pass me a specific list of targets to minimize as arguments.

@gares
Copy link
Copy Markdown
Member Author

gares commented Feb 17, 2022

The bench is noise, indeed we cover a case which was a hard failure in developments with no ltac proof search.

@gares gares force-pushed the reverse-coercions branch from 4647a9c to 06afcfd Compare February 17, 2022 12:48
Comment on lines +600 to +607
(* XXX this order relation is not total ... *)
let r = List.sort (fun c1 c2 -> if ClTypSet.mem c1 (reachable_from c2) then 1 else -1) r in
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@pi8027 do you know what happens if List.sort is given an "non order" relation (like this one, which is not total and not anti-symmetric)?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There is a stable_sort close to sort https://ocaml.org/api/List.html#VALsort so List.sort may or may not be stable, that's unspecified.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

In some sense, if it returns a permutation of the input given a random relation, it is still ok, if it asserts false... it is not

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That should be fine (the above doc doesn't expect a total order, any preorder is fine).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

And looking at the current implementation, it cannot throw an exception https://github.com/ocaml/ocaml/blob/trunk/stdlib/list.ml#L320

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There is a stable_sort close to sort https://ocaml.org/api/List.html#VALsort so List.sort may or may not be stable, that's unspecified.

@proux01 Well if we start trusting implementations rather than specifications now, we see that sort = stable_sort... 😆

@gares
Copy link
Copy Markdown
Member Author

gares commented Feb 17, 2022

@charguer this PR also makes your example in this discourse post by declaring a default canonical structure (the eta expansion of the record) (plus the magic done here).

Comment on lines +28 to +39

(* Above, it would be nice to write [eapply (T A)], or just [eapply T].
For that, we'd need to coerce [A:Type] to the type [IType]
by applying on-the-fly the operation [IType_make A _]. Thus, we need something like:
[Coercion (fun (A:Type) => IType_make A _) : Sortclass >-> IType.]
Would that be possible?

I understand that [IType_type] is already a reverse coercion from [IType] to [Type],
but I don't see why it would necessarily cause trouble to have cycles
in the coercion graphs. *)


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can remove this part of the test file :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

(FTR, you can push to this branch on my GH space)

Comment on lines +11 to +12

Arguments IType_make IType_type {IType_inhab}.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is unnecessary

@gares
Copy link
Copy Markdown
Member Author

gares commented Feb 17, 2022

I broke this test Check (nat : Type) : Set. which now passes but should not.
Maybe we manage to coerce Type -> Set since the class is the same and now we consider identity coercions from a type to itself as a path?

@gares
Copy link
Copy Markdown
Member Author

gares commented Feb 17, 2022

And we broke mathcomp, but I did not investigate why.

@CohenCyril
Copy link
Copy Markdown
Contributor

And we broke mathcomp, but I did not investigate why.

actually... the test suite is broken ;)

@gares
Copy link
Copy Markdown
Member Author

gares commented Feb 18, 2022

This last commit is the fix I had initially in mind. It just avoids to use reverse coercions if the two endpoints are the same

@coqbot-app
Copy link
Copy Markdown
Contributor

coqbot-app bot commented Feb 18, 2022

🔴 CI failure at commit 1ff839b without any failure in the test-suite

✔️ Corresponding job for the base commit dc5e355 succeeded

❔ Ask me to try to extract a minimal test case that can be added to the test-suite

🏃 @coqbot ci minimize will minimize the following target: ci-elpi
  • You can also pass me a specific list of targets to minimize as arguments.

@gares
Copy link
Copy Markdown
Member Author

gares commented Feb 18, 2022

We re back on track, maybe you can play a bit more with mathcomp to test this better?

@coqbot-app
Copy link
Copy Markdown
Contributor

coqbot-app bot commented Feb 18, 2022

🔴 CI failure at commit 1ff839b without any failure in the test-suite

✔️ Corresponding job for the base commit dc5e355 succeeded

❔ Ask me to try to extract a minimal test case that can be added to the test-suite

🏃 @coqbot ci minimize will minimize the following target: ci-elpi
  • You can also pass me a specific list of targets to minimize as arguments.

@CohenCyril
Copy link
Copy Markdown
Contributor

We re back on track, maybe you can play a bit more with mathcomp to test this better?

Sure, I'd like to play a bit with mathcomp on HB & categories on HB actually... but I'm struggling to compile coq-elpi on my computer 😢

@gares
Copy link
Copy Markdown
Member Author

gares commented Feb 21, 2022

Hum, the PR was just accepted in nixpkgs. For coq-elpi master you need a new elpi

@CohenCyril
Copy link
Copy Markdown
Contributor

For coq-elpi master you need a new elpi

Which one?

@gares
Copy link
Copy Markdown
Member Author

gares commented Feb 21, 2022

1.14.x (it should be the default on nix as well since that PR)

@CohenCyril
Copy link
Copy Markdown
Contributor

CohenCyril commented Feb 22, 2022

Do you know what I am doing wrong?

File "src/coq_elpi_vernacular.ml", line 767, characters 8-36:
767 |     try ComExtraDeps.query_extra_dep id
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: Unbound module ComExtraDeps
make[1]: *** [Makefile.coq:735: src/coq_elpi_vernacular.cmo] Error 2
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:38: build] Error 2

@gares
Copy link
Copy Markdown
Member Author

gares commented Feb 22, 2022

you are using the coq-master branch of coq elpi against coq 8.15 I guess

@gares
Copy link
Copy Markdown
Member Author

gares commented Feb 23, 2022

No, the problem is that elpi-master moved because of a PR, but this branch was not rebased. I'm doing it now

@gares gares force-pushed the reverse-coercions branch 2 times, most recently from 481345b to 1a29053 Compare February 23, 2022 09:06
gares added a commit to gares/hierarchy-builder that referenced this pull request Feb 23, 2022
@gares gares added the kind: feature New user-facing feature request or implementation. label Feb 23, 2022
@gares gares added this to the 8.16+rc1 milestone Feb 23, 2022
gares added a commit to gares/hierarchy-builder that referenced this pull request Apr 28, 2022
@gares gares force-pushed the reverse-coercions branch from 516cef9 to 5cf4262 Compare April 28, 2022 12:07
@gares
Copy link
Copy Markdown
Member Author

gares commented Apr 28, 2022

rebased together with the overlay

@gares
Copy link
Copy Markdown
Member Author

gares commented Apr 29, 2022

ping

@ppedrot
Copy link
Copy Markdown
Member

ppedrot commented Apr 29, 2022

You should probably ping @mattam82 directly. If he doesn't answer soon, I can take over if needed. It's just a matter of merging it so...

@gares
Copy link
Copy Markdown
Member Author

gares commented May 2, 2022

ping @mattam82 @ppedrot

@ppedrot ppedrot self-assigned this May 2, 2022
@ppedrot
Copy link
Copy Markdown
Member

ppedrot commented May 2, 2022

@gares OK, I'm taking over, but before merging I'll wait for the doc tweaks.

@mattam82
Copy link
Copy Markdown
Member

mattam82 commented May 2, 2022

@ppedrot I was waiting for the doc changes as well, so whoever comes first when they're here can merge :)

@gares
Copy link
Copy Markdown
Member Author

gares commented May 2, 2022

I'm fine with the changes but I won't be able to work on them today, not tomorrow. @CohenCyril @proux01 if you could step in for that last change...

@proux01 proux01 force-pushed the reverse-coercions branch from 5cf4262 to 306c320 Compare May 2, 2022 21:15
@gares
Copy link
Copy Markdown
Member Author

gares commented May 3, 2022

Thanks

@ppedrot
Copy link
Copy Markdown
Member

ppedrot commented May 3, 2022

@coqbot merge now

@coqbot-app
Copy link
Copy Markdown
Contributor

coqbot-app bot commented May 3, 2022

@ppedrot: You can't merge the PR because it hasn't been approved yet.

@ppedrot
Copy link
Copy Markdown
Member

ppedrot commented May 3, 2022

@coqbot merge now

@coqbot-app coqbot-app bot merged commit b2750f9 into rocq-prover:master May 3, 2022
@coqbot-app
Copy link
Copy Markdown
Contributor

coqbot-app bot commented May 3, 2022

@ppedrot: Please take care of the following overlays:

  • 15693-gares-reverse-coercions.sh

gares added a commit to LPCIC/coq-elpi that referenced this pull request May 3, 2022
bors bot added a commit to Mtac2/Mtac2 that referenced this pull request May 3, 2022
356: Adapt to rocq-prover/rocq#15693 r=Janno a=proux01

To be merged in sync with the upstream PR rocq-prover/rocq#15693

Co-authored-by: Pierre Roux <pierre@roux01.fr>
bors bot added a commit to Mtac2/Mtac2 that referenced this pull request May 3, 2022
356: Adapt to rocq-prover/rocq#15693 r=Janno a=proux01

To be merged in sync with the upstream PR rocq-prover/rocq#15693

Co-authored-by: Pierre Roux <pierre@roux01.fr>
Janno pushed a commit to Mtac2/Mtac2 that referenced this pull request May 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind: feature New user-facing feature request or implementation. part: coercions The coercion mechanism.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants