add direct prodcts
This commit is contained in:
parent
890e943901
commit
4b723e17f6
|
@ -394,3 +394,62 @@ InstallMethod(Opposite, "for right rack",
|
||||||
[ IsRightRack and IsBuiltFromMultiplicationTable],
|
[ IsRightRack and IsBuiltFromMultiplicationTable],
|
||||||
L -> LeftRackByMultiplicationTableNC(TransposedMat(MultiplicationTable(L)))
|
L -> LeftRackByMultiplicationTableNC(TransposedMat(MultiplicationTable(L)))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# Note that opposite of quandles seems to come for free from above, which is
|
||||||
|
# good.
|
||||||
|
|
||||||
|
## Direct products
|
||||||
|
# As in the case of general one-sided quasigroups, this implementation should
|
||||||
|
# only be called with a second-argument collection which is not a group or
|
||||||
|
# quasigroup.
|
||||||
|
InstallOtherMethod(DirectProductOp,
|
||||||
|
"for a list and non-quasigroup magma built form multiplication table",
|
||||||
|
[IsList, IsMagma and IsBuiltFromMultiplicationTable],
|
||||||
|
function (list, first)
|
||||||
|
local item, i, jof, bigtable;
|
||||||
|
# Simple checks
|
||||||
|
if IsEmpty(list) then
|
||||||
|
Error("Usage: Cannot take DirectProduct of zero items.");
|
||||||
|
elif Length(list) = 1 then
|
||||||
|
return list[1];
|
||||||
|
fi;
|
||||||
|
# See if we can handle all objects
|
||||||
|
for i in [2..Length(list)] do
|
||||||
|
if not HasMultiplicationTable(list(i)) then
|
||||||
|
return DirectProductOp(Permuted(list, (1,i)), list[i]);
|
||||||
|
fi;
|
||||||
|
od;
|
||||||
|
# OK, safe to take everyone's multiplication table.
|
||||||
|
# So go ahead and make the big thing
|
||||||
|
bigtable := ProductTableOfCanonicalCayleyTables(
|
||||||
|
List(list, MultiplicationTable));
|
||||||
|
# But we have to figure out what to do with it.
|
||||||
|
jof := RoughJoinOfFilters@(list, first);
|
||||||
|
# Dispatch modeled after the general one
|
||||||
|
if "IsMagmaWithOne" in jof then
|
||||||
|
if "IsMonoid" in jof then
|
||||||
|
return MonoidByMultiplicationTable(bigtable);
|
||||||
|
fi;
|
||||||
|
return MagmaWithOneByMultiplicationTable(bigtable);
|
||||||
|
fi;
|
||||||
|
if "IsAssociative" in jof then
|
||||||
|
return SemigroupByMultiplicationTable(bigtable);
|
||||||
|
elif "IsLeftQuasigroup" in jof then
|
||||||
|
if "IsLSelfDistributive" in jof then
|
||||||
|
if "IsElementwiseIdempotent" in jof then
|
||||||
|
return LeftQuandleByMultiplicationTableNC(bigtable);
|
||||||
|
fi;
|
||||||
|
return LeftRackByMultiplicationTableNC(bigtable);
|
||||||
|
fi;
|
||||||
|
return LeftQuandleByMultiplicationTableNC(bigtable);
|
||||||
|
elif "IsRightQuasigroup" in jof then
|
||||||
|
if "IsLSelfDistributive" in jof then
|
||||||
|
if "IsElementwiseIdempotent" in jof then
|
||||||
|
return RightQuandleByMultiplicationTableNC(bigtable);
|
||||||
|
fi;
|
||||||
|
return RightRackByMultiplicationTableNC(bigtable);
|
||||||
|
fi;
|
||||||
|
return RightQuandleByMultiplicationTableNC(bigtable);
|
||||||
|
fi;
|
||||||
|
return MagmaByMultiplicationTable(bigtable);
|
||||||
|
end);
|
||||||
|
|
117
gap/structure.gi
117
gap/structure.gi
|
@ -503,3 +503,120 @@ InstallMethod(Opposite, "for a right quandle",
|
||||||
Q -> OppHelper@(Q, GeneratorsOfRightQuasigroup, LeftQuandleNC)
|
Q -> OppHelper@(Q, GeneratorsOfRightQuasigroup, LeftQuandleNC)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# Direct Products
|
||||||
|
# We actually try to handle here the general cases that are not otherwise
|
||||||
|
# handled by the groups functions in GAP as a whole, or the LOOPS package
|
||||||
|
|
||||||
|
# Helper for roughly creating the join of the filters of a bunch of objects.
|
||||||
|
FiltersOfObj@ := function(obj)
|
||||||
|
local f;
|
||||||
|
f := CategoriesOfObject(obj);
|
||||||
|
Append(f,KnownTruePropertiesOfObject(obj));
|
||||||
|
Append(f,List(KnownAttributesOfObject(obj), x -> Concatenate("Has", x)));
|
||||||
|
return f;
|
||||||
|
end;
|
||||||
|
|
||||||
|
# From the implementation of DirectProductOp for groups and quasigroups, the
|
||||||
|
# below will only be called with a second-argument collection which is not a
|
||||||
|
# group or quasigroup.
|
||||||
|
|
||||||
|
# This is a helper that creates a rough join of the filters of a list of
|
||||||
|
# objects, using the same arguments as directproduct op (the redundant "first"
|
||||||
|
# argument, which is handy for seeding the filter list)
|
||||||
|
RoughJoinOfFilters@ := function(list, first);
|
||||||
|
local item, jof;
|
||||||
|
jof := Set(FiltersOfObj@(first));
|
||||||
|
for item in list{[2..Length(list)]} do
|
||||||
|
IntersectSet(jof, FiltersOfObj@);
|
||||||
|
od;
|
||||||
|
end;
|
||||||
|
|
||||||
|
InstallOtherMethod(DirectProductOp, "for a list and non-quasigroup magma",
|
||||||
|
[IsList, IsMagma],
|
||||||
|
function (list, first)
|
||||||
|
local item, i, jof, ids, gens, g, current, genfunc, genlists;
|
||||||
|
# Simple checks
|
||||||
|
if IsEmpty(list) then
|
||||||
|
Error("Usage: Cannot take DirectProduct of zero items.");
|
||||||
|
elif Length(list) = 1 then
|
||||||
|
return list[1];
|
||||||
|
fi;
|
||||||
|
jof := RoughJoinOfFilters(list, first);
|
||||||
|
|
||||||
|
# The dispatch below is somewhat ad-hoc, but covers the major existing cases
|
||||||
|
|
||||||
|
# First, if we don't have generators for all of the items, we're kinda out
|
||||||
|
# of luck here:
|
||||||
|
if not ForAny(jof, nm -> StartsWith(nm,"HasGenerators")) then
|
||||||
|
TryNextMethod();
|
||||||
|
fi;
|
||||||
|
# Next, if anything is not even a magma, recommend cartesian product
|
||||||
|
if not "IsMagma" in jof then
|
||||||
|
Info(InfoRAQ, 1, "Try Cartesian() for products of collections.");
|
||||||
|
TryNextMethod();
|
||||||
|
fi;
|
||||||
|
|
||||||
|
# The primary division now is between entities with identities, for which
|
||||||
|
# the product will have a smaller generating set, and those which do
|
||||||
|
# not, for which the generators is the full cartesian product of generators.
|
||||||
|
if "IsMagmaWithOne" in jof then
|
||||||
|
# Code basically copied from DirectProductOp() for general groups;
|
||||||
|
# would be better if this could be moved into the GAP core
|
||||||
|
ids := List(list, One);
|
||||||
|
gens := [];
|
||||||
|
for i in [1..Length(list)] do
|
||||||
|
for g in GeneratorsOfMagmaWithOne(list[i]) do
|
||||||
|
current := ShallowCopy(ids);
|
||||||
|
current[i] = g;
|
||||||
|
Add(gens, DirectProductElement(current));
|
||||||
|
od;
|
||||||
|
od;
|
||||||
|
# Now, we want the most specific structure we know about here.
|
||||||
|
# Only aware of MagmaWithOne and Monoid, as direct products of
|
||||||
|
# loops are already covered by the LOOPS package:
|
||||||
|
if "IsMonoid" in jof then
|
||||||
|
return MonoidByGenerators(gens);
|
||||||
|
fi;
|
||||||
|
return MagmaWithOneByGenerators(gens);
|
||||||
|
fi;
|
||||||
|
# OK, here we know not all structures have inverses. Therefore, we must
|
||||||
|
# resort to the full cartesian product of generators.
|
||||||
|
# But we need to figure out what function to use to obtain the generators.
|
||||||
|
if "HasGeneratorsOfLeftQuasigroup" in jof then
|
||||||
|
genfunc := GeneratorsOfLeftQuasigroup;
|
||||||
|
elif "HasGeneratorsOfRightQuasigroup" in jof then
|
||||||
|
genfunc := GeneratorsOfRightQuasigroup;
|
||||||
|
elif "HasGeneratorsOfMagma" in jof then
|
||||||
|
genfunc := GeneratorsOfMagma;
|
||||||
|
else
|
||||||
|
Info(InfoRAQ,1, "RAQ: Unusual product, each of ", list,
|
||||||
|
" has generators, but not sure what kind; trying next method.");
|
||||||
|
TryNextMethod();
|
||||||
|
fi;
|
||||||
|
|
||||||
|
genlists := List(list, genfunc);
|
||||||
|
gens := Cartesian(genlists);
|
||||||
|
Apply(gens, DirectProductElement);
|
||||||
|
# Again, we need to figure out what sort of structure we might have
|
||||||
|
if "IsAssociative" in jof then
|
||||||
|
return SemigroupByGenerators(gens);
|
||||||
|
elif "IsLeftQuasigroup" in jof then
|
||||||
|
if "IsLSelfDistributive" in jof then
|
||||||
|
if "IsElementwiseIdempotent" in jof then
|
||||||
|
return LeftQuandleNC(gens);
|
||||||
|
fi;
|
||||||
|
return LeftRackNC(gens);
|
||||||
|
fi;
|
||||||
|
return LeftQuasigroupNC(gens);
|
||||||
|
elif "IsRightQuasigroup" in jof then
|
||||||
|
if "IsRSelfDistributive" in jof then
|
||||||
|
if "IsElementwiseIdempotent" in jof then
|
||||||
|
return RightQuandleNC(gens);
|
||||||
|
fi;
|
||||||
|
return RightRackNC(gens);
|
||||||
|
fi;
|
||||||
|
return RightQuasigroupNC(gens);
|
||||||
|
fi;
|
||||||
|
# Not seeing any additional structure; did I miss anything?
|
||||||
|
return MagmaByGenerators(gens);
|
||||||
|
end);
|
||||||
|
|
Loading…
Reference in New Issue