-
-
Notifications
You must be signed in to change notification settings - Fork 702
Fix FinitelyPresentedGroupElement.__hash__ #41173
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
base: develop
Are you sure you want to change the base?
Conversation
5a62283 to
b6de2f9
Compare
|
It still cause timeout issues |
|
Maybe the serve is down. We may skip the tests? |
|
The ouput is correct |
| raise ValueError('the values do not satisfy all relations of the group') | ||
| return super().__call__(values) | ||
|
|
||
| def _normal_form_by_gap_nffunction(self) -> GapElement: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a hidden method? It makes more sense to me for this to be public.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we guarantee the method is implemented by GAP?
Is NFFunction even publicly documented API in GAP, if so, what is its behavior?
Better be safe.
| determined only by the value of this group element, | ||
| and not the Tietze list. | ||
| TESTS:: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should add some actual examples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as above. It seems dangerous to promise behavior of this while the underlying gap function is undocumented.
| Prefer to use ``libgap(k)`` for consistency. | ||
| The returned object should not be mutated, otherwise with the current implementation, | ||
| ``self`` will be mutated as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Prefer to use ``libgap(k)`` for consistency. | |
| The returned object should not be mutated, otherwise with the current implementation, | |
| ``self`` will be mutated as well. |
I don't see the point of this; please remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove what?
- the recommendation to use
libgap()? - the
_libgap_hook? - the whole method?
it's true that the external user interface is really meant to be libgap(...) though (instead of x._libgap_() or x.gap(), note that the last one doesn't work on almost all types, while libgap(...) works on almost all types. See also #39905 #39909)
| try: | ||
| self._gap.MakeConfluent() | ||
| except ValueError: | ||
| raise ValueError('could not make the system confluent') | ||
| self._gap.MakeConfluent() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please explain this change. It seems like it is making the error message more understandable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MakeConfluent is a GAP-wrapped function and can only ever raise GAPError or (if the user interrupt it) KeyboardInterrupt or AlarmInterrupt. ValueError is never raised.
| elif len(r.Tietze()) == 2: | ||
| a = all_edges[G([r.Tietze()[0]])] | ||
| b = all_edges[G([r.Tietze()[1]])] | ||
| a = all_edges[F([r.Tietze()[0]])] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be very surprising to have elements in the free group instead of the FPG. This change needs much more justification, both here and in the documentation if deemed reasonable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all_edges is a local variable, it's not visible outside. What matters is the simplicial set structure.
edit: thinking about it again maybe the result are visible somewhere in the simplicial set structure (need double check), but either way, what matters is the simplicial set structure.
Co-authored-by: Travis Scrimshaw <[email protected]>
|
I really don't understand why the problem that was meant to be addressed by this PR is not fixed properly, by converting the group into a permutation group to begin with, as I explained on the predecessor to this PR. Instead there is some fishy code calling undocumented GAP functions. Which might break, change behaviour, etc. |
dimpase
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please address the original problem, and do not use undocumented 3rd party code.
|
@dimpase the surface level problem is Cayley graph construction is incorrect. The underlying problem is What do you propose to do with |
|
Construction of the Cayley graph of a permutation group is trivial. I really don't see why anyone would want to mess around with words. |
|
computing the canonical form of an element in an f.p. group is in general algorithmically unsolvable, and is solvable, but still rather tricky, for finite groups, and some classes of infinite groups. I don't mind if hash returns not implemented for f.p. groups. |
|
The current situation is:
The proposals are:
Am I summarizing the situation correctly? @dimpase |
|
I find it rather unconvincing that the undocumented GAP function does the job you claim it does. Looking at its description in the source code, and the fact it's merely a helper in the documented GAP function "47.3-4 SetReducedMultiplication", it seems it's just a heuristic to speed up multiplication of words in an f.p. group. |
|
I am speaking on this topic not as an amateur in the area, but as someone with a PhD in group theory, as someone who published ~20 papers where computations with f.p. groups played a significant role. And the main message I am trying to get through is that if you want to do anything with an f.p. group which is not of a very special type, your best and the only bet is to convert it to a group where you can efficiently test words in generators for equality: a permutation group, a matrix group, etc. It's meaningless to talk about hash properties for elements x,y of an arbitrary f.p. group, as the question of whether x==y is algorithmically unsolvable. |
Replacement for #40563. Fix #40549
Note that
FpElementNFFunctionis what GAP uses internally for==Sometimes
==works better thanconfluent_rewriting_system. (Although I don't dare to include this as a test, otherwise upgrade to GAP that selects a different algorithm may randomly timeout the test)Sometimes not. But gap appears to use some sort of caching system, so it might work anyway.
When one compute one
confluent_rewriting_systemand onehashbefore the==, it finishes quickly.📝 Checklist
⌛ Dependencies