Skip to content

Objectify: warn if Is{Component,Positional}ObjectRep absent - #4964

Draft
fingolfin wants to merge 2 commits into
gap-system:masterfrom
fingolfin:mh/force-pos-or-com-objrep
Draft

Objectify: warn if Is{Component,Positional}ObjectRep absent#4964
fingolfin wants to merge 2 commits into
gap-system:masterfrom
fingolfin:mh/force-pos-or-com-objrep

Conversation

@fingolfin

Copy link
Copy Markdown
Member

This works towards resolving #1043: now Objectify warns if IsPositionalObjectRep resp. IsComponentObjectRep is not set for an object that should have one of them; and it also gives an error if both are set / "the wrong one" is set (i.e. IsPositionalObjectRep for a T_COMOBJ or IsComponentObjectRep for a T_POSOBJ).

I've eliminated all the warnings triggered by loading GAP and running tst/testinstall.g, and submitted gap-packages/fr#50 to fix one violation in a package (I've already fixed a bunch of others in packages in the past couple years). I am guessing there may still be a couple more, so I am reluctant to turn the warnings into an error just now... at the very least, before we attempt such a thing, the test suites of all packages should be run against a GAP with that error activated.

Also, before merging this PR we should check how this extra test affects performance: Objectify is a bit of a bottleneck, and we don't want to make it worse than it already is...

@fingolfin

Copy link
Copy Markdown
Member Author

Hmm, thinking about it, I am not even sure why to warn -- instead we could just add that flag? Perhaps for performance reasons: a missing flag that has to be added in requires us to create a new sub-type...

@fingolfin fingolfin closed this Mar 15, 2024
@fingolfin fingolfin reopened this Mar 15, 2024
@fingolfin fingolfin closed this Oct 25, 2024
@fingolfin fingolfin reopened this Oct 25, 2024
Comment thread lib/type1.g
Comment on lines +605 to +606
#Assert(0, IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsPositionalObjectRep)));
Assert(0, not IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsComponentObjectRep)));

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.

Maybe disable this by default, but have it enabled e.g. in most test suites (as long as the use START_TEST)?

Suggested change
#Assert(0, IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsPositionalObjectRep)));
Assert(0, not IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsComponentObjectRep)));
#Assert(1, IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsPositionalObjectRep)));
Assert(1, not IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsComponentObjectRep)));

Comment thread lib/type1.g
Comment on lines +613 to +614
#Assert(0, IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsComponentObjectRep)));
Assert(0, not IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsPositionalObjectRep)));

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.

Suggested change
#Assert(0, IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsComponentObjectRep)));
Assert(0, not IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsPositionalObjectRep)));
#Assert(1, IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsComponentObjectRep)));
Assert(1, not IS_SUBSET_FLAGS(flags, FLAGS_FILTER(IsPositionalObjectRep)));

@fingolfin
fingolfin force-pushed the mh/force-pos-or-com-objrep branch 3 times, most recently from 5705e69 to 6d8dc13 Compare January 8, 2025 20:27
@fingolfin
fingolfin force-pushed the mh/force-pos-or-com-objrep branch from 6d8dc13 to d1171f7 Compare January 8, 2025 21:06
@fingolfin fingolfin added this to the GAP 4.17.0 milestone Jun 5, 2026
@fingolfin

Copy link
Copy Markdown
Member Author

I'd like to get this out of my system one way or another:

  1. we could just change this PR to add the missing filter (any reason against that)
  2. we could just give up and close this
  3. we could try to get all packages that are distributed and violated this fixed (but of course there are also many not distributed packages)

Perhaps @ThomasBreuer has some insights on this?

@ThomasBreuer ThomasBreuer left a comment

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.

When Objectify( type, r ) is called with a record r then SET_TYPE_COMOBJ is called, and the result admits component access.
When Objectify( type, l ) is called with a plain list l then SET_TYPE_POSOBJ is called, and the result admits access to positions.
This is independent of the type type, and it fits to the documentation of Objectify.
(In other words, apparently IsComponentObjectRep is not needed to guarantee component access, and IsPositionalObjectRep is not needed to guarantee position access.)

In this sense, it is safe to set automatically IsComponentObjectRep in the first case and IsPositionalObjectRep in the second case, and to signal an error if this yields an object in IsComponentObjectRep and IsPositionalObjectRep.

Perhaps Objectify should check that IsInternalRep or IsDataObjectRep is not set in the given type.

Comment thread lib/alglie.gi

return ObjByExtRep( Fam, [ zero, tlist ] );
tlist := ObjByExtRep( Fam, [ zero, tlist ] );
return [ zero, tlist![2] ];

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.

As far as I see, this change is a bugfix.
(And NormalizedElementOfMagmaRingModuloRelations is a misleading name.)

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.

I wish I had made a note what the error was / why this change is the correct fix sigh

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.

NormalizedElementOfMagmaRingModuloRelations is called in the GAP library only in lib/mgmring.gi. In all cases, Objectify is called immediately afterwards with the result. For the old code, this means that the object had already the desired type before the Objectify call, and gets objectified again with the same type.

In this sense, I think the library code does not produce wrong results. Nevertheless, the old code contradicts the definition of NormalizedElementOfMagmaRingModuloRelations. And there may be code outside lib/mgmring.gi which wants to use NormalizedElementOfMagmaRingModuloRelations. If the package tests do not show an example where the proposed change yields a different result then we should just apply the proposed fix and add a test, perhaps even as a manual example.

gap> R:= GroupRing( Rationals, SymmetricGroup( 3 ) );;
gap> Fam:= FamilyObj( Zero( R ) );;
gap> x:= Sum( GeneratorsOfAlgebra( R ) );;
gap> descr:= [ 0, CoefficientsAndMagmaElements( x ) ];;
gap> NormalizedElementOfMagmaRingModuloRelations( Fam, descr ) = descr;
true
gap> R:= FreeLieAlgebra( Rationals, 2 );;
gap> Fam:= FamilyObj( Zero( R ) );;
gap> x:= Sum( GeneratorsOfAlgebra( R ) );;
gap> descr:= [ 0, CoefficientsAndMagmaElements( x ) ];;
gap> NormalizedElementOfMagmaRingModuloRelations( Fam, descr ) = descr;
true

(The first true comes from a correct NormalizedElementOfMagmaRingModuloRelations method, the second true will occur only after the fix.)

@ThomasBreuer

Copy link
Copy Markdown
Contributor

I'd like to get this out of my system one way or another:

  1. we could just change this PR to add the missing filter (any reason against that)
  2. we could just give up and close this
  3. we could try to get all packages that are distributed and violated this fixed (but of course there are also many not distributed packages)

I suggest variant 1.:
In Objectify, set IsComponentObjectRep if the argument in question is a record, and set IsPositionalObjectRep if the argument in question is a plain list.

And add an example for the NormalizedElementOfMagmaRingModuloRelations fix, for example the one shown above.

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

Successfully merging this pull request may close these issues.

2 participants