GAP:IsFiniteJoinClosed

Function type
IsFiniteJoinClosed is a GAP function defined here that takes as input a group and a subgroup property, and outputs a boolean variable. It is not an in-built function.

Behavior
The behavior is as follows:


 * The function returns true if the join of any two subgroups of the group having the property also has the property; in other words, the subgroup property is a finite-join-closed subgroup property.
 * The function returns false if there exist two subgroups of the group having the property whose join does not have the property.

Note that IsFiniteJoinClosed assumes that the property provided is a subgroup property in the sense of being invariant under isomorphisms. In particular, it uses the fact that given two conjugate subgroups, one of them satisfies the property if and only if the other one does.

Related functions

 * GAP:IsFiniteJoinClosedGivenNormalizingJoinClosed: A somewhat quicker method to determine whether a subgroup property is finite-join-closed, assuming that the subgroup property is a normalizing join-closed subgroup property: whenever two subgroups have the property and one of them normalizes the other, their join also has the property.
 * GAP:IsFiniteJoinClosedGivenClosedUnderJoinWithNormal: A somewhat quicker method to determine whether a subgroup property is finite-join-closed, assuming that the join of any subgroup having the property with any normal subgroup having the property also has the property.

Code
IsFiniteJoinClosed := function(G,P) local H, K, L, R, S;       L := Filtered(ConjugacyClassesSubgroups(G),C -> P(G,Representative(C))); for R in L do           H := Representative(R); for S in L do               for K in AsList(S) do                    if (not P(G,Group(Union(H,K)))) then return false; fi; od; od; od; return true; end;;

Underlying idea
The idea is as follows:


 * First, a list of all conjugacy classes of subgroups is created, using the GAP command ConjugacyClassesSubgroups.
 * This list is then filtered for the subgroup property. In other words, all the conjugacy classes of subgroups that do not satisfy the property are removed, and the new, smaller list comprises the conjugacy classes of subgroups that do satisfy the property. Note here that we are using the fact that a subgroup satisfies the property if and only if all its conjugate subgroups do.
 * Next, we take joins between subgroups in these conjugacy classes, and check whether these joins again satisfy the property. For this, we use a slightly smart approach: instead of taking join between all pairs of subgroups in these conjugacy classes, we try all pairs where one member of the pair varies over representatives of the conjugacy classes of subgroups, and the other member varies over all subgroups. The idea is that if a counterexample exists, we can conjugate it to a situation where one of the two subgroups is the representative of its conjugacy class.

Possible modifications to the code
There are some areas of possible performance improvement in the code:

IsFiniteJoinClosedGivenTrim := function(G,P) local H, K, L, D, R, S;       D := ConjugacyClassesMaximalSubgroups(G); L := Filtered(ConjugacyClassesSubgroups(G),C -> P(G,Representative(C)) and             not (C in D) and              not IsTrivial(Representative(C));        for R in L do            H := Representative(R);            for S in L do                for K in AsList(S) do                    if (not P(G,Group(Union(H,K)))) then                       return false;                    fi;                od;           od;        od;        return true; end;;  IsFiniteJoinClosed := function(G,P)        local H, K, L, R, S;        L := Filtered(ConjugacyClassesSubgroups(G),C -> P(G,Representative(C)));        M := List(L,Representative);        for H in M do            for S in L do                for K in AsList(S) do                    if (Intersection(ConjugateSubgroups(Group(Union(H,K))),M)=[]) then                       return false;                    fi;                od;           od; od; return true; end;;
 * Some extreme cases can be eliminated. For instance, if it is known that the trivial subgroup always satisfies the property, the trivial subgroup can be eliminated from the original list of conjugacy classes. Further, if it is known that the whole group satisfies the property, all maximal subgroups of the group that satisfy the property can be eliminated. A trim subgroup property is a subgroup property that is true both for the trivial subgroup and the whole group, and the following modified code works for trim subgroup properties:
 * If computing whether a subgroup of a group satisfies the property is an expensive operation, the check of whether the join of the two subgroups satisfies the property can be replaced by a check as to whether it is in the already-computed list. This leads to the following modified code:
 * If the subgroup property is known to satisfy some additional metaproperties, then smarter methods can be used. Two examples are GAP:IsFiniteJoinClosedGivenClosedUnderJoinWithNormal and GAP:IsFiniteJoinClosedGivenNormalizingJoinClosed.