A |Homomorphism| object represents a homomorphism from a group of type |d_source| to a group of type |d_dest|. The essential data is a matrix |d_matrix| with integral coefficients. As usual the matrix entry (i,j) expresses component $i$ of the image of generator $j$.
For such a homomorphism to be well defined, the matrix entry (i,j) should be a multiple of |d_dest[i]/g|, with |g == gcd(d_dest[i],d_source[j])|.
Computationally we shall proceed as follows. We set $M$ to a common multiple of the annihilators of |d_source| and |d_dest|, and think of all cyclic groups as embedded in $Z/M$; this means that before acting upon a source element $(x_1,...,x_m)$ we should multiply each component $x_j$ by the cotype $q_j=M/s_j$ of that component with respect to $M$, where $s_j$ is |d_source[j]|. After forming $y_j= a_{i,j} q_j x_j$ for each $i$, the component $y_i$ must be in the subgroup of index $t_i$ in $Z/M$, where $t_i$ is |d_dest[i]|, in other words it must be divisible by $M/t_i$, and the compoentn $i$ of the final result will be $y_i/(M/t_i)$. This definition is independent of the choice of $M$; we will take the lcm of the annihilators.
In fact this definition might work for some group elements of the source but not for all. In that case we don't really have a homomorphism, but we allow applying to those group elements for which it works nontheless. The predicates |defined| serve to find out whether a source element is OK.