Some details about the implementation of homalg
Presentations
A presentation of a module in the current Maple implementation of
homalg is a list
containing as first entry the list of generators and as second entry the list
of relations. The third entry is a string delimiter to optically indicate the
end of the presentation. This string, unless changed by the user, defaults to
"Presentation". The remaining entries provide extra information about
the presented module, e.g. its Hilbert series in case the ring is the
polynomial ring. This extra information can only be provided by the
ring-specific package.
For M = coker(M) = R1 x l0 /
R1 x l1 M the list of the concrete
generators are numbered by abstract generators being the l0
standard basis row vectors of the underlying free module R1 x
l0. The list of relations simply contains the rows of
the matrix M. For illustrations see the Library of
Examples.
The morphism part of functors
The name convention for functors used in the Maple implementation of
homalg is as follows: If the procedure implementing the object part of
a functor is called F, then the procedure implementing the morphism
part is called FMap. It is defined using the procedure
FunctorMap applied to the
object part procedure F. The several pieces of code for the morphism
part of the functors
Cokernel,
Kernel,
DefectOfHoms
and Hom_R,
and the two bifunctors
TensorProduct
and Hom, reproduced below,
demonstrate how
FunctorMap unifies the
definition of the morphism part of all functors in homalg.
In future implementations of homalg the two procedures implementing the
object and morphism part of a functor will be unified in one. The unified
procedure will be able to recognize if it has been applied to an object, to a
morphism or even to complexes. This will be an easy task, once we strictly use
structures throughout homalg.
Encapsulating functors
A functor is fully defined when both parts are defined, i.e. its object part
and its morphism part. If the functor is a multi-functor, then several
morphism parts have to be defined. homalg accesses all these parts of a
functor via a so called encapsulation. It incorporates both parts and also
takes care of the possible multi-functoriality. The implementation of the
encapsulations of the functors
Hom_R,
TensorProduct,
and
Hom
can be viewed below.
Composition of functors
Composing two functors is an easy task
since one simply has to compose their actions on objects and on morphisms. The
procedure responsible for this is called ComposeFunctors. The
implementation of the composition of the functors
HomHom_R
and
HomHom can be viewed below.
Applying functors to complexes
Functors should be applied to
complexes of modules, rather than to single modules. Thereby homalg
again makes use of the encapsulation of functors. In this implementation,
there are two procedures depending on whether one is dealing with a covariant
or a contravariant functor. They are called FunctorOnSeqs and
CofunctorOnSeqs. The implementation of the functors
Hom
and
HomHom
on complexes can be viewed below.
Derivation of functors
The left derivation procedure for covariant functors is called
LeftDerivedFunctor.
The faster derivation procedure for right exact functors, for example
− ⊗ L, is called
LeftDerivedRightExactFunctor.
The right derivation procedure for contravariant functors is called
RightDerivedCofunctor. The faster derivation procedure for left exact
contravariant functors, for example
Hom(−, L), is called
RightDerivedLeftExactCofunctor.
The implementation of the left derived functor
LHomHom
(of HomHom with respect to its first argument) and the right derived
functor
Ext
(of Hom with respect to its first argument) can be viewed below.
How FunctorMap works
Let F denote the object part procedure of a functor F. First
FunctorMap asks F if the underlying functor is co- or
contravariant. If F is homalg-basic it has to know the answer
itself. If F is defined as a composition F1 o
F2 then the
question is passed to the procedure ComposeFunctors, which decides the
answer by asking F1 and
F2 (this is recursive). If F is defined as
a derivation Lq G or
Rq G, using one of the derivation procedures,
then F passes the question to the latter, which decides the answer by
asking G (this is recursive). Any recursion ends when a
homalg-basic functor is reached.
FunctorMap then asks F if it is defined using the procedure
ComposeFunctors. If F is homalg-basic it ignores the
question. If F is defined using one of the derivation procedures, the
question is passed to the latter, which ignores it. If F is indeed
defined as a composition F1 o F2,
then F passes the question to
ComposeFunctors, which returns the two functors
F1 and F2 in both
their parts. FunctorMap can now easily construct the morphism part of
F by composing the morphism parts of F1 and
F2. In case F is not
defined as a composition, FunctorMap asks it if is defined by
derivation. If F is homalg-basic it ignores the question. If
F is indeed defined as a derivation Lq G or
Rq G, using one of the
derivation procedures, then F passes the question to the latter, which
returns the functor G in both its parts and a procedure based on
ResolutionOfSeq to compute φq out of φ.
With these two ingredients FunctorMap is able to
construct the morphism part of F.
If F is defined neither by composition nor by derivation, i.e. its is
homalg-basic, then it is asked by FunctorMap to
return its hull functor HullF together with the natural
embedding. Again this suffices to
construct the morphism part of F.
Functors producing subfactor modules
How to use FunctorMap to define the morphism part
CokernelMap of the functor Cokernel in
the Maple implementation:
`homalg/CokernelMap` := proc(alpha1,A,phi,beta1,B,var,RingPackage) ### Main: "Functors"
local RP, nar, opts, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[7..-1-nar];
#=====# begin of the core procedure #=====#
functor := `homalg/Cokernel`;
`homalg/FunctorMap`(functor,
[alpha1,A], phi, [beta1,B]
,var,optional,RP)
end:
How to use FunctorMap to define the morphism part
KernelMap of the functor Kernel in
the Maple implementation:
`homalg/KernelMap` := proc(A,alpha2,_A,psi,B,beta2,_B,var,RingPackage) ### Main: "Functors"
local RP, nar, opts, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[9..-1-nar];
#=====# begin of the core procedure #=====#
functor := `homalg/Kernel`;
`homalg/FunctorMap`(functor,
[A,alpha2,_A], psi, [B,beta2,_B]
,var,optional,RP)
end:
How to use FunctorMap to define the morphism part
TorsionSubmoduleMap of the functor TorsionSubmodule in
the Maple implementation:
`homalg/TorsionSubmoduleMap` := proc(M,phi,N,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[5..-1-nar];
#=====# begin of the core procedure #=====#
functor := `homalg/TorsionSubmodule`;
`homalg/FunctorMap`(functor,
[M], phi, [N]
,var,optional,RP)
end:
Other types of basic functors
The functors Cokernel and Kernel
are special cases of the functor DefectOfHoms.
How to use FunctorMap to define the morphism part
DefectOfHomsMap of the functor DefectOfHoms in
the Maple implementation:
`homalg/DefectOfHomsMap` :=
proc(alpha1,A,alpha2,_A,phi,beta1,B,beta2,_B,var,RingPackage) ### Main: "Functors"
local RP, nar, opts, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[11..-1-nar];
#=====# begin of the core procedure #=====#
functor := `homalg/DefectOfHoms`;
`homalg/FunctorMap`(functor,
[alpha1,A,alpha2,_A], phi, [beta1,B,beta2,_B]
,var,optional,RP)
end:
TensorProduct(-,-) is a bifunctor, covariant in each argument.
How to use FunctorMap to define
TensorProductMap in the Maple implementation:
`homalg/TensorProductMap` := proc(M,phi,N,L,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[6..-1-nar];
#=====# begin of the core procedure #=====#
functor := proc(M) `homalg/TensorProduct`(M,L,args[1+1..-1]) end;
`homalg/FunctorMap`(functor,
[M], phi, [N]
,var,optional,RP)
end:
How to use FunctorMap to define
TensorProduct2Map in
the Maple implementation:
`homalg/TensorProduct2Map` := proc(L,M,phi,N,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[6..-1-nar];
#=====# begin of the core procedure #=====#
functor := proc(M) `homalg/TensorProduct`(L,M,args[1+1..-1]) end;
`homalg/FunctorMap`(functor,
[M], phi, [N]
,var,optional,RP)
end:
How to use FunctorMap to define HomMap_R in
the Maple implementation:
`homalg/HomMap_R` := proc(M,phi,N,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, cofunctor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then
RETURN(RP(args[1..-1-nar]))
fi;
optional := args[5..-1-nar];
#=====# begin of the core procedure #=====#
cofunctor := `homalg/Hom_R`;
`homalg/FunctorMap`(cofunctor,
[M], phi, [N]
,var,optional,RP)
end:
Hom(-,-) is a bifunctor, contravariant in its first
and covariant in its second argument.
How to use FunctorMap to define HomMap in
the Maple implementation:
`homalg/HomMap` := proc(M,phi,N,L,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, cofunctor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[6..-1-nar];
#=====# begin of the core procedure #=====#
cofunctor := proc(M) `homalg/Hom`(M,L,args[1+1..-1]) end;
`homalg/FunctorMap`(cofunctor,
[M], phi, [N]
,var,optional,RP)
end:
How to use FunctorMap to define Hom2Map in
the Maple implementation:
`homalg/Hom2Map` := proc(L,M,phi,N,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[6..-1-nar];
#=====# begin of the core procedure #=====#
functor := proc(M) `homalg/Hom`(L,M,args[1+1..-1]) end;
`homalg/FunctorMap`(functor,
[M], phi, [N]
,var,optional,RP)
end:
Encapsulating functors
Here we demonstrate the simplest form of encapsulation.
How to encapsulate the functor Hom_R in the Maple implementation:
`homalg/Functor_Hom_R` := proc() ### Main: "Functors"
[ `homalg/Hom_R`,
`homalg/HomMap_R` ]
end:
We show how to encapsulate the functor TensorProduct in
the Maple implementation.
This encapsulation takes care of the bi-functoriality of
TensorProduct(-,-):
`homalg/Functor_TensorProduct` := proc(B) ### Main: "Functors"
[ proc(M) `homalg/TensorProduct`(M,B,args[1+1..-1]) end,
proc(M,phi,N) `homalg/TensorProductMap`(M,phi,N,B,args[3+1..-1]) end,
## take care of multi-functoriality:
B,
proc(P)
proc(M,phi,N) `homalg/TensorProduct2Map`(P,M,phi,N,args[3+1..-1]) end
end ]
end:
Next we show how to encapsulate the functor Hom in the Maple
implementation.
This encapsulation takes care of the bi-functoriality of Hom(-,-):
`homalg/Functor_Hom` := proc(B) ### Main: "Functors"
[ proc(M) `homalg/Hom`(M,B,args[1+1..-1]) end,
proc(M,phi,N) `homalg/HomMap`(M,phi,N,B,args[3+1..-1]) end,
## take care of multi-functoriality:
B,
proc(P)
proc(M,phi,N) `homalg/Hom2Map`(P,M,phi,N,args[3+1..-1]) end
end ]
end:
Composition of functors
Composing functors is an easy task in homalg.
The procedure responsible for this is called ComposeFunctors.
Here we demonstrate this by two examples.
The object part of the functor HomHom_R is defined by using
ComposeFunctors in the Maple implementation:
`homalg/HomHom_R` := proc(M,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, cofunctor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[3..-1-nar];
#=====# begin of the core procedure #=====#
cofunctor := `homalg/Functor_Hom_R`();
eval(
`homalg/ComposeFunctors`(cofunctor,cofunctor,var,optional,RP)(M,var,RP)
)
end:
HomHom_R is a covariant functor.
The morphism part is defined by using
FunctorMap in the Maple implementation:
`homalg/HomHomMap_R` := proc(M,phi,N,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[5..-1-nar];
#=====# begin of the core procedure #=====#
functor := `homalg/HomHom_R`;
`homalg/FunctorMap`(functor,
[M], phi, [N]
,var,optional,RP)
end:
How to encapsulate the functor HomHom_R in the Maple implementation:
`homalg/Functor_HomHom_R` := proc() ### Main: "Functors"
[ `homalg/HomHom_R`,
`homalg/HomHomMap_R` ]
end:
The object part of the functor HomHom is defined by using
ComposeFunctors in the Maple implementation:
`homalg/HomHom` := proc(M,A,B,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, cofunctor1, cofunctor2;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[5..-1-nar];
#=====# begin of the core procedure #=====#
cofunctor1 := `homalg/Functor_Hom`(B);
cofunctor2 := `homalg/Functor_Hom`(A);
eval(
homalg/ComposeFunctors`(cofunctor1,cofunctor2,var,optional,RP)(M,var,RP)
)
end:
HomHom is a tri-functor, covariant in the first and
third and contravariant in the second argument. We show how to use
FunctorMap to define the morphism part of HomHomMap in
the Maple implementation:
`homalg/HomHomMap` := proc(M,phi,N,A,B,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[7..-1-nar];
#=====# begin of the core procedure #=====#
functor := proc(M) `homalg/HomHom`(M,A,B,args[1+1..-1]) end;
`homalg/FunctorMap`(functor,
[M], phi, [N]
,var,optional,RP)
end:
How to use FunctorMap to define HomHom2Map in
the Maple implementation:
`homalg/HomHom2Map` := proc(A,M,phi,N,B,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, cofunctor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[7..-1-nar];
#=====# begin of the core procedure #=====#
cofunctor := proc(M) `homalg/HomHom`(A,M,B,args[1+1..-1]) end;
`homalg/FunctorMap`(cofunctor,
[M], phi, [N]
,var,optional,RP)
end:
How to use FunctorMap to define HomHom3Map in
the Maple implementation:
`homalg/HomHom3Map` := proc(A,B,M,phi,N,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[7..-1-nar];
#=====# begin of the core procedure #=====#
functor := proc(M) `homalg/HomHom`(A,B,M,args[1+1..-1]) end;
`homalg/FunctorMap`(functor,
[M], phi, [N]
,var,optional,RP)
end:
How to encapsulate the functor HomHom in the Maple implementation:
`homalg/Functor_HomHom` := proc(A,B) ### Main: "Functors"
[ proc(M) `homalg/HomHom`(M,A,B,args[1+1..-1]) end,
proc(M,phi,N) `homalg/HomHomMap`(M,phi,N,A,B,args[3+1..-1]) end,
## take care of multi-functoriality:
A,
proc(P)
proc(M,phi,N) `homalg/HomHom2Map`(P,M,phi,N,B,args[3+1..-1]) end
end,
B,
proc(P)
proc(M,phi,N) `homalg/HomHom3Map`(P,A,M,phi,N,args[3+1..-1]) end
end ]
end:
Derivation of functors
We show how to use CofunctorOnSeqs to define HomOnSeqs in
the Maple implementation.
Here we use the above defined encapsulation:
`homalg/HomOnSeqs` := proc(L,alpha::{table,list},_var,RingPackage) ### Main: "Complexes"
local RP, nar, cofunctor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
#=====# begin of the core procedure #=====#
cofunctor := `homalg/Functor_Hom`(L);
`homalg/CofunctorOnSeqs`(cofunctor,args[1+1..-1])
end:
Next we show how to use FunctorOnSeqs to define HomHomOnSeqs in
the Maple implementation.
Again we use the above defined encapsulation:
`homalg/HomHomOnSeqs` := proc(A,B,alpha::{table,list},_var,RingPackage) ### Main: "Complexes"
local RP, nar, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
#=====# begin of the core procedure #=====#
functor := `homalg/Functor_HomHom`(A,B);
`homalg/FunctorOnSeqs`(functor,args[2+1..-1])
end:
The following procedures define the tri-functor LHomHom in
the Maple implementation. For the object part of LHomHom we
use LeftDerivedFunctor:
`homalg/LHomHom` := proc(q::nonnegint,M,A,B,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[6..-1-nar];
#=====# begin of the core procedure #=====#
functor := `homalg/Functor_HomHom`(A,B);
`homalg/LeftDerivedFunctor`(
q,functor,M
,var,optional,RP)
end:
How to use FunctorMap to define LHomHomMap in
the Maple implementation:
`homalg/LHomHomMap` := proc(q,M,phi,N,A,B,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[8..-1-nar];
#=====# begin of the core procedure #=====#
functor := proc(M) `homalg/LHomHom`(q,M,A,B,args[1+1..-1]) end;
`homalg/FunctorMap`(functor,
[M], phi, [N]
,var,optional,RP)
end:
How to use FunctorMap to define LHomHom2Map in
the Maple implementation:
`homalg/LHomHom2Map` := proc(q,A,M,phi,N,B,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, cofunctor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[8..-1-nar];
#=====# begin of the core procedure #=====#
cofunctor := proc(M) `homalg/LHomHom`(q,A,M,B,args[1+1..-1]) end;
`homalg/FunctorMap`(cofunctor,
[M], phi, [N]
,var,optional,RP)
end:
How to use FunctorMap to define LHomHom3Map in
the Maple implementation:
`homalg/LHomHom3Map` := proc(q,A,B,M,phi,N,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[8..-1-nar];
#=====# begin of the core procedure #=====#
functor := proc(M) `homalg/LHomHom`(q,A,B,M,args[1+1..-1]) end;
`homalg/FunctorMap`(functor,
[M], phi, [N]
,var,optional,RP)
end:
How to encapsulate the functor HomHom in the Maple implementation:
`homalg/Functor_LHomHom` := proc(q,A,B) ### Main: "Functors"
[ proc(M) `homalg/LHomHom`(q,M,A,B,args[1+1..-1]) end,
proc(M,phi,N) `homalg/LHomHomMap`(q,M,phi,N,A,B,args[3+1..-1]) end,
## take care of multi-functoriality:
A,
proc(P)
proc(M,phi,N) `homalg/LHomHom2Map`(q,P,M,phi,N,B,args[3+1..-1]) end
end,
B,
proc(P)
proc(M,phi,N) `homalg/LHomHom3Map`(q,P,A,M,phi,N,args[3+1..-1]) end
end ]
end:
How to use FunctorOnSeqs to define LHomHomOnSeqs in
the Maple implementation:
`homalg/LHomHomOnSeqs` := proc(q,A,B,alpha::{table,list},_var,RingPackage) ### Main: "Complexes"
local RP, nar, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
#=====# begin of the core procedure #=====#
functor := `homalg/Functor_LHomHom`(q,A,B);
`homalg/FunctorOnSeqs`(functor,args[3+1..-1])
end:
The following procedures define the bi-functor Ext in
the Maple implementation.
For the object part of Ext we use
RightDerivedLeftExactCofunctor:
`homalg/Ext` := proc(q::nonnegint,A,B,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, cofunctor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[5..-1-nar];
#=====# begin of the core procedure #=====#
cofunctor := `homalg/Functor_Hom`(B);
`homalg/RightDerivedLeftExactCofunctor`(
q,cofunctor,A
,var,optional,RP)
end:
How to use FunctorMap to define ExtMap in
the Maple implementation:
`homalg/ExtMap` := proc(q,M,phi,N,L,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, cofunctor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[7..-1-nar];
#=====# begin of the core procedure #=====#
cofunctor := proc(M) `homalg/Ext`(q,M,L,args[1+1..-1]) end;
`homalg/FunctorMap`(cofunctor,
[M], phi, [N]
,var,optional,RP)
end:
How to use FunctorMap to define Ext2Map in
the Maple implementation:
`homalg/Ext2Map` := proc(q,L,M,phi,N,var::list,RingPackage) ### Main: "Functors"
local RP, nar, optional, functor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then RETURN(RP(args[1..-1-nar])) fi;
optional := args[7..-1-nar];
#=====# begin of the core procedure #=====#
functor := proc(M) `homalg/Ext`(q,L,M,args[1+1..-1]) end;
`homalg/FunctorMap`(functor,
[M], phi, [N]
,var,optional,RP)
end:
How to encapsulate the functor Ext in the Maple implementation:
`homalg/Functor_Ext` := proc(q,B) ### Main: "Functors"
[ proc(M) `homalg/Ext`(q,M,B,args[1+1..-1]) end,
proc(M,phi,N) `homalg/ExtMap`(q,M,phi,N,B,args[3+1..-1]) end,
## take care of multi-functoriality:
B,
proc(P)
proc(M,phi,N) `homalg/Ext2Map`(q,P,M,phi,N,args[3+1..-1]) end
end ]
end:
How to use CofunctorOnSeqs to define ExtOnSeqs in
the Maple implementation:
`homalg/ExtOnSeqs` := proc(q,L,alpha::{table,list},_var,RingPackage) ### Main: "Complexes"
local RP, nar, cofunctor;
RP := `homalg/tablename`(procname,args[-1],nar);
if type(RP,procedure) then
RETURN(RP(args[1..-1-nar]))
fi;
#=====# begin of the core procedure #=====#
cofunctor := `homalg/Functor_Ext`(q,L);
`homalg/CofunctorOnSeqs`(cofunctor,args[2+1..-1])
end: