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

View File

@ -2,13 +2,14 @@
## Create structures with generators
InstallGlobalFunction(CloneOfTypeByGenerators,
function(cat, fam, gens, genAttrib)
function(cat, fam, gens, genAttrib, tableCstr),
local M;
if not(IsEmpty(gens) or IsIdenticalObj(FamilyObj(gens), fam)) then
Error("<fam> and family of <gens> do not match");
fi;
M := Objectify(NewType( fam, cat and IsAttributeStoringRep), rec());
Setter(genAttrib)(M, AsList(gens));
SetConstructorFromTable(M, tableCstr);
return M;
end);
@ -28,7 +29,8 @@ InstallGlobalFunction(LeftQuasigroup, function(arg)
fam := FamilyObj(arg[1]);
fi;
return CloneOfTypeByGenerators(IsLeftQuasigroup, fam, arg,
GeneratorsOfLeftQuasigroup);
GeneratorsOfLeftQuasigroup,
LeftQuasigroupByMultiplicationTable);
end);
InstallGlobalFunction(LeftRack, function(arg)
@ -46,7 +48,8 @@ InstallGlobalFunction(LeftRack, function(arg)
fam := FamilyObj(arg[1]);
fi;
return CloneOfTypeByGenerators(IsLeftRack, fam, arg,
GeneratorsOfLeftQuasigroup);
GeneratorsOfLeftQuasigroup,
LeftRackByMultiplicationTableNC);
end);
InstallGlobalFunction(RightQuasigroup, function(arg)
@ -64,7 +67,8 @@ InstallGlobalFunction(RightQuasigroup, function(arg)
fam := FamilyObj(arg[1]);
fi;
return CloneOfTypeByGenerators(IsRightQuasigroup, fam, arg,
GeneratorsOfRightQuasigroup);
GeneratorsOfRightQuasigroup,
RightQuasigroupByMultiplicationTable);
end);
InstallGlobalFunction(RightRack, function(arg)
@ -82,9 +86,29 @@ InstallGlobalFunction(RightRack, function(arg)
fam := FamilyObj(arg[1]);
fi;
return CloneOfTypeByGenerators(IsRightRack, fam, arg,
GeneratorsOfRightQuasigroup);
GeneratorsOfRightQuasigroup,
RightRackByMultiplicationTableNC);
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
InstallGlobalFunction(LeftQuasigroupByMultiplicationTable,
function(T)
@ -99,7 +123,60 @@ InstallGlobalFunction(LeftQuasigroupByMultiplicationTable,
);
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,
"for two elts in magma by mult table, when left has left quotients",
@ -112,24 +189,49 @@ InstallOtherMethod(LeftQuotient,
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 a family with a multiplication table",
[IsFamily and HasMultiplicationTable],
"for an object with a multiplication table",
[HasMultiplicationTable],
function(fam)
local LS, n;
LS := LeftSectionList(fam);
LS := LeftPerms(fam);
n := Size(LS);
return List(LS, x->ListPerm(Inverse(x), n));
end);
## Create section lists as needed
InstallMethod(LeftSectionList,
"for a family with a multiplication table",
[IsFamily and HasMultiplicationTable],
InstallMethod(RightDivisionTable,
"for an object with a multiplication table",
[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)
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);