"""Punkt 1: dasselbe Programm mit geänderten Daten neu rechnen – ohne LLM-Aufruf.""" import pytest from core.model_schema import SolverStatus from solving.solver_stage import run_solver_code # Programm nach der Vorgabe des Solver-Prompts: alle Zahlen stehen in DATA DATA_CODE = ''' from scipy.optimize import linprog DATA = { "kosten": [3, 2], # Kosten je Tonne [Tsd. €] "bedarf": 4, # Mindestmenge [t] "obergrenze": 3, # je Rohstoff lieferbar [t] } def solve_model(): """Baut das LP aus DATA auf und löst es.""" grenze = DATA["obergrenze"] return linprog(DATA["kosten"], A_ub=[[-1, -1]], b_ub=[-DATA["bedarf"]], bounds=[(0, grenze), (0, grenze)], method="highs") def main(): """Löst das Modell und meldet Ergebnis samt Restriktionen.""" res = solve_model() x, y = float(res.x[0]), float(res.x[1]) report("optimal" if res.status == 0 else "error", float(res.fun), {"x": x, "y": y}, constraints=[{"name": "Bedarf", "lhs": x + y, "sense": ">=", "rhs": DATA["bedarf"]}], variables=[{"name": "x", "value": x, "var_type": "continuous", "lb": 0, "ub": DATA["obergrenze"]}]) if __name__ == "__main__": main() ''' def test_run_without_override_uses_own_data(): run = run_solver_code(DATA_CODE) assert run.status == SolverStatus.OPTIMAL assert run.objective_value == pytest.approx(9) # 1t * 3 + 3t * 2 assert run.data["bedarf"] == 4 def test_changed_data_is_used_without_touching_the_code(): run = run_solver_code(DATA_CODE, data={"bedarf": 5}) assert run.status == SolverStatus.OPTIMAL assert run.objective_value == pytest.approx(12) # 2t * 3 + 3t * 2 assert run.data["bedarf"] == 5 and run.data["kosten"] == [3, 2] # nur der geänderte Wert wird ersetzt def test_constraints_follow_the_changed_data(): run = run_solver_code(DATA_CODE, data={"bedarf": 5}) assert run.constraints[0].rhs == 5 def test_infeasible_data_is_reported_not_crashing(): run = run_solver_code(DATA_CODE, data={"bedarf": 99}) assert run.status in (SolverStatus.ERROR, SolverStatus.INFEASIBLE) # --- CLI-Modus: gespeichertes Ergebnis neu rechnen --- def gespeichertes_ergebnis(tmp_path): import json from core.model_schema import PipelineResult, SolverCode from test_model_checks import make_spec from test_review import make_review result = PipelineResult(task="Aufgabe", specification=make_spec(), review=make_review(), revisions=0, solver_code=SolverCode(code=DATA_CODE)) pfad = tmp_path / "ergebnis.json" pfad.write_text(result.model_dump_json(indent=2), encoding="utf-8") return pfad def test_resolve_without_data_reproduces_the_result(tmp_path): from TextToModel import resolve_result neu = resolve_result(str(gespeichertes_ergebnis(tmp_path))) assert neu.solver_run.objective_value == pytest.approx(9) assert neu.reliable and neu.usage is None # kein LLM-Aufruf def test_resolve_with_changed_data(tmp_path): import json from TextToModel import resolve_result daten = tmp_path / "daten.json" daten.write_text(json.dumps({"bedarf": 5}), encoding="utf-8") neu = resolve_result(str(gespeichertes_ergebnis(tmp_path)), str(daten)) assert neu.solver_run.objective_value == pytest.approx(12) assert neu.solver_run.data["bedarf"] == 5 def test_resolve_keeps_specification_and_checks_feasibility(tmp_path): from TextToModel import resolve_result neu = resolve_result(str(gespeichertes_ergebnis(tmp_path))) assert neu.specification.problem_class.value.startswith("Linear") assert neu.solver_run.feasibility == []