text: #include "Highs.h"
  #include "SpecialLps.h"
  #include "catch.hpp"
  
  const bool dev_run = false;
  
  TEST_CASE("PresolveSolvePostsolve", "[highs_test_presolve]") {
    Highs highs0;
    Highs highs1;
    if (!dev_run) {
      highs0.setOptionValue("output_flag", false);
      highs1.setOptionValue("output_flag", false);
    }
    std::string model_file =
        std::string(HIGHS_DIR) + "/check/instances/25fv47.mps";
    HighsStatus return_status;
    highs0.readModel(model_file);
    return_status = highs0.presolve();
    REQUIRE(return_status == HighsStatus::kOk);
    HighsPresolveStatus model_presolve_status = highs0.getModelPresolveStatus();
    if (model_presolve_status == HighsPresolveStatus::kTimeout) {
      if (dev_run)
        printf("Presolve timeout: return sttus = %d\n", (int)return_status);
    }
    HighsLp lp = highs0.getPresolvedLp();
    highs1.passModel(lp);
    highs1.setOptionValue("presolve", kHighsOffString);
    highs1.run();
    HighsBasis basis = highs1.getBasis();
    HighsSolution solution = highs1.getSolution();
    return_status = highs0.postsolve(solution, basis);
    REQUIRE(return_status == HighsStatus::kOk);
    HighsModelStatus model_status = highs0.getModelStatus();
    REQUIRE(model_status == HighsModelStatus::kOptimal);
  }
  
  TEST_CASE("Presolve", "[highs_test_presolve]") {
    Highs highs;
    if (!dev_run) highs.setOptionValue("output_flag", false);
  
    // Make sure that an empty LP returns kNotReduced
    const HighsModel& presolved_model = highs.getPresolvedModel();
    REQUIRE(highs.presolve() == HighsStatus::kOk);
    REQUIRE(highs.getModelPresolveStatus() == HighsPresolveStatus::kNotReduced);
  
    std::string model_file;
    model_file = std::string(HIGHS_DIR) + "/check/instances/adlittle.mps";
    highs.readModel(model_file);
    REQUIRE(highs.presolve() == HighsStatus::kOk);
    REQUIRE(highs.getModelPresolveStatus() == HighsPresolveStatus::kReduced);
    REQUIRE(!presolved_model.isEmpty());
  
    model_file = std::string(HIGHS_DIR) + "/check/instances/gas11.mps";
    highs.readModel(model_file);
    REQUIRE(highs.presolve() == HighsStatus::kOk);
    REQUIRE(highs.getModelPresolveStatus() ==
            HighsPresolveStatus::kUnboundedOrInfeasible);
    REQUIRE(presolved_model.isEmpty());
  
    HighsLp lp;
    HighsModelStatus require_model_status;
    double optimal_objective;
    SpecialLps special_lps;
  
    special_lps.scipLpi3Lp(lp, require_model_status);
    highs.passModel(lp);
    REQUIRE(highs.presolve() == HighsStatus::kOk);
    REQUIRE(highs.getModelPresolveStatus() == HighsPresolveStatus::kInfeasible);
    REQUIRE(highs.getModelStatus() == require_model_status);
    REQUIRE(presolved_model.isEmpty());
  
    special_lps.distillationLp(lp, require_model_status, optimal_objective);
    // Have to set matrix dimensions to match presolved_model.lp_
    lp.setMatrixDimensions();
    highs.passModel(lp);
    REQUIRE(highs.presolve() == HighsStatus::kOk);
    REQUIRE(lp.equalButForNames(presolved_model.lp_));
    // ToDo @leona this LP isn't reduced by presolve, so the model
    // presolve status should be HighsPresolveStatus::kNotReduced, but
    // is HighsPresolveStatus::kReduced
    //  REQUIRE(highs.getModelPresolveStatus() ==
    //  HighsPresolveStatus::kNotReduced);
    REQUIRE(highs.getModelPresolveStatus() == HighsPresolveStatus::kReduced);
    REQUIRE(highs.getModelStatus() == HighsModelStatus::kNotset);
    REQUIRE(!presolved_model.isEmpty());
  
    special_lps.primalDualInfeasible1Lp(lp, require_model_status);
    highs.passModel(lp);
    REQUIRE(highs.presolve() == HighsStatus::kOk);
    REQUIRE(highs.getModelPresolveStatus() == HighsPresolveStatus::kInfeasible);
    REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
    REQUIRE(presolved_model.isEmpty());
  }
  