Add constructors for the other one-sided quasigroups and racks.

This commit is contained in:
Glen Whitney 2017-10-18 21:37:48 +02:00
parent 1c8d3fbe52
commit bc8c892898
2 changed files with 127 additions and 19 deletions

View File

@ -20,6 +20,10 @@ DeclareCategoryCollections("IsLSelfDistElement");
DeclareCategory("IsRSelfDistElement", IsMultiplicativeElement); DeclareCategory("IsRSelfDistElement", IsMultiplicativeElement);
DeclareCategoryCollections("IsRSelfDistElement"); DeclareCategoryCollections("IsRSelfDistElement");
# Predicates on tables:
DeclareProperty( "IsLeftSelfDistributiveTable", IsMatrix );
DeclareProperty( "IsRightSelfDistributiveTable", IsMatrix );
# Left self-distributive magmas: # Left self-distributive magmas:
DeclareProperty("IsLSelfDistributive", IsMagma); DeclareProperty("IsLSelfDistributive", IsMagma);
InstallTrueMethod(IsLSelfDistributive, InstallTrueMethod(IsLSelfDistributive,
@ -71,13 +75,15 @@ InstallImmediateMethod(GeneratorsOfMagma,
## And now, build them from multiplication tables ## And now, build them from multiplication tables
# Need attributes on the families to store the sections and division tables # Need attributes on the families to store the sections and division tables
DeclareAttribute("LeftSectionList", IsFamily and HasMultiplicationTable); DeclareAttribute("LeftPerms", HasMultiplicationTable);
DeclareAttribute("RightSectionList", IsFamily and HasMultiplicationTable); DeclareAttribute("RightPerms", HasMultiplicationTable);
DeclareAttribute("LeftDivisionTable", IsFamily and HasMultiplicationTable); DeclareAttribute("LeftDivisionTable", HasMultiplicationTable);
DeclareAttribute("RightDivisionTable", IsFamily and HasMultiplicationTable); DeclareAttribute("RightDivisionTable", HasMultiplicationTable);
# And the builders # And the builders
DeclareGlobalFunction("LeftQuasigroupByMultiplicationTable"); DeclareGlobalFunction("LeftQuasigroupByMultiplicationTable");
DeclareGlobalFunction("LeftRackByMultiplicationTable"); DeclareGlobalFunction("LeftRackByMultiplicationTable");
DeclareGlobalFunction("LeftRackByMultiplicationTableNC");
DeclareGlobalFunction("RightQuasigroupByMultiplicationTable"); DeclareGlobalFunction("RightQuasigroupByMultiplicationTable");
DeclareGlobalFunction("RightRackByMultiplicationTable"); DeclareGlobalFunction("RightRackByMultiplicationTable");
DeclareGlobalFunction("RightRackByMultiplicationTableNC");

View File

@ -2,13 +2,14 @@
## Create structures with generators ## Create structures with generators
InstallGlobalFunction(CloneOfTypeByGenerators, InstallGlobalFunction(CloneOfTypeByGenerators,
function(cat, fam, gens, genAttrib) function(cat, fam, gens, genAttrib, tableCstr),
local M; local M;
if not(IsEmpty(gens) or IsIdenticalObj(FamilyObj(gens), fam)) then if not(IsEmpty(gens) or IsIdenticalObj(FamilyObj(gens), fam)) then
Error("<fam> and family of <gens> do not match"); Error("<fam> and family of <gens> do not match");
fi; fi;
M := Objectify(NewType( fam, cat and IsAttributeStoringRep), rec()); M := Objectify(NewType( fam, cat and IsAttributeStoringRep), rec());
Setter(genAttrib)(M, AsList(gens)); Setter(genAttrib)(M, AsList(gens));
SetConstructorFromTable(M, tableCstr);
return M; return M;
end); end);
@ -28,7 +29,8 @@ InstallGlobalFunction(LeftQuasigroup, function(arg)
fam := FamilyObj(arg[1]); fam := FamilyObj(arg[1]);
fi; fi;
return CloneOfTypeByGenerators(IsLeftQuasigroup, fam, arg, return CloneOfTypeByGenerators(IsLeftQuasigroup, fam, arg,
GeneratorsOfLeftQuasigroup); GeneratorsOfLeftQuasigroup,
LeftQuasigroupByMultiplicationTable);
end); end);
InstallGlobalFunction(LeftRack, function(arg) InstallGlobalFunction(LeftRack, function(arg)
@ -46,7 +48,8 @@ InstallGlobalFunction(LeftRack, function(arg)
fam := FamilyObj(arg[1]); fam := FamilyObj(arg[1]);
fi; fi;
return CloneOfTypeByGenerators(IsLeftRack, fam, arg, return CloneOfTypeByGenerators(IsLeftRack, fam, arg,
GeneratorsOfLeftQuasigroup); GeneratorsOfLeftQuasigroup,
LeftRackByMultiplicationTableNC);
end); end);
InstallGlobalFunction(RightQuasigroup, function(arg) InstallGlobalFunction(RightQuasigroup, function(arg)
@ -64,7 +67,8 @@ InstallGlobalFunction(RightQuasigroup, function(arg)
fam := FamilyObj(arg[1]); fam := FamilyObj(arg[1]);
fi; fi;
return CloneOfTypeByGenerators(IsRightQuasigroup, fam, arg, return CloneOfTypeByGenerators(IsRightQuasigroup, fam, arg,
GeneratorsOfRightQuasigroup); GeneratorsOfRightQuasigroup,
RightQuasigroupByMultiplicationTable);
end); end);
InstallGlobalFunction(RightRack, function(arg) InstallGlobalFunction(RightRack, function(arg)
@ -82,9 +86,29 @@ InstallGlobalFunction(RightRack, function(arg)
fam := FamilyObj(arg[1]); fam := FamilyObj(arg[1]);
fi; fi;
return CloneOfTypeByGenerators(IsRightRack, fam, arg, return CloneOfTypeByGenerators(IsRightRack, fam, arg,
GeneratorsOfRightQuasigroup); GeneratorsOfRightQuasigroup,
RightRackByMultiplicationTableNC);
end); end);
## 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);
## And now create them from multiplication tables ## And now create them from multiplication tables
InstallGlobalFunction(LeftQuasigroupByMultiplicationTable, InstallGlobalFunction(LeftQuasigroupByMultiplicationTable,
function(T) function(T)
@ -99,7 +123,60 @@ InstallGlobalFunction(LeftQuasigroupByMultiplicationTable,
); );
end); end);
## And define the operation InstallGlobalFunction(RightQuasigroupByMultiplicationTable,
function(T)
if not IsRightQuasigroupTable(T) then
Error("Multiplication table <T> must have each column a permutation of ",
"the same entries.");
fi;
return MagmaByMultiplicationTableCreatorNC(
CanonicalCayleyTable(T),
RightQuasigroup,
IsRightQuotientElement and IsMagmaByMultiplicationTableObj
);
end);
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 LeftRackByMulitplicationTableNC(T);
end);
InstallGlobalFunction(LeftRackByMulitplicationTableNC,
T -> MagmaByMultiplicationTableCreatorNC(T, LeftRack,
IsLeftQuotientElement and IsLSelfDistributiveElement and
IsMagmaByMultiplicationTableObj
);
);
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,
T -> MagmaByMultiplicationTableCreatorNC(T, RightRack,
IsRightQuotientElement and IsRSelfDistributiveElement and
IsMagmaByMultiplicationTableObj
);
);
## And define the operations
InstallOtherMethod(LeftQuotient, InstallOtherMethod(LeftQuotient,
"for two elts in magma by mult table, when left has left quotients", "for two elts in magma by mult table, when left has left quotients",
@ -112,24 +189,49 @@ InstallOtherMethod(LeftQuotient,
return fam!.set[ix]; return fam!.set[ix];
end); 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 ## Create division tables as needed
InstallMethod(LeftDivisionTable, InstallMethod(LeftDivisionTable,
"for a family with a multiplication table", "for an object with a multiplication table",
[IsFamily and HasMultiplicationTable], [HasMultiplicationTable],
function(fam) function(fam)
local LS, n; local LS, n;
LS := LeftSectionList(fam); LS := LeftPerms(fam);
n := Size(LS); n := Size(LS);
return List(LS, x->ListPerm(Inverse(x), n)); return List(LS, x->ListPerm(Inverse(x), n));
end); end);
## Create section lists as needed InstallMethod(RightDivisionTable,
InstallMethod(LeftSectionList, "for an object with a multiplication table",
"for a family with a multiplication table", [HasMultiplicationTable],
[IsFamily and HasMultiplicationTable], function (obj)
local RS, n;
RS := RightPerms(fam);
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) function(fam)
return List(MultiplicationTable(fam), x->PermList(x)); return List(MultiplicationTable(fam), x->PermList(x));
end); end);
InstallMethod(RightPerms,
"for an object with a muliplication table",
[HasMultiplicationTable],
function(fam)
return List(TransposedMat(MultiplicationTable(fam)), x->PermList(x));
end);