# UnifiedSolution

所有产品求解路径返回 `UnifiedSolution`。应用应通过这个对象读取状态、变量、目标、约束和诊断证据，不依赖具体 backend 的原始结果结构。

## 核心字段

| 字段 | 类型 | 含义 |
| --- | --- | --- |
| `solver_name` | `str` | 产生结果的求解路线名称。 |
| `status` | `SolutionStatus` | 求解状态。 |
| `variable_values` | `dict[int, Any]` | 变量节点 ID 到最终取值的映射。 |
| `objective_values` | `dict[int, Any]` | 目标节点 ID 到值的映射。 |
| `constraint_values` | `dict[int, Any]` | 约束节点 ID 到布尔结果的映射。 |
| `feasible` | `bool` | 是否通过公开可行性判断。 |
| `dag_recheck_passed` | `bool` | 最终结果是否通过 DAG 复核。 |
| `result` | `SolveResult` | strategy、迭代数、耗时、终止原因和重启次数。 |
| `summary` | `SolveSummary` | domain、compiler、构造/搜索阶段和 external evaluation 的结构化统计。 |
| `diagnostics` | `dict[str, Any]` | 策略和执行路径的扩展诊断。 |
| `telemetry` | `dict[str, Any]` | typed runtime telemetry 的公开投影。 |

## 便捷属性

| 属性 | 含义 |
| --- | --- |
| `objective_value` | 单目标场景下第一个目标值的快捷访问；没有目标值时为 `None`。 |
| `final_solution` | 返回当前 `UnifiedSolution`，用于统一处理可能包装解对象的调用代码。 |

```python
solution = solve(builder)

if solution.feasible and solution.dag_recheck_passed:
    print("目标值：", solution.objective_value)
    print("变量：", solution.variable_values)
else:
    print("状态：", solution.status)
    print("诊断：", solution.diagnostics)
```

## SolutionStatus

| 状态 | 含义 |
| --- | --- |
| `OPTIMAL` | 已找到可行解，并由所选精确路径证明最优。 |
| `FEASIBLE` | 已找到可行解，但未证明最优；启发式搜索通常返回此状态。 |
| `INFEASIBLE` | 已确认没有满足当前约束的解。 |
| `FAILED` | 求解过程失败，调用方应检查异常或诊断信息。 |
| `FALLBACK` | 结果来自明确记录的降级路径。 |

## 读取诊断

`diagnostics` 和 `telemetry` 是扩展信息，不应替代核心字段。业务代码优先读取 `status`、`feasible`、`dag_recheck_passed`、`objective_value` 和变量值；只有排查性能、终止原因或策略行为时才读取具体诊断键。

```python
termination = solution.result.termination_reason
iterations = solution.result.iterations
evaluations = (
    solution.summary.construct_candidates_evaluated
    + solution.summary.loop_candidates_evaluated
)
```

诊断键会随策略能力扩展。调用方应使用 `.get(...)` 并为缺失值提供合理处理，不要假设所有求解路径都产生同一组扩展字段。

<!-- public-api: optagent.UnifiedSolution -->
<!-- public-api: optagent.SolutionStatus -->
