Skip to content

类编译器架构与模型转换 ​

OSPF 可以用类编译器架构组织“业务表达 → 数学表示 → 后端执行 → 业务结果”。这个类比解释职责分离,不意味着建模就是编译文本,也不意味着求解等于代码生成。

1. 前端、中间表示与后端 ​

层次保存的内容主要职责
业务前端实体、参数、规则身份、单位和上下文将业务定义绑定为数学表达
符号与建模层变量、表达式、函数符号、约束、目标组合、检查和组织数学语义
求解层表示目标模型类别所需的域与关系显式转换、辅助结构、可执行模型描述
后端适配具体求解器对象和配置能力匹配、模型装载、求解和状态读取
结果映射原始身份与转换映射将解和诊断返回业务对象

中间表示不一定只有一种。线性稀疏系数、二次项和原生 CP 关系具有不同结构,不能要求所有模型都先变成线性矩阵。

2. 内部 DSL 不需要重复解析宿主代码 ​

Kotlin/Rust 程序已经由宿主编译器处理语法。建模 DSL 通常通过对象与运算构造表达,不必再从源码字符串做词法分析。

模型层仍需要语义检查:引用是否属于本轮模型,类型和取值域是否一致,表达是否线性,所需逻辑或全局约束是否有合适执行路径。这些检查与宿主程序能否编译是不同问题。

符号表达式承载运算结构,但业务单位、权限和来源仍需要额外绑定。

3. 贯穿例子:产量不足惩罚 ​

概述、概念与变量 ​

生产上下文计划整数产量 x∈{0,…,8},单位件;需求 d=10 件。单位生产成本 c=2 元/件,单位不足惩罚 p=5 元/件,均为已知正数。这里只有一种产品,不需要筛选谓词。

中间值与原始目标 ​

不足量定义为:

s(x)=max(0,d−x).

总成本是生产成本与不足惩罚之和:

F(x)=cx+ps(x),minF(x).

产量域已经给出容量约束。这里 s 是函数定义,不是可随意赋值的第二个业务决策。

转换后的约束 ​

引入连续辅助变量 u≥0,使用:

s.t.u≥d−x,u≥0,

并最小化 cx+pu。由于 p>0,且 u 在此模型中没有其他耦合关系,对固定 x 最优选择恰为 u=max(0,d−x)。因此两个优化问题的最优值和最优产量一致。

但这不是函数图像的无条件等价表达:转换模型允许非最优点中 u>s(x)。如果其他约束使用 u,或目标不再促使其下降,就必须重新论证或者采用精确的函数图像建模方式。

结果 ​

对 0≤x≤8,原始目标为 50−3x,因此最优 x=8,s=2,F=26。结果映射应使用原始定义解释“不足 2 件”,不能只把一个匿名辅助列直接显示给用户。

4. 转换如何保持来源 ​

一个函数符号可能生成多行约束与多列辅助变量。转换需要记录原始符号、变量和约束到这些元素的对应关系。公共报告使用业务身份,不依赖易变的行列序号。

数值解映射与诊断映射不同:前者提取原始变量并求值中间量;后者解释某些底层约束为何出现以及属于哪条业务规则。底层 IIS 映射回名字后,仍不自动成为原始约束粒度的极小冲突。

5. 等价、松弛与近似 ​

精确转换应说明保留的是可行域投影、目标值还是最优解。引入辅助变量后,原空间与扩展空间维度不同,不能直接比较集合相等。

松弛通常扩大可行域,可能用于给出界;它的可行解未必满足原问题。分段近似改变函数,需要声明区间和误差。表达式化简只是在构建阶段改写表示,不是求解最优化问题。

若后端不支持某个语义,应选择经声明的转换路线或明确拒绝,不能悄悄删项、放松整数域或换成近似后仍称为原模型。

6. 后端无关与能力边界 ​

后端无关表示业务规则不直接依赖厂商对象,不表示所有后端能力完全相同。目标类别、变量域、逻辑关系、时间控制与诊断能力都需要匹配。

远端执行可以传递版本化模型表示,但不能把进程内对象地址当成跨机器身份。模型、参数、转换策略和求解配置应分别管理;见远端求解。

7. 与其他章节的关系 ​

领域语言解释表达的组成,DDD解释业务所有权,本章解释表达的转换与执行。形式化设计与形式化验证进一步讨论转换正确性,临界约束分析使用反向证据映射解释目标边界。