2017-10-20 09:08:09 +00:00
|
|
|
## bytable.gi RAQ Implementation of racks etc. by multiplication tables.
|
|
|
|
|
|
|
|
## Predicates to check tables for distributivity
|
|
|
|
InstallMethod(IsRightSelfDistributiveTable, "for matrix",
|
|
|
|
[ IsMatrix ],
|
|
|
|
T -> IsLeftSelfDistributiveTable(TransposedMat(T))
|
|
|
|
);
|
|
|
|
|
|
|
|
InstallMethod(IsLeftSelfDistributiveTable, "for matrix",
|
|
|
|
[ IsMatrix ],
|
|
|
|
function(T)
|
|
|
|
# Everybody else does it by checking all of the cases, so why not me, too?
|
|
|
|
# Is there a better way?
|
|
|
|
local n,i,j,k;
|
|
|
|
n := Length(T);
|
|
|
|
for i in [1..n] do for j in [1..n] do for k in [1..n] do
|
|
|
|
if T[i, T[j,k]] <> T[T[i,j], T[i,k]] then return false; fi;
|
|
|
|
od; od; od;
|
|
|
|
return true;
|
|
|
|
end);
|
|
|
|
|
|
|
|
InstallMethod(IsElementwiseIdempotentTable, "for matrix",
|
|
|
|
[ IsMatrix ],
|
|
|
|
T -> ForAll([1..Length(T)], i->(T[i,i]=i))
|
|
|
|
);
|
|
|
|
|
2017-10-20 14:21:59 +00:00
|
|
|
## And a general principle: collections from finite families are finite.
|
|
|
|
|
|
|
|
InstallMethod(IsFinite, "for any collection (with a finite element family)",
|
|
|
|
[IsCollection],
|
|
|
|
function(C)
|
|
|
|
local ef;
|
|
|
|
ef := ElementsFamily(FamilyObj(C));
|
|
|
|
if HasIsFinite(ef) and IsFinite(ef) then return true; fi;
|
|
|
|
TryNextMethod();
|
|
|
|
return fail;
|
|
|
|
end);
|
|
|
|
|
|
|
|
|
2017-10-20 09:08:09 +00:00
|
|
|
## And now create them from multiplication tables
|
2017-10-20 14:21:59 +00:00
|
|
|
|
2017-10-25 00:17:01 +00:00
|
|
|
# First a helper function
|
2017-10-25 00:30:46 +00:00
|
|
|
MagmaNumber@ := 1;
|
|
|
|
MagmaLetters@ := "VABCDEFGHJKMNPSTU";
|
2017-10-25 00:17:37 +00:00
|
|
|
MagmaBase@ := Length(MagmaLetters@);
|
2017-10-25 00:17:01 +00:00
|
|
|
NextMagmaString@ := function(filts)
|
|
|
|
local str, n;
|
|
|
|
str := "l";
|
2017-10-25 00:28:03 +00:00
|
|
|
if not "IsLeftQuotientElement" in NamesFilter(filts) then
|
2017-10-25 00:17:01 +00:00
|
|
|
str := "r";
|
|
|
|
fi;
|
|
|
|
n := MagmaNumber@;
|
|
|
|
MagmaNumber@ := MagmaNumber@ + 1;
|
|
|
|
while n > 0 do
|
2017-10-25 00:18:24 +00:00
|
|
|
Add(str, MagmaLetters@[RemInt(n, MagmaBase@) + 1]);
|
2017-10-25 00:17:01 +00:00
|
|
|
n := QuoInt(n, MagmaBase@);
|
|
|
|
od;
|
|
|
|
return str;
|
|
|
|
end;
|
|
|
|
|
2017-10-20 14:31:22 +00:00
|
|
|
FiniteMagmaCreator@ := function(tbl, cnstr, filts)
|
2017-10-20 14:21:59 +00:00
|
|
|
local M;
|
|
|
|
M := MagmaByMultiplicationTableCreatorNC(
|
2017-10-20 14:31:22 +00:00
|
|
|
tbl, cnstr, filts and IsMagmaByMultiplicationTableObj);
|
|
|
|
# Is there such a thing as a non-finite table in GAP? Anyhow...
|
|
|
|
SetIsFinite(ElementsFamily(FamilyObj(M)), IsFinite(tbl));
|
2017-10-25 00:17:01 +00:00
|
|
|
SpecifyElmNamePrefix(M, NextMagmaString@(filts));
|
2017-10-20 14:21:59 +00:00
|
|
|
return M;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2017-10-20 09:08:09 +00:00
|
|
|
InstallGlobalFunction(LeftQuasigroupByMultiplicationTable,
|
|
|
|
function(T)
|
|
|
|
if not IsLeftQuasigroupTable(T) then
|
|
|
|
Error("Multiplication table <T> must have each row a permutation of ",
|
|
|
|
"the same entries.");
|
|
|
|
fi;
|
|
|
|
return LeftQuasigroupByMultiplicationTableNC(
|
|
|
|
CanonicalCayleyTableOfLeftQuasigroupTable(T));
|
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(LeftQuasigroupByMultiplicationTableNC,
|
2017-10-20 14:21:59 +00:00
|
|
|
T -> FiniteMagmaCreator@(T, LeftQuasigroupNC, IsLeftQuotientElement)
|
2017-10-20 09:08:09 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
InstallGlobalFunction(RightQuasigroupByMultiplicationTable,
|
|
|
|
function(T)
|
|
|
|
if not IsRightQuasigroupTable(T) then
|
|
|
|
Error("Multiplication table <T> must have each row a permutation of ",
|
|
|
|
"the same entries.");
|
|
|
|
fi;
|
|
|
|
return RightQuasigroupByMultiplicationTableNC(CanonicalCayleyTable(T));
|
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(RightQuasigroupByMultiplicationTableNC,
|
2017-10-20 14:21:59 +00:00
|
|
|
T -> FiniteMagmaCreator@(T, RightQuasigroupNC, IsRightQuotientElement)
|
2017-10-20 09:08:09 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
InstallGlobalFunction(LeftRackByMultiplicationTable,
|
|
|
|
function(T)
|
|
|
|
if not IsLeftQuasigroupTable(T) then
|
|
|
|
Error("Multiplication table <T> must have each row a permutation of ",
|
|
|
|
"the same entries.");
|
|
|
|
fi;
|
|
|
|
T := CanonicalCayleyTableOfLeftQuasigroupTable(T);
|
|
|
|
if not IsLeftSelfDistributiveTable(T) then
|
|
|
|
Error("Multiplication table <T> must be left self distributive.");
|
|
|
|
fi;
|
|
|
|
return LeftRackByMultiplicationTableNC(T);
|
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(LeftRackByMultiplicationTableNC,
|
2017-10-20 14:21:59 +00:00
|
|
|
T -> FiniteMagmaCreator@(T, LeftRackNC,
|
|
|
|
IsLeftQuotientElement and IsLSelfDistElement)
|
2017-10-20 09:08:09 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
InstallGlobalFunction(LeftQuandleByMultiplicationTable,
|
|
|
|
function(T)
|
|
|
|
if not IsLeftQuasigroupTable(T) then
|
|
|
|
Error("Multiplication table <T> must have each row a permutation of ",
|
|
|
|
"the same entries.");
|
|
|
|
fi;
|
|
|
|
T := CanonicalCayleyTableOfLeftQuasigroupTable(T);
|
|
|
|
if not (IsLeftSelfDistributiveTable(T) and
|
|
|
|
IsElementwiseIdempotentTable(T)) then
|
|
|
|
Error("Multiplication table <T> must be left self-dist and idempotent.");
|
|
|
|
fi;
|
|
|
|
return LeftQuandleByMultiplicationTableNC(T);
|
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(LeftQuandleByMultiplicationTableNC,
|
2017-10-20 14:21:59 +00:00
|
|
|
T -> FiniteMagmaCreator@(T, LeftQuandleNC,
|
|
|
|
IsLeftQuotientElement and IsLSelfDistElement and IsIdempotent)
|
2017-10-20 09:08:09 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
InstallGlobalFunction(RightRackByMultiplicationTable,
|
|
|
|
function(T)
|
|
|
|
if not IsRightQuasigroupTable(T) then
|
|
|
|
Error("Multiplication table <T> must have each column a permutation of ",
|
|
|
|
"the same entries.");
|
|
|
|
fi;
|
|
|
|
T := CanonicalCayleyTable(T);
|
|
|
|
if not IsRightSelfDistributiveTable(T) then
|
|
|
|
Error("Multiplication table <T> must be right self distributive.");
|
|
|
|
fi;
|
|
|
|
return RightRackByMultiplicationTableNC(T);
|
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(RightRackByMultiplicationTableNC,
|
2017-10-20 14:21:59 +00:00
|
|
|
T -> FiniteMagmaCreator@(T, RightRackNC,
|
|
|
|
IsRightQuotientElement and IsRSelfDistElement)
|
2017-10-20 09:08:09 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
InstallGlobalFunction(RightQuandleByMultiplicationTable,
|
|
|
|
function(T)
|
|
|
|
if not IsRightQuasigroupTable(T) then
|
|
|
|
Error("Multiplication table <T> must have each column a permutation of ",
|
|
|
|
"the same entries.");
|
|
|
|
fi;
|
|
|
|
T := CanonicalCayleyTable(T);
|
|
|
|
if not (IsRightSelfDistributiveTable(T) and
|
|
|
|
IsElementwiseIdempotentTable(T)) then
|
|
|
|
Error("Multiplication table <T> must be right self-dist and idempotent.");
|
|
|
|
fi;
|
|
|
|
return RightQuandleByMultiplicationTableNC(T);
|
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(RightQuandleByMultiplicationTableNC,
|
2017-10-20 14:21:59 +00:00
|
|
|
T -> FiniteMagmaCreator@(T, RightQuandleNC,
|
|
|
|
IsRightQuotientElement and IsRSelfDistElement and IsIdempotent)
|
2017-10-20 09:08:09 +00:00
|
|
|
);
|
|
|
|
|
2017-10-24 20:57:19 +00:00
|
|
|
## Creators from permutations
|
|
|
|
InstallGlobalFunction(LeftQuasigroupByPerms,
|
|
|
|
function(perms)
|
|
|
|
local Q;
|
|
|
|
Q := LeftQuasigroupByMultiplicationTableNC(
|
|
|
|
CayleyTableByPerms(perms, [1..Length(perms)]));
|
|
|
|
SetLeftPerms(Q, perms);
|
2017-10-24 21:14:42 +00:00
|
|
|
return Q;
|
2017-10-24 20:57:19 +00:00
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(LeftRackByPerms,
|
|
|
|
function(perms)
|
|
|
|
local Q;
|
|
|
|
Q := LeftRackByMultiplicationTable(
|
|
|
|
CayleyTableByPerms(perms, [1..Length(perms)]));
|
|
|
|
SetLeftPerms(Q, perms);
|
2017-10-24 21:14:42 +00:00
|
|
|
return Q;
|
2017-10-24 20:57:19 +00:00
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(LeftRackByPermsNC,
|
|
|
|
function(perms)
|
|
|
|
local Q;
|
|
|
|
Q := LeftRackByMultiplicationTableNC(
|
|
|
|
CayleyTableByPerms(perms, [1..Length(perms)]));
|
|
|
|
SetLeftPerms(Q, perms);
|
2017-10-24 21:14:42 +00:00
|
|
|
return Q;
|
2017-10-24 20:57:19 +00:00
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(LeftQuandleByPerms,
|
|
|
|
function(perms)
|
|
|
|
local Q;
|
|
|
|
Q := LeftQuandleByMultiplicationTable(
|
|
|
|
CayleyTableByPerms(perms, [1..Length(perms)]));
|
|
|
|
SetLeftPerms(Q, perms);
|
2017-10-24 21:14:42 +00:00
|
|
|
return Q;
|
2017-10-24 20:57:19 +00:00
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(LeftQuandleByPermsNC,
|
|
|
|
function(perms)
|
|
|
|
local Q;
|
|
|
|
Q := LeftQuandleByMultiplicationTableNC(
|
|
|
|
CayleyTableByPerms(perms, [1..Length(perms)]));
|
|
|
|
SetLeftPerms(Q, perms);
|
2017-10-24 21:14:42 +00:00
|
|
|
return Q;
|
2017-10-24 20:57:19 +00:00
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(RightQuasigroupByPerms,
|
|
|
|
function(perms)
|
|
|
|
local Q;
|
|
|
|
Q := RightQuasigroupByMultiplicationTableNC(
|
|
|
|
TransposedMat(
|
|
|
|
CayleyTableByPerms(perms, [1..Length(perms)])));
|
|
|
|
SetRightPerms(Q, perms);
|
2017-10-24 21:14:42 +00:00
|
|
|
return Q;
|
2017-10-24 20:57:19 +00:00
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(RightRackByPerms,
|
|
|
|
function(perms)
|
|
|
|
local Q;
|
|
|
|
Q := RightRackByMultiplicationTable(
|
|
|
|
TransposedMat(
|
|
|
|
CayleyTableByPerms(perms, [1..Length(perms)])));
|
|
|
|
SetRightPerms(Q, perms);
|
2017-10-24 21:14:42 +00:00
|
|
|
return Q;
|
2017-10-24 20:57:19 +00:00
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(RightRackByPermsNC,
|
|
|
|
function(perms)
|
|
|
|
local Q;
|
|
|
|
Q := RightRackByMultiplicationTableNC(
|
|
|
|
TransposedMat(
|
|
|
|
CayleyTableByPerms(perms, [1..Length(perms)])));
|
|
|
|
SetRightPerms(Q, perms);
|
2017-10-24 21:14:42 +00:00
|
|
|
return Q;
|
2017-10-24 20:57:19 +00:00
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(RightQuandleByPerms,
|
|
|
|
function(perms)
|
|
|
|
local Q;
|
|
|
|
Q := RightQuandleByMultiplicationTable(
|
|
|
|
TransposedMat(
|
|
|
|
CayleyTableByPerms(perms, [1..Length(perms)])));
|
|
|
|
SetRightPerms(Q, perms);
|
2017-10-24 21:14:42 +00:00
|
|
|
return Q;
|
2017-10-24 20:57:19 +00:00
|
|
|
end);
|
|
|
|
|
|
|
|
InstallGlobalFunction(RightQuandleByPermsNC,
|
|
|
|
function(perms)
|
|
|
|
local Q;
|
|
|
|
Q := RightQuandleByMultiplicationTableNC(
|
|
|
|
TransposedMat(
|
|
|
|
CayleyTableByPerms(perms, [1..Length(perms)])));
|
|
|
|
SetRightPerms(Q, perms);
|
2017-10-24 21:14:42 +00:00
|
|
|
return Q;
|
2017-10-24 20:57:19 +00:00
|
|
|
end);
|
|
|
|
|
2017-10-20 09:08:09 +00:00
|
|
|
## And define the operations
|
|
|
|
|
|
|
|
InstallOtherMethod(LeftQuotient,
|
|
|
|
"for two elts in magma by mult table, when left has left quotients",
|
|
|
|
IsIdenticalObj,
|
|
|
|
[IsLeftQuotientElement, IsMagmaByMultiplicationTableObj],
|
|
|
|
function (l,r)
|
|
|
|
local fam, ix;
|
|
|
|
fam := FamilyObj(l);
|
|
|
|
ix := LeftDivisionTable(fam)[l![1],r![1]];
|
|
|
|
return fam!.set[ix];
|
|
|
|
end);
|
|
|
|
|
|
|
|
InstallOtherMethod(\/,
|
|
|
|
"for two elts in magma by mult table, when right has right quotients",
|
|
|
|
IsIdenticalObj,
|
|
|
|
[IsMagmaByMultiplicationTableObj, IsRightQuotientElement],
|
|
|
|
function (l,r)
|
|
|
|
local fam, ix;
|
|
|
|
fam := FamilyObj(r);
|
|
|
|
ix := RightDivisionTable(fam)[l![1],r![1]];
|
|
|
|
return fam!.set[ix];
|
|
|
|
end);
|
|
|
|
|
|
|
|
## Create division tables as needed
|
|
|
|
InstallMethod(LeftDivisionTable,
|
|
|
|
"for an object with a multiplication table",
|
|
|
|
[HasMultiplicationTable],
|
|
|
|
function(fam)
|
|
|
|
local LS, n;
|
|
|
|
LS := LeftPerms(fam);
|
|
|
|
n := Size(LS);
|
|
|
|
return List(LS, x->ListPerm(Inverse(x), n));
|
|
|
|
end);
|
|
|
|
|
|
|
|
InstallMethod(RightDivisionTable,
|
|
|
|
"for an object with a multiplication table",
|
|
|
|
[HasMultiplicationTable],
|
|
|
|
function (obj)
|
|
|
|
local RS, n;
|
|
|
|
RS := RightPerms(obj);
|
|
|
|
n := Size(RS);
|
|
|
|
return TransposedMat(List(RS, x->ListPerm(Inverse(x), n)));
|
|
|
|
end);
|
|
|
|
|
|
|
|
## Create perm lists as needed
|
|
|
|
InstallMethod(LeftPerms,
|
|
|
|
"for an object with a multiplication table",
|
|
|
|
[HasMultiplicationTable],
|
|
|
|
function(fam)
|
|
|
|
return List(MultiplicationTable(fam), x->PermList(x));
|
|
|
|
end);
|
|
|
|
|
|
|
|
InstallMethod(RightPerms,
|
|
|
|
"for an object with a muliplication table",
|
|
|
|
[HasMultiplicationTable],
|
|
|
|
function(fam)
|
|
|
|
return List(TransposedMat(MultiplicationTable(fam)), x->PermList(x));
|
|
|
|
end);
|
|
|
|
|
|
|
|
## Distributivity/idempotence checkers for when need be
|
2017-10-20 13:25:22 +00:00
|
|
|
InstallMethod(IsLSelfDistributive, "for collections with multiplication tables",
|
2017-10-20 13:30:44 +00:00
|
|
|
[IsMultiplicativeElementCollection and HasMultiplicationTable],
|
2017-10-20 09:08:09 +00:00
|
|
|
M -> IsLeftSelfDistributiveTable(MultiplicationTable(M))
|
|
|
|
);
|
|
|
|
|
2017-10-20 13:25:22 +00:00
|
|
|
InstallMethod(IsRSelfDistributive, "for collections with multiplication table",
|
2017-10-20 13:30:44 +00:00
|
|
|
[IsMultiplicativeElementCollection and HasMultiplicationTable],
|
2017-10-20 09:08:09 +00:00
|
|
|
M -> IsRightSelfDistributiveTable(MultiplicationTable(M))
|
|
|
|
);
|
|
|
|
|
|
|
|
## Patch View/Print/Display for magma by mult objects
|
|
|
|
InstallMethod(String, "for an element of magma by multiplication table",
|
|
|
|
[IsMagmaByMultiplicationTableObj],
|
|
|
|
function(obj)
|
|
|
|
local fam;
|
|
|
|
fam := FamilyObj(obj);
|
|
|
|
if IsBound(fam!.elmNamePrefix) then
|
|
|
|
return Concatenation(fam!.elmNamePrefix, String(obj![1]));
|
|
|
|
fi;
|
|
|
|
return Concatenation("m", String(obj![1]));
|
|
|
|
end);
|
|
|
|
|
|
|
|
InstallMethod(ViewString, "for an element of magma by multiplication table",
|
|
|
|
[IsMagmaByMultiplicationTableObj],
|
|
|
|
obj -> String(obj));
|
|
|
|
|
|
|
|
InstallMethod(DisplayString, "for an element of magma by multiplication table",
|
|
|
|
[IsMagmaByMultiplicationTableObj],
|
|
|
|
obj -> String(obj));
|
|
|
|
|
|
|
|
InstallMethod(PrintObj, "for an element of magma by multiplication table",
|
|
|
|
[IsMagmaByMultiplicationTableObj],
|
|
|
|
function(obj) Print(String(obj)); end);
|
|
|
|
|
|
|
|
## Property of a collection that its elements know their multiplication table
|
2017-10-24 21:24:41 +00:00
|
|
|
InstallImmediateMethod(IsBuiltFromMultiplicationTable,
|
2017-10-24 21:26:04 +00:00
|
|
|
IsCollection, 1,
|
2017-10-20 09:08:09 +00:00
|
|
|
C -> HasMultiplicationTable(ElementsFamily(FamilyObj(C)))
|
|
|
|
);
|
|
|
|
|
|
|
|
## Special case the Opposite function from LOOPS package, since the opposite
|
|
|
|
## of a left quasigroup is a right quasigroup and vice versa
|
|
|
|
|
|
|
|
# Is there a way to do this just once for each direction?
|
|
|
|
InstallMethod(Opposite, "for left quasigroup",
|
|
|
|
[ IsLeftQuasigroup and IsBuiltFromMultiplicationTable],
|
|
|
|
L -> RightQuasigroupByMultiplicationTable(
|
|
|
|
TransposedMat(MultiplicationTable(L))
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
InstallMethod(Opposite, "for left rack",
|
|
|
|
[ IsLeftRack and IsBuiltFromMultiplicationTable],
|
|
|
|
L -> RightRackByMultiplicationTableNC(TransposedMat(MultiplicationTable(L)))
|
|
|
|
);
|
|
|
|
|
|
|
|
InstallMethod(Opposite, "for right quasigroup",
|
|
|
|
[ IsRightQuasigroup and IsBuiltFromMultiplicationTable],
|
|
|
|
L -> LeftQuasigroupByMultiplicationTable(
|
|
|
|
TransposedMat(MultiplicationTable(L))
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
InstallMethod(Opposite, "for right rack",
|
|
|
|
[ IsRightRack and IsBuiltFromMultiplicationTable],
|
|
|
|
L -> LeftRackByMultiplicationTableNC(TransposedMat(MultiplicationTable(L)))
|
|
|
|
);
|
2017-10-25 14:18:35 +00:00
|
|
|
|
|
|
|
# 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,
|
2017-10-25 15:02:21 +00:00
|
|
|
"for a list and non-quasigroup magma built from multiplication table",
|
2017-10-25 14:18:35 +00:00
|
|
|
[IsList, IsMagma and IsBuiltFromMultiplicationTable],
|
|
|
|
function (list, first)
|
2017-10-25 14:40:56 +00:00
|
|
|
local n, item, i, jof, bigtable;
|
|
|
|
n := Length(list);
|
2017-10-25 17:26:21 +00:00
|
|
|
# Simple checks
|
2017-10-25 14:54:11 +00:00
|
|
|
if n < 1 then
|
2017-10-25 14:18:35 +00:00
|
|
|
Error("Usage: Cannot take DirectProduct of zero items.");
|
2017-10-25 17:26:21 +00:00
|
|
|
elif n < 2 then
|
|
|
|
return list[1];
|
2017-10-25 14:47:09 +00:00
|
|
|
fi;
|
2017-10-25 14:18:35 +00:00
|
|
|
# See if we can handle all objects
|
2017-10-25 14:40:56 +00:00
|
|
|
for i in [2..n] do
|
2017-10-25 17:26:21 +00:00
|
|
|
if not HasMultiplicationTable(list[i]) then
|
2017-10-25 14:18:35 +00:00
|
|
|
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;
|
2017-10-27 01:27:32 +00:00
|
|
|
return LeftQuasigroupByMultiplicationTableNC(bigtable);
|
2017-10-25 14:18:35 +00:00
|
|
|
elif "IsRightQuasigroup" in jof then
|
2017-10-28 23:11:39 +00:00
|
|
|
if "IsRSelfDistributive" in jof then
|
2017-10-25 14:18:35 +00:00
|
|
|
if "IsElementwiseIdempotent" in jof then
|
|
|
|
return RightQuandleByMultiplicationTableNC(bigtable);
|
|
|
|
fi;
|
|
|
|
return RightRackByMultiplicationTableNC(bigtable);
|
|
|
|
fi;
|
2017-10-27 01:27:32 +00:00
|
|
|
return RightQuasigroupByMultiplicationTableNC(bigtable);
|
2017-10-25 14:18:35 +00:00
|
|
|
fi;
|
|
|
|
return MagmaByMultiplicationTable(bigtable);
|
|
|
|
end);
|