Add constructors for the other one-sided quasigroups and racks.
This commit is contained in:
parent
1c8d3fbe52
commit
bc8c892898
|
@ -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");
|
||||||
|
|
132
gap/structure.gi
132
gap/structure.gi
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue