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

Make congruence poset object a digraph #385

Merged
merged 5 commits into from
Oct 13, 2017

Conversation

mtorpey
Copy link
Collaborator

@mtorpey mtorpey commented Sep 27, 2017

This probably should've been the case when the object was first created. A poset of semigroup congruences is a digraph with vertices labelled by the congruences themselves. An edge i -> j exists if congruence i j is a subrelation (a refinement) of congruence j i.

This is in reference to Issue #369.

EDIT: i and j reversed.

@wilfwilson
Copy link
Collaborator

An edge i -> j exists if congruence i is a subrelation (a refinement) of congruence j.

That's not what you've implemented:

gap> S := PartitionMonoid(2);;
gap> lat := LatticeOfCongruences(S);;
gap> univ := UniversalSemigroupCongruence(S);;
gap> triv := SemigroupCongruence(S, []);;
gap> pos_univ := Position(DigraphVertexLabels(lat), univ);;
gap> pos_triv := Position(DigraphVertexLabels(lat), triv);;
gap> IsDigraphEdge(lat, [pos_univ, pos_triv]);
true
gap> IsSubrelation(triv, univ);
false

Which do you want?

@mtorpey
Copy link
Collaborator Author

mtorpey commented Sep 27, 2017

My documentation for IsCongruencePoset says

an edge from vertex i to vertex j if and only if the congruence numbered j is a subrelation of the congruence numbered i.

which is what I intend.

My description in the first comment of this PR is wrong.

@mtorpey mtorpey added the 3.1 label Sep 27, 2017
@wilfwilson
Copy link
Collaborator

Thanks for clearing that up @mtorpey. My comments in this post are all about making sure that the behaviour of your posets is consistent with Digraphs.

Here's the documentation:

A congruence poset is a digraph with a vertex for each congruence, and an edge from vertex i to vertex j if and only if the congruence numbered j is a subrelation of the congruence numbered i.

You should make your posets reflexive, since a congruence contains itself. Furthermore, it makes sense to do this for the following reason. Your posets are currently antisymmetric and transitive, but since they're not reflexive, IsPartialOrderDigraph returns false:

gap> S := SymmetricInverseMonoid(3);;
gap> lat := LatticeOfCongruences(S);;
gap> IsAntisymmetricDigraph(lat) and IsTransitiveDigraph(lat);
true
gap> IsReflexiveDigraph(lat) or IsPartialOrderDigraph(lat);
false

I think it's natural to expect a poset of congruences to satisfy IsPartialOrderDigraph. If you make this change, then when a poset of congruences is created, you can set IsPartialOrderDigraph to be true (or you can make this inherent for any poset of congruences).

More fundamentally, you should change the definition of the partial order that is used for your posets. In your setup, x -> y is an edge if y ⊆ x. However this doesn't work well with Digraphs. From the Digraphs documentation:

For a partial order digraph digraph, the corresponding partial order is the relation , defined by x≤y if and only if [x, y] (aka x -> y) is an edge of digraph.

So, taking this all together, cong1 ≤ cong2 if and only if cong2 ⊆ cong1, which I hope you can see is strange. Here's an example of where the problem kicks in:

The join of two elements partially ordered by less-than-or-equal is their least unique upper bound. Therefore, with your congruences, the join of two elements c1 and c2 is greater than both c1 and c2, and is therefore contained in c1 and c2. But (obviously) the join of c1 andc2 contains c1 and c2. This means that, according to Digraphs, a JoinSemilatticeOfCongruences is a meet semilattice rather than a join semilattice.

gap> S := Semigroup([
>  Transformation([1, 3, 3, 3]),
>  Transformation([1, 2, 1])]);;
gap> cong1 := SemigroupCongruence(S,
>  [Transformation([1, 1, 1, 1]), Transformation([1, 2, 1])]);;
gap> cong2 := SemigroupCongruence(S,
>  [Transformation([1, 1, 1, 1]), Transformation([1, 3, 3, 3])]);;
gap> poset := JoinSemilatticeOfCongruences([cong1, cong2],
>   JoinSemigroupCongruences);;
gap> poset := DigraphAddAllLoops(poset);; # make it a partial order
gap> IsPartialOrderDigraph(poset);
true
gap> IsJoinSemilatticeDigraph(poset);
false
gap> IsMeetSemilatticeDigraph(poset);
true

Let me know if you want more convincing about this.

Copy link
Collaborator

@wilfwilson wilfwilson left a comment

Choose a reason for hiding this comment

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

I've review your PR, and it looks good. Most of my comments are things that will need to change once you've switched the direction of the partial order.

return poset;
end;

InstallMethod(MinimalCongruences,
"for a congruence poset",
[IsCongruencePoset],
poset -> CongruencesOfPoset(poset){DigraphSinks(poset!.po)});
poset -> CongruencesOfPoset(poset){DigraphSinks(poset)});
Copy link
Collaborator

Choose a reason for hiding this comment

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

When you add loops at every vertex, you'll have to change this. Options: vertices with out-degree 1, or vertices with in-degree 1. Or remove loops and then get the sinks.

obtained using <Ref Attr = "CongruencesOfPoset"/>.
A congruence poset is a digraph
(see <Ref Filt = "IsDigraph" BookName = "Digraphs"/>) with a vertex for
each congruence, and an edge from vertex <C>i</C> to vertex <C>j</C> if
Copy link
Collaborator

Choose a reason for hiding this comment

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

Swap this

doc/conglatt.xml Outdated
gap> IsDigraph(poset);
true
gap> OutNeighbours(poset);
[ [ ], [ 1 ], [ 1, 2, 4 ], [ 1, 2 ] ]
Copy link
Collaborator

Choose a reason for hiding this comment

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

This will presumably change.

doc/conglatt.xml Outdated
gap> LatticeOfRightCongruences(S);
<poset of 5 congruences over <regular transformation monoid
of size 3, degree 2 with 2 generators>>
gap> OutNeighbours(LatticeOfRightCongruences(S));
[ [ ], [ 1 ], [ 1 ], [ 1 ], [ 1, 2, 3, 4 ] ]
Copy link
Collaborator

@wilfwilson wilfwilson Oct 4, 2017

Choose a reason for hiding this comment

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

This will presumably change too.

children := OutNeighboursMutableCopy(poset!.po);
parents := InNeighboursMutableCopy(poset!.po);
children := OutNeighboursMutableCopy(poset);
parents := InNeighboursMutableCopy(poset);
Copy link
Collaborator

Choose a reason for hiding this comment

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

swap this

children := OutNeighboursMutableCopy(poset!.po);
parents := InNeighboursMutableCopy(poset!.po);
children := OutNeighboursMutableCopy(poset);
parents := InNeighboursMutableCopy(poset);
Copy link
Collaborator

Choose a reason for hiding this comment

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

swap

SetInNeighbours(po, parents);
poset := Objectify(NewType(FamilyObj(children), IsCongruencePoset),
rec(po := po));
poset := Digraph(children);
Copy link
Collaborator

Choose a reason for hiding this comment

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

same swap

SetInNeighbours(po, parents);
poset := Objectify(NewType(FamilyObj(children), IsCongruencePoset),
rec(po := po));
poset := Digraph(children);
Copy link
Collaborator

Choose a reason for hiding this comment

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

same swap

fi;

rel := List([1 .. Length(poset)], x -> Filtered(poset[x], y -> x <> y));
rel := List([1 .. Length(out_nbs)], x -> Filtered(out_nbs[x], y -> x <> y));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Change to rel := InNeighbours(DigraphReflexiveTransitiveReduction(poset));

The remove the line j := Difference(rel[i], Union(rel{rel[i]}));.

@@ -510,14 +500,15 @@ InstallMethod(DotString,
"for a congruence poset and a record",
[IsCongruencePoset, IsRecord],
function(poset, opts)
local congs, S, symbols, i, nr, rel, str, j, k;
local out_nbs, congs, S, symbols, i, nr, rel, str, j, k;
out_nbs := OutNeighbours(poset);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Dont need this line. Throughout this method, change Length(out_nbs) and Length(rel) to Size(poset).

@mtorpey
Copy link
Collaborator Author

mtorpey commented Oct 4, 2017

Added changes to reverse the ordering.

I still need to add loops.

@mtorpey
Copy link
Collaborator Author

mtorpey commented Oct 13, 2017

This is done!

@wilfwilson wilfwilson merged commit 42445da into semigroups:master Oct 13, 2017
@mtorpey mtorpey deleted the lattice-digraph branch October 16, 2017 12:36
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.

None yet

2 participants