//  [python]
def writeMinDistanceLP(
    fname,
    fbas,
    work_dir=None,
    ignoreDistance=[],
    with_protein_cost=False,
    constraint_mode='strict',
    moma=False,
):
    if work_dir == None:
        work_dir = os.getcwd()

    fC = []
    objFname = ''
    for l in fbas:
        fC.append(len(l.reactions))
        objFname += l.prefix
    fC = numpy.array(fC)
    if __DEBUG__:
        print(fC)
        print((fC == fC[0]))
        print(numpy.alltrue((fC == fC[0])))
    if moma:
        assert len(fbas) == 2, '\nMOMA only defined for two inputs'
    else:
        assert numpy.alltrue(
            (fC == fC[0])
        ), '\nModels must have the same number of fluxes\n!'

    conL = []
    # model flux_bounds
    initial_cnstr = []

    if moma:
        initial_cnstr.append(BuildLPConstraintsStrict(fbas[0]))
        mt = fbas[1].clone()
        mt.setPrefix('mt_', 'all')
        initial_cnstr.append(BuildLPConstraintsStrict(mt))
        del mt
    else:
        for f in fbas:
            if constraint_mode == 'math':
                initial_cnstr.append(BuildLPConstraintsMath(f))
            elif constraint_mode == 'relaxed':
                initial_cnstr.append(BuildLPConstraintsRelaxed(f))
            else:
                initial_cnstr.append(BuildLPConstraintsStrict(f))

    for ib in initial_cnstr:
        ib.seek(0)
        for l in ib:
            conL.append(l.strip())
        conL.append(' ')
    del initial_cnstr

    bndL = []
    # model bounds
    initial_bnds = []
    for f in fbas:
        initial_bnds.append(BuildLPFluxBounds(f))
    for ib in initial_bnds:
        ib.seek(0)
        for l in ib:
            bndL.append(l.strip())
        bndL.append(' ')
    del initial_bnds

    artVar = []
    artVarX = []
    # ignoreDistance = []

    Combi = CBTools.ComboGen()
    Cnumber = 2
    Cdata = ''
    unique_combinations = None
    for x in range(len(fbas)):
        Cdata += '%s' % x
    if __DEBUG__:
        print(Cdata)

    Combi.uniqueCombinations(Cdata, Cnumber, temp=[])
    Combi.numberifyComb2Int()
    unique_combinations = Combi.combo_int

    if __DEBUG__:
        print('Data ({}):\n{}\n'.format(Cnumber, Cdata))
        print('UniqueCombinStr:\n{}'.format(Combi.combo))
        print('UniqueCombinations:\n{}'.format(unique_combinations))

    zbase = 0
    combcount = 1
    for uq in unique_combinations:
        if __DEBUG__:
            print(uq)
        MD0 = fbas[uq[0]]
        MD0 = fbas[uq[0]]
        if moma:
            MD1 = fbas[uq[1]].clone()
            MD1.setPrefix('mt_', 'all')
        else:
            MD1 = fbas[uq[1]]

        RiD1 = MD0.getReactionIds()
        RiD2 = MD1.getReactionIds()
        for s in range(len(MD0.reactions)):
            if __DEBUG__:
                print(RiD1[s], RiD2[s])
            if RiD1[s] not in ignoreDistance:
                if moma:
                    ridx2 = RiD2.index(MD1.prefix + RiD1[s])
                else:
                    ridx2 = s
                ##  av = 'z%s' % (zbase+s+1)
                av = 'zvar%s%s' % (combcount, RiD1[s].replace(MD0.prefix, ''))

                c1 = '%sa: %s - %s - %s <= 0.0' % (av, RiD1[s], RiD2[ridx2], av)
                ##  c1 = '%s - %s - %s <= 0.0' % (RiD1[s], RiD2[s], av)
                c2 = '%sb: %s - %s + %s >= 0.0' % (av, RiD1[s], RiD2[ridx2], av)
                ##  c2 = '%s - %s + %s >= 0.0' % (RiD1[s], RiD2[s], av)

                # add the protein cost
                if with_protein_cost:
                    av = '%s %s' % (MD0.reactions[s].annotation['CBM_PEPTIDE_COST'], av)
                artVar.append(av)
                conL.append(c1)
                conL.append(c2)

        combcount += 1
        zbase += len(MD0.reactions)

    objS = '%smulti: ' % objFname
    vcntr = 0
    for v in artVar:
        objS += '%s + ' % v
        vcntr += 1
        if vcntr >= 500:
            objS += '\n'
            vcntr = 0
    objS = objS[:-3]
    if len(artVarX) >= 1:
        objS += ' \\* Ignored: '
        for o in artVarX:
            objS += '%s ' % o
        objS += '*\\\n'
    objL = [objS]

    objFcnstr = [' ']
    assert (
        len(f.objectives[f.activeObjIdx].getFluxObjectiveReactions()) == 1
    ), "\nOnly single fluxObjectives dealt with at this time"
    if moma:
        f = fbas[0]
        objFcnstr.append(
            'C_%s: %s >= %f'
            % (
                f.objectives[f.activeObjIdx].getFluxObjectiveReactions()[0],
                f.objectives[f.activeObjIdx].getFluxObjectiveReactions()[0],
                f.objectives[f.activeObjIdx].value,
            )
        )
    else:
        for f in fbas:
            objFcnstr.append(
                'C_%s: %s >= %f'
                % (
                    f.objectives[f.activeObjIdx].getFluxObjectiveReactions()[0],
                    f.objectives[f.activeObjIdx].getFluxObjectiveReactions()[0],
                    f.objectives[f.activeObjIdx].value,
                )
            )
    conL = conL + objFcnstr

    if __DEBUG__:
        print(objL)
        for c in conL:
            print(c)
        print(' ')
        for b in bndL:
            print(b)

    F = open(os.path.join(work_dir, fname + '.lp'), 'w')
    header = '\\\\ MultiInputMinimization: '
    for f in fbas:
        header += '%s, ' % f.getId()
    F.write('%s\n' % header[:-2])
    F.write('\nMinimize\n')
    for o in objL:
        F.write('%s \n' % o)
    F.write('\nSubject to\n')
    for c in conL:
        F.write('%s \n' % c)
    F.write('\nBounds\n')
    for b in bndL:
        F.write(' %s \n' % b)
    F.write('END\n\n')
    F.close()
    print('LP written to: {}.lp'.format(os.path.join(work_dir, fname)))
    return os.path.join(work_dir, fname + '.lp')