<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def amalgamate(colcount, snode, snptr, snpar, snpost, merge_function):
 """ Supernodal amalgamation. amalgamate(colcount, snode, snptr, snpar, snpost, merge_function) PURPOSE Iterates over the clique tree in topological order and greedily merges a supernode with its parent if merge_function(|J_{par(k)}|, |J_k|, |N_{par(k)}|, |N_k|) returns True. ARGUMENTS colcount vector with column counts snode vector with supernodes snptr vector with offsets snpar vector with supernodal parent indices snpost vector with supernodal post ordering merge_function function RETURNS colcount vector with amalgamated column counts snode vector with amalgamated supernodes snptr vector with amalgamated offsets snpar vector with amalgamated supernodal parent indices snpost vector with amalgamated supernodal post ordering """

    N = len(snpost)
    ch = {}
    for j in snpost:
        if snpar[j] in ch: ch[snpar[j]].append(j)
        else: ch[snpar[j]] = [j]

    snlist = [snode[snptr[k]:snptr[k+1]] for k in range(N)]

    snpar_ = +snpar
    colcount_ = +colcount
    Ns = N
    for k in snpost:
        if snpar_[k] != k:
            colk = colcount_[snlist[k][0]]
            colp = colcount_[snlist[snpar_[k]][0]]
            nk = len(snlist[k])
            np = len(snlist[snpar_[k]])
            if merge_function and merge_function(colp,colk,np,nk):
                # merge supernode k and snpar[k]
                snlist[snpar_[k]] = matrix(sorted(list(snlist[k]) + list(snlist[snpar_[k]])))
                snlist[k] = None
                colcount_[snlist[snpar_[k]][0]] = colp + nk
                Ns -= 1
                if k in ch:
                    for c in ch[k]:
                        snpar_[c] = snpar_[k]
                    ch[snpar_[k]] += ch[k]
                snpar_[k] = k

    L = [i for i,s in enumerate(snlist) if s is not None]
    snptr_ = matrix(0,(len(L)+1,1))
    snode_ = +snode
    for i,l in enumerate(L):
        snptr_[i+1] = snptr_[i] + len(snlist[l])
        snode_[snptr_[i]:snptr_[i+1]] = snlist[l]

    snpar_ = snpar_[L]
    for i in range(len(snpar_)):
        snpar_[i] = L.index(snpar_[i])
    snpost_ = post_order(snpar_)
    return colcount_, snode_, snptr_, snpar_, snpost_