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

Minimize the set of multiple inheritance (coercion) paths to check for conversion #13909

Merged
merged 2 commits into from Mar 25, 2021

Conversation

pi8027
Copy link
Contributor

@pi8027 pi8027 commented Mar 7, 2021

The coercion mechanism reports a pair of inheritance paths sharing the same source and target classes (hereinafter a diamond) as ambiguous paths if they are inconvertible, to let the user ensure the coherence of the inheritance graph. In general, we do not necessarily have to check all the diamonds in an inheritance graph to verify its coherence. For example, it is sufficient to check two (small) diamonds ([f1; g2], [g1, f2]) and ([f2; h2], [h1; f3]) in the following diagram, since commutations of other (large) diamonds can be deduced from those of small ones using basic equational reasoning. In practice, not checking such large diamonds may reduce the number of ambiguous path warnings.

     /\
    /  \
f1 /    \ g1
  /      \
 /        \
 \        /\
  \   f2 /  \
g2 \    /    \ h1
    \  /      \
     \/        \
      \        /
       \      /
     h2 \    / f3
         \  /
          \/

This PR implements the most general way to do such reduction I could find, which is proved correct in the sense that the inheritance graph is coherent if Coq does not report any ambiguous path. (I also have a draft paper briefly explain this, which I think I can partially share if needed.) To check if a diamond is reducible or not, the table of coercion classes (class_tab) has been extended with:

  1. the two sets of coercion classes reachable from (cl_reachable_from) and to (cl_reachable_to) the class, respectively, and
  2. the representative element of the strongly connected component including the class (cl_repr).

(I will add more explanations later depending on what reviewers request. Let me run CI first.)

Kind: enhancement.

  • Added / updated test-suite

@pi8027 pi8027 added kind: enhancement Enhancement to an existing user-facing feature, tactic, etc. part: coercions The coercion mechanism. labels Mar 7, 2021
@pi8027 pi8027 requested a review from a team as a code owner March 7, 2021 02:31
@pi8027
Copy link
Contributor Author

pi8027 commented Mar 7, 2021

BTW, I still do not understand the following things in coercionops.ml:

  • Bijint and cl_index are really needed? Replacing them with ClTypMap and cl_typ would work and simplify the implementation. (I believe there is no performance issue here. Another potential issue would be that the printing order of Print Graph will change.)
  • A circular inheritance path of C >-> C can be registered to inheritance_graph only if different_class_params holds for C. What are the use cases of this?

@gares
Copy link
Member

gares commented Mar 7, 2021

Bijint and cl_index are really needed? Replacing them with ClTypMap and cl_typ would work and simplify the implementation. (I believe there is no performance issue here. Another potential issue would be that the printing order of Print Graph will change.)

I'm OK with that. BTW, if you are going to refactor the code, in spite of #13902 being merged, I still don't have an API that given a GlobRef.t tells me the number of parameters and the src/tgt classes. Would you mind making it possible? (adding the missing fields to coe_info_typ should suffice)

A circular inheritance path of C >-> C can be registered to inheritance_graph only if different_class_params holds for C. What are the use cases of this?

If I'm not mistake these are not "loops" but rather a form of "identity coercions": indexing looking just at the head constant is too simplistic.

@pi8027
Copy link
Contributor Author

pi8027 commented Mar 8, 2021

Bijint and cl_index are really needed? Replacing them with ClTypMap and cl_typ would work and simplify the implementation. (I believe there is no performance issue here. Another potential issue would be that the printing order of Print Graph will change.)

I'm OK with that. BTW, if you are going to refactor the code, in spite of #13902 being merged, I still don't have an API that given a GlobRef.t tells me the number of parameters and the src/tgt classes. Would you mind making it possible? (adding the missing fields to coe_info_typ should suffice)

Sure. I will do that first and then redo this PR on top of it.

A circular inheritance path of C >-> C can be registered to inheritance_graph only if different_class_params holds for C. What are the use cases of this?

If I'm not mistake these are not "loops" but rather a form of "identity coercions": indexing looking just at the head constant is too simplistic.

I don't think so. In the following condition, different_class_params env i is relevant only if the source class i is equal to the target class j. If it is an identity coercion, the source class should be a constant that unfolds to the target class applied to some arguments; thus, they are not the same, as you said.

if not (Bijint.Index.equal i j) || different_class_params env i then

@pi8027 pi8027 mentioned this pull request Mar 8, 2021
2 tasks
@pi8027 pi8027 marked this pull request as draft March 8, 2021 12:17
@gares
Copy link
Member

gares commented Mar 10, 2021

I think you can nor rebase on top of the refactoring PR which was merged

The table of coercion classes (`class_tab`) has been extended with information
about reachability. The conversion checking of a pair of multiple inheritance
paths (of coercions) will be skipped if these paths can be reduced to smaller
adjoining pairs of multiple inheritance paths, and this reduction will be
determined based on that reachability information.
@pi8027 pi8027 marked this pull request as ready for review March 12, 2021 17:18
@pi8027
Copy link
Contributor Author

pi8027 commented Mar 19, 2021

I don't think I have to update the reference manual in accordance with this change. So this PR is ready for review.

@gares
Copy link
Member

gares commented Mar 25, 2021

@pi8027 can you take of the request by @SkySkimmer ? Otherwise this seems ready to me.

@pi8027
Copy link
Contributor Author

pi8027 commented Mar 25, 2021

Yes. I will do that by the end of this week.

@gares
Copy link
Member

gares commented Mar 25, 2021

@coqbot merge now

@coqbot-app
Copy link
Contributor

coqbot-app bot commented Mar 25, 2021

@gares: You can't merge the PR because you're not among the assignees and no milestone is set.

@gares gares self-assigned this Mar 25, 2021
@gares gares added this to the 8.14+rc1 milestone Mar 25, 2021
@gares
Copy link
Member

gares commented Mar 25, 2021

@coqbot merge now

@coqbot-app coqbot-app bot merged commit d1194d6 into coq:master Mar 25, 2021
@pi8027 pi8027 deleted the reduce-ambiguous-paths branch March 26, 2021 04:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: enhancement Enhancement to an existing user-facing feature, tactic, etc. part: coercions The coercion mechanism.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants