LSR 008 - 量纲剥离(Unit Stripping)规范

基本信息

  • LSR 编号 008

  • 标题 量纲剥离(Unit Stripping)规范

  • 作者 Ziyang-Bai

  • 状态 草案

  • 类型 标准规范

  • 创建日期 04-05-2026

  • 归属项目 编译器、通用

摘要

定义带量纲数值到无量纲数值的剥离路径,覆盖 as num 与 as scalar;该语义不改变数学等价判定 [3]。

技术规范

1. 设计目标

  • 为带量纲值提供单一、明确、可预测的剥离语法

  • 与现有 as <unit> 单位转换保持组合性

  • 剥离仅显式触发,精度与安全边界清晰

2. 语法

2.1 基础语法

expr as num
expr as scalar

规则:

  • as num :先转换到 SI 基准量值,再移除单位签名

  • as scalar :仅移除单位签名,不进行数值缩放

2.2 与单位转换组合

(expr as <target_unit>) as scalar

规则:先转换到目标单位,再剥离为纯数值。

3. 语义定义

3.1 默认基准

  • expr as num 采用 SI 基准量值

  • 例:10<km> as num 的结果是 10000

  • 对抽象基单位(如 score、token ),as num 采用该基单位自身刻度

  • 例:10<score> as num 结果为 10

3.2 目标单位下剥离

  • 若用户希望在某单位刻度下得到纯数值,必须先显式转换单位

  • 例:(10<km> as <km>) as scalar 结果为 10

  • 抽象单位之间仅在存在显式比例定义时允许转换

3.3 as scalar 语义

  • expr as scalar 保留当前单位刻度,仅移除静态单位签名;刻度不由显示格式决定

  • 例:10<km> as scalar 结果为 10

  • 适用于符号推导或公式整理,保持当前刻度,降低系数膨胀

3.4 编译期降级(与 LSR-000 [1] 对齐)

  • 核心量纲在编译期追踪;运行期裸 num 不携带可供恢复量纲的标签

  • as num 与 as scalar 在代码生成前落实为相应的数值缩放和静态量纲移除;符号系数仍可保留为未求值的 num 表达式

  • 单位比例默认为精确数学值,剥离本身不调用 approximate。已有近似值参与缩放时遵循局部近似传播,保留近似标记和工作精度;量纲与近似精度互不混淆

  • 动态单位文本、运行期单位标签和异量纲动态包装属于可选扩展,不是核心剥离语义的前提

  • 不同量纲的值可用静态元组组合;剥离后的裸数不能反推出原单位或量纲

4. 类型规则

  • 输入必须是带静态量纲或无量纲的标量数学值,基本静态类型为 num;精确数、符号值与近似值采用同一规则

  • 输出为无量纲 num;scalar 是剥离语法关键字,不是另一基本数学类型

  • int、frac、real、complex 仅为 num 的值约束,剥离不会仅因输入满足某个约束而改变基本类型;缩放后的值需重新满足使用位置要求的约束

  • 非标量值(包括向量、矩阵、集合和关系)不属于本规范的剥离支持域;容器若需剥离,应按相应接口显式处理元素

  • 对 vector、matrix、table、set、text、bool 等不支持的输入使用 as num 或 as scalar,诊断 UnitStripTypeMismatch

5. 与外部函数/底层操作的交互

5.1 外部函数调用

当外部函数仅接受无量纲参数时,调用端必须显式剥离 [2]:

let dist = 1200<m>
let raw = dist as num
let r = c_ext_fft(raw)

剥离只处理量纲,不选择外部数值表示。FFI 中的 int、frac、real、complex 标注还须按扩展接口规范选择固定 C ABI 表示,并在调用前完成具体求值、表示映射和范围检查;未求值符号式不能直接作为 C 数值传入。

5.2 位运算/底层数值 API

位运算和底层原语要求无量纲数值,并另行检查各自的整数、可具体求值及表示范围约束;带量纲值必须先显式剥离:

let t = 8<s>
let bits = bit_and((t as num), 3)

规则:外部函数若要求保留当前单位刻度数值,使用 as scalar。

6. 安全约束与错误模型

  • UnitStripTypeMismatch: 作用于非数值类型

  • UnitStripOverflow: 缩放时超出所选数值表示的支持范围;不得仅因精确整数超出机器整数范围而丢失精确性

  • UnitStripInvalid: 单位转换阶段失败(例无效目标单位)

  • UnitStripLegacySyntax: 使用了废弃语法 as num<_>

规则:

  • 单位维度检查由上游运算与 as <unit> 阶段完成

  • as num 会按 SI 基准缩放后再剥离,as scalar 仅剥离标签

  • 单位不相容或操作确定无定义时沿错误路径传播;符号系数尚不能求值时保留合法的缩放表达式,不自动近似或恢复已擦除的信息

7. 语法约束

  • 仅允许 expr as num 与 expr as scalar

8. 示例

let speed = 20<m/s>
let raw_si = speed as num                 # SI 基准量值
let raw_kmh = (speed as <km/h>) as scalar # km/h 刻度数值
let raw_keep = speed as scalar             # 保留当前刻度值

func second2hour(s num<s>) -> num<h> {
    return s as <h>
}

9. 引用