Skip to content

符号表达式与符号运算 ​

数值计算回答“给定输入后结果是多少”,符号运算保留未知量与关系,回答“结果由哪些输入、按照什么规则得到”。这层能力既服务优化建模,也可以服务指标计算和规则解释,不依赖 LLM。

1. 表达式不是文本公式 ​

把公式保存成字符串会丢失类型、引用和作用域信息。抽象语法树(AST)用节点表达常量、引用、算术、比较与逻辑结构。以下是概念节点,不是 Kotlin/Rust API 名称:

text
LessEqual
├─ Add
│  ├─ Multiply(Constant(2), Reference(production[A]))
│  └─ Multiply(Constant(3), Reference(production[B]))
└─ Reference(labor.capacity)

它表示 2xA+3xB≤H。AST 描述关系,但节点本身不会自动知道工时单位、业务日期或字段权限;这些由业务绑定提供。

2. 三类容易混淆的对象 ​

对象职责示例
业务规则保存业务对象、单位、时间与来源本班次工时不得超过 8 小时
符号表达式保存数学结构与引用2xA+3xB≤H
求解模型指定变量域、约束、目标及可执行表示非负整数产量的线性模型

数学 AST 能表示某个函数,不代表所选优化后端能够处理它。变量乘变量不能仅因为 AST 构造成功,就被放进只支持线性的路径。

3. 求值、绑定与部分求值 ​

若 xA=1,xB=2,H=8,求值结果是 8≤8,为真。若只绑定 H=8,产量仍未知,则保留 2xA+3xB≤8。这是参数绑定或部分求值,不是求解出产量。

求值环境需要区分“未绑定”“无效值”和“值为零”。缺失产量不能默认为零;除数为零不能因化简而消失。布尔表达的未知值也不能自动当作 false,除非该语言明确采用并记录了这种语义。

当规则复用到另一个班次时,绑定的是新的 H 与本轮产量引用,不能把旧变量实例嵌入长期保存的模板。

4. 规范化与等价性的条件 ​

将 2x+x 合并成 3x 有助于规范化;将 x/x 替换为 1 则要求 x≠0。浮点重排可能改变舍入误差,条件表达还可能有分支求值约定。变换规则必须说明数值域和定义域,而不是仅凭表面形式判断。

具名中间值可以使表达依赖形成有向无环图,而不必重复复制整棵树。共享节点不等于共享一个可变求值缓存;缓存与模型运行、输入及线程边界需要分离。循环定义如 a=b+1,b=a−1 不能按普通表达式展开处理;若要表达方程系统,应显式建模。

5. 贯穿例子:工时指标的两种使用 ​

概念、变量与中间值 ​

产品集合 I={A,B},产量 xi∈Z≥0(件),系数 aA=2,aB=3(小时/件),预算 H=8(小时)。无筛选谓词或辅助变量。工时指标为:

U=∑i∈Iaixi.

数据断言要求系数为正、预算非负。优化模型可以增加:

s.t.U≤H,max(3xA+4xB).

数值路径与建模路径 ​

数值路径绑定已有方案 (1,2) 并返回 U=8 小时;建模路径保留未知产量,并将关系转换成约束系数。两条路径使用同一个数学定义,但输出一个是数值,另一个是模型结构。

这也是把表达式做成可复用组件的价值:业务指标可以服务方案展示、约束构造和结果核对,而不需要分别维护三套公式。

6. 依赖、缓存与业务身份 ​

依赖收集回答表达式引用了哪些字段或符号,可用于确定重新绑定范围。缓存键应包含表达结构、参数值或参数槽约定、数值语义、业务数据版本及转换策略。

表达式结构相同不等于输入相同,也不等于权限相同。缓存一份表达求值计划不是缓存最优解。原始规则身份应独立于规范化后的哈希,以便错误和结果回到业务规则。

继续阅读类编译器架构与模型转换了解表达怎样进入求解模型;LLM 技术路径说明受控业务输入如何使用这一层。