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

IsPositionalObjectRep and IsComponentObjectRep are not consistently set #1043

Open
fingolfin opened this issue Dec 28, 2016 · 3 comments
Open
Labels
kind: bug Issues describing general bugs, and PRs fixing them

Comments

@fingolfin
Copy link
Member

fingolfin commented Dec 28, 2016

(This is taken from issue #897)

Many representation for positional respectively component representations do now have the IsPositionalObjectRep respectively IsComponentObjectRep filters set. This can lead to surprising behavior and bugs, see e.g. issue #897. According to @markuspf this affects at least these representations in the library (and more in packages):

  • IsSyllableAssocWordRep
  • IsLetterAssocWordRep
  • IsBLetterAssocWordRep
  • IsWLetterAssocWordRep
  • IsPermGroupGeneralMapping
  • IsSubgroupOfWholeGroupByQuotientRep
  • IsGenericCharacterTableRep
  • IsNullMapMatrix
  • IsDefaultGeneralMappingRep
  • IsInverseGeneralMappingRep
  • IsMemberPcSeriesPermGroup
  • IsSlicedPerm
  • IsSlicedPermInv
  • IsFromTheLeftCollectorRep
  • IsGroupClassByListRep
  • IsNilpotentLieAutomorphismRep

(Found by filtering AllRepresentations() by not having any of the four Reps above in their IMPL_FLAGS, AllRepresentations() being a function @markuspf added to the library).

I was bitten by this yesterday, as polycyclic's IsFromTheLeftCollectorRep suffers from the same problem (and thus a collector was shown to use 300 bytes of RAM when it really are 300,000 bytes...)

So all in all, it seems that IsPositionalObjectRep serves no useful purpose, other than perhaps to increase some ranks a little bit. It is not well-documented either: entering ?IsPositionalObjectRep gives nothing, though it is mentioned in section 79.11 "Positional Objects".

So, what to do? Some random ideas (without consideration how easy and/or efficient it would be to implement them)

  1. Change GAP to automatically add set IsInternalRep, IsPositionalObjectRep, IsComponentObjectRep, IsDataObjectRep for objects based on their TNUMs.
  2. Change NewRepresentation to enforce that every newly declared representation sets one of the four representation types
  3. Phase out those four types as filters, instead use IS_COMOBJ, IS_POSOBJ, IS_DATOBJ in code that really has to act based on the representation kind.
  4. A combination of the above.
  5. ... other ideas?

Idea 1 might work by hooking into Objectify resp. SetTypeObj, which already has to look at the object in order to invoke SET_TYPE_POSOBJ or SET_TYPE_COMOBJ. So adding in the correct filters would be doable there. Some caveats: This would change some filter ranks and could thus lead to some indirect breakage (arguably caused by unsafe reliance on certain relative filter ranks, but breakage nevertheless).
Moreover, this could require creating a new type object on the fly (?), again and again, which is inefficient.

Approach 2 would help to avoid that inefficiency, by inspecting the (currently unused, see issue #1042) slots argument to NewRepresentation. Alas, that does not always work, and since the argument has been unused so far, it is quite likely that somebody used it incorrectly, and thus this heuristic will fail :-(.

Approach 3 avoids all that mucking around with filters, and is fast and reliable. However, it would not allow for method dispatch. But then, I think few (if any things) rely on that with the exception perhaps of some very special things like MemoryUsage (a notable exception here is IsFFE and IsInternalRep which is used quite a bit in the library).

We could also combine these, say do approach 1, but instead of changing the type, print an InfoWarning to help us track down incorrect representation declarations and fix them. Or print the warning and change the type. Etc.

@frankluebeck
Copy link
Member

The representations IsPositionalObjectRep do occur in the documentation, try for example ?Representation or ?NewRepresentation. It would be good to add some <Index> elements to the documentation.

In view of the documentation I would consider representation declarations which do not imply one of the four mentioned representations a bug. I would vote for a check when a representation is declared and to raise an error, if none of the four base representations is implied.

@stevelinton
Copy link
Contributor

I'd support Frank's proposal. All representations should imply exactly one of the four base representations.

@fingolfin
Copy link
Member Author

fingolfin commented Aug 1, 2022

In my original issue description, I referred to a library function AllRepresentations, but I can't find any trace of that?!? Anyway, here is how one can compute a list of offending representations:

reps:=FILTERS{Filtered(CATS_AND_REPS,i->INFO_FILTERS[i] in FNUM_REPS)};;
badreps:=Filtered(reps,r->not IS_IMPLIED_BY(IsComponentObjectRep,r) and not IS_IMPLIED_BY(IsPositionalObjectRep,r) and not IS_IMPLIED_BY(IsDataObjectRep,r) and not IS_IMPLIED_BY(IsInternalRep,r));
for r in Set(badreps,NAME_FUNC) do Print("- `",r,"`\n"); od;

The result as of right now, after LoadAllPackages() (but with a few packages missing on my system):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug Issues describing general bugs, and PRs fixing them
Projects
None yet
Development

No branches or pull requests

3 participants