(blst)
return True
blst is a list of integers [i_{1},...,i_{r}] representing the geometric
        product of r basis vectors a_{{i_1}}*...*a_{{i_r}}.  reduce_basis_loop
        searches along the list [i_{1},...,i_{r}] untill it finds i_{j} == i_{j+1}
        and in this case contracts the list, or if i_{j} > i_{j+1} it revises
        the list (~i_{j} means remove i_{j} from the list)

        Case 1: If i_{j} == i_{j+1}, return a_{i_{j}}**2 and
                [i_{1},..,~i_{j},~i_{j+1},...,i_{r}]

        Case 2: If i_{j} > i_{j+1}, return a_{i_{j}}.a_{i_{j+1}},
                [i_{1},..,~i_{j},~i_{j+1},...,i_{r}], and
                [i_{1},..,i_{j+1},i_{j},...,i_{r}]
blst is a list of integers [i_{1},...,i_{r}] representing the geometric
        product of r basis vectors a_{{i_1}}*...*a_{{i_r}}.  reduce_basis_loop
        searches along the list [i_{1},...,i_{r}] untill it finds i_{j} == i_{j+1}
        and in this case contracts the list, or if i_{j} > i_{j+1} it revises
        the list (~i_{j} means remove i_{j} from the list)
blst is a list of integers [ i_ { 1 } ... i_ { r } ] representing the geometric product of r basis vectors a_ {{ i_1 }} * ... * a_ {{ i_r }} . reduce_basis_loop searches along the list [ i_ { 1 } ... i_ { r } ] untill it finds i_ { j } == i_ { j + 1 } and in this case contracts the list or if i_ { j } > i_ { j + 1 } it revises the list ( ~i_ { j } means remove i_ { j } from the list )
def reduce_basis_loop(blst):
        """
        blst is a list of integers [i_{1},...,i_{r}] representing the geometric
        product of r basis vectors a_{{i_1}}*...*a_{{i_r}}.  reduce_basis_loop
        searches along the list [i_{1},...,i_{r}] untill it finds i_{j} == i_{j+1}
        and in this case contracts the list, or if i_{j} > i_{j+1} it revises
        the list (~i_{j} means remove i_{j} from the list)

        Case 1: If i_{j} == i_{j+1}, return a_{i_{j}}**2 and
                [i_{1},..,~i_{j},~i_{j+1},...,i_{r}]

        Case 2: If i_{j} > i_{j+1}, return a_{i_{j}}.a_{i_{j+1}},
                [i_{1},..,~i_{j},~i_{j+1},...,i_{r}], and
                [i_{1},..,i_{j+1},i_{j},...,i_{r}]
        """
        nblst = len(blst)  # number of basis vectors
        if nblst <= 1:
            return True  # a scalar or vector is already reduced
        jstep = 1
        while jstep < nblst:
            istep = jstep - 1
            if blst[istep] == blst[jstep]:  # basis vectorindex is repeated
                i = blst[istep]  # save basis vector index
                if len(blst) > 2:
                    blst = blst[:istep] + blst[jstep + 1:]  # contract blst
                else:
                    blst = []
                if len(blst) <= 1 or jstep == nblst - 1:
                    blst_flg = True  # revision of blst is complete
                else:
                    blst_flg = False  # more revision needed
                return MV.metric[i, i], blst, blst_flg
            if blst[istep] > blst[jstep]:  # blst not in normal order
                blst1 = blst[:istep] + blst[jstep + 1:]  # contract blst
                a1 = MV.metric2[blst[jstep], blst[istep]]  # coef of contraction
                blst = blst[:istep] + [blst[jstep]] + [blst[istep]] + blst[jstep + 1:]  # revise blst
                if len(blst1) <= 1:
                    blst1_flg = True  # revision of blst is complete
                else:
                    blst1_flg = False  # more revision needed
                return a1, blst1, blst1_flg, blst
            jstep += 1
        return True
def reduce_basis_loop ( blst ) : nblst = len ( blst ) # number of basis vectors if nblst <= 1 : return True # a scalar or vector is already reduced jstep = 1 while jstep < nblst : istep = jstep - 1 if blst [ istep ] == blst [ jstep ] : # basis vectorindex is repeated i = blst [ istep ] # save basis vector index if len ( blst ) > 2 : blst = blst [ : istep ] + blst [ jstep + 1 : ] # contract blst else : blst = [ ] if len ( blst ) <= 1 or jstep == nblst - 1 : blst_flg = True # revision of blst is complete else : blst_flg = False # more revision needed return MV . metric [ i , i ] , blst , blst_flg if blst [ istep ] > blst [ jstep ] : # blst not in normal order blst1 = blst [ : istep ] + blst [ jstep + 1 : ] # contract blst a1 = MV . metric2 [ blst [ jstep ] , blst [ istep ] ] # coef of contraction blst = blst [ : istep ] + [ blst [ jstep ] ] + [ blst [ istep ] ] + blst [ jstep + 1 : ] # revise blst if len ( blst1 ) <= 1 : blst1_flg = True # revision of blst is complete else : blst1_flg = False # more revision needed return a1 , blst1 , blst1_flg , blst jstep += 1 return True