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: