def METHOD_NAME(soft_constraints, soft_weights, hard_constraints=[], solver='ortools', verbose=1):
    # init with hard constraints
    assum_model = Model(hard_constraints)
    # make assumption indicators, add reified constraints
    ind = BoolVar(shape=len(soft_constraints), name="ind")
    for i,bv in enumerate(ind):
        assum_model += [bv.implies(soft_constraints[i])]
    # to map indicator variable back to soft_constraints
    indmap = dict((v,i) for (i,v) in enumerate(ind))
    assum_solver = SolverLookup.lookup(solver)(assum_model)
    if assum_solver.solve(assumptions=ind):
        if verbose:
            print("Unexpectedly, the model is SAT")
        return []
    ## ----------------- MODEL ------------------
    hs_mip_model = Model(
        # Objective: min sum(x_l * w_l)
        minimize=sum(var * soft_weights[id] for id, var in enumerate(ind))
    )
    # instantiate hitting set solver
    hittingset_solver = SolverLookup.lookup(solver)(hs_mip_model)
    while(True):
        hittingset_solver.solve()
        # Get hitting set
        hs = ind[ind.value() == 1]
        if not assum_solver.solve(assumptions=hs):
            if verbose > 1:
                cost = sum([soft_weights[indmap[v]] for v in hs])
                print("\t hitting set with cost", cost, "is UNSAT:", [soft_constraints[indmap[v]] for v in hs])
            return [soft_constraints[indmap[v]] for v in hs]
        if verbose > 1:
            cost = sum([soft_weights[indmap[v]] for v in hs])
            print("\t hitting set with cost", cost, "is SAT:", [soft_constraints[indmap[v]] for v in hs])
        # compute complement of model in formula F
        C = set(v for v in ind if not v.value())
        # Add complement as a new set to hit: sum x[j] * hij >= 1
        hittingset_solver += (sum(C) >= 1)