跳转到内容

AMIR:Aira Modeling Intermediate Representation 规范:模型身份、类型与值

主文档与完整目录。本分篇与主文档共同构成同一规范,版本、状态与权威以主文档为准;仅拆分阅读结构,条款编号和正文语义不变。

一个 canonical AMIR Document 必须是单个 JSON object。顶层字段如下:

字段 必需 语义
$schema 是 所使用的 JSON Schema URI
amirVersion 是 AMIR 语义版本,当前实现为 0.4.0
documentId 是 跨 Revision 不变的 DocumentId
revision 是 当前 Revision 清单
settings 是 单位、坐标系、容差与 Field 符号约定
parameters 是 ParameterId 到 Parameter 的 map,可为空
nodes 是 NodeId 到 Node 的 map
bodies 是 BodyId 到稳定 body 身份及其当前权威输出的 map,可为空
product 否 修订所有的产品结构、配置、物料身份及关联工程声明
assertions 是 AssertionId 到 Assertion 的 map,可为空
roots 是 对外发布的具名根输出;可为空,执行时另行检查所请求输出
metadata 否 标题、说明、标签等非几何语义信息
extensions 是 命名空间化扩展,可为空 object

除 extensions 外,顶层未知字段必须被结构验证器拒绝。Artifact、内核句柄、Geometry Certificate 和渲染缓存禁止内嵌进 Document;它们属于运行时 Artifact Store。

当前文档级 product 与草案中的通用 Assembly 运算端口是不同概念;不能由后者尚未实现推断产品结构不存在。 product.root 引用共享 Body 或装配定义,assemblies 中的重复引用展开为不同实例路径;所有定义引用必须存在,包含未使用定义在内的装配定义图必须无环。Body 保持零件几何的唯一权威,实例不复制出另一份建模定义。

配置、显式物料身份、关联图纸、工程尺寸、基准、公差和交换来源保存在同一产品声明中;几何求值、BOM、图纸与交换消费所选配置下的产品结果。声明字段存在不代表支持任意尺寸类型、修饰语义或制造标准。精确字段与接受域见当前 schema,组织方式见工程定义方案,实现与验证状态只见工作进度。

DocumentId、NodeId、BodyId、ParameterId、ExpressionId、ConstraintId、AssertionId、SemanticRefId 和 ToleranceProfileId:

  • 必须在所属 Document 中唯一;
  • 必须匹配 ^[A-Za-z][A-Za-z0-9._:-]{0,127}$;
  • 禁止包含 #、/、空白或依赖数组位置;
  • 一旦进入 committed Revision,身份不得通过“重命名”改变;可修改独立的 label;
  • 不得编码拓扑索引或执行顺序。

实现应该使用 UUID、ULID 或等价稳定 ID。本文示例使用可读 ID 仅为便于说明。

PortName 必须匹配 ^[A-Za-z][A-Za-z0-9_]{0,63}$。canonical PortRef 使用对象形式:

{ "port": { "node": "n.extrude", "port": "solid" } }

字符串简写 n.extrude#solid 可以存在于表层语言中,但不得出现在 canonical AMIR。

Revision 清单至少包含:

{
"id": "draft:01K3EXAMPLE000000000000000",
"state": "draft",
"parents": [],
"operationCatalog": "amir.ops/0.1.0",
"createdAt": "2026-08-29T00:00:00Z",
"actor": { "kind": "human", "id": "user:example" }
}

规则如下:

  • state 只能是 draft 或 committed。
  • draft 的 id 必须为 draft:<uuid-or-ulid>,可以随候选事务废弃。
  • committed Revision 必须不可变,id 必须为 rev:sha256:<64 lowercase hex>。
  • committed Revision 必须包含 modelHash、patchHash 和 authoringLockHash。authoringLockHash 只锁定解释模型所需的 schema、Operation Catalog 与 semantic extension packages,不包含具体 kernel/platform build。
  • parents 为 RevisionId 数组;常规提交恰有一个父版本,初始提交为空,合并提交可以多于一个。
  • operationCatalog 必须固定完整版本,不能使用 latest、范围或未固定 URL。
  • 当前契约不含迁移记录,旧版字段直接拒绝;不提供修订迁移或兼容读取。
  • actor.kind 只能是 human、ai、service 或 import。

modelHash 与 RevisionId 的计算见第 14 节。

Model Revision 与几何执行必须分离。一个 canonical Candidate 或 committed Revision 可以在 browser、native 或 server 上产生多个 Evaluation,而不会改变 AMIR 或 RevisionId。Evaluation 的计算身份由模型语义内容决定,不要求预先存在尚未提交的 RevisionId。

EvaluationId 必须为:

eval:sha256(SHA-256(JCS({
modelHash,
authoringLockHash,
executionManifestHash,
executionClass,
qualityProfileId,
inputArtifactsByLogicalKey
})))

inputArtifactsByLogicalKey 是以稳定逻辑输入名为 key 的 map,不得使用依赖枚举顺序的裸数组。ExecutionManifest 固定 compiler/adapter/kernel/plugin build、平台和浮点策略、线程/seed、实际 tolerance、资源策略与 capability resolution。Artifact 和 Geometry Certificate 必须绑定 EvaluationId。

Evaluation provenance 使用独立、不可变的 EvaluationBinding 关联 source subject:{revisionId},或 {candidateId, baseRevision, patchHash}。Candidate 在提交后,如果 modelHash、authoringLockHash、ExecutionManifest、execution class、quality profile 和输入 artifacts 完全相同,可以复用同一 EvaluationId;commit 另写一个 Revision binding 与新的 committed Certificate,不修改原 candidate binding/certificate。更换 kernel、平台或 quality profile 只创建新 Evaluation;只有 AMIR 语义或 authoring lock 改变时才创建新 Model Revision。

{
"evaluationId": "eval:sha256:...",
"modelHash": "sha256:...",
"authoringLockHash": "sha256:...",
"source": {
"candidateId": "candidate:sha256:...",
"baseRevision": "rev:sha256:...",
"patchHash": "sha256:..."
}
}

AMIR 是名义类型系统。Operation Catalog 中的所有公共 Port 必须声明完整类型;禁止使用无约束的 Any、宿主语言对象或内核类名。

本版基础类型至少包括:

  • 标量:Bool、Int、Count、Real、String、BytesHash;Count 是非负整数名义类型,不从负值或任意 Int 隐式构造;
  • 量纲:Length、Angle、Area、Volume、Mass、Time、Ratio;
  • 空间值:Point2、Point3、Direction2、Direction3、Vec2<T>、Vec3<T>、Quaternion、Transform3D、Axis2D、Axis3D、Plane3D、Box2D、Box3D;
  • 几何:第 4.4 节定义的表示类型;
  • 集合:List<T>、Set<T>、Optional<T>、Map<String,T>;
  • 选择结果:EntitySet<Face>、EntitySet<Edge>、EntitySet<Vertex>、EntitySet<SketchEntity>、EntitySet<Instance>。

泛型类型使用 Name<T,...> 的 canonical 字符串形式。Operation Catalog 必须解析类型表达式,不能把它当作仅供显示的字符串。

每个有量纲常量必须显式携带单位。settings.units 只是表层输入和 UI 的默认单位,不能使 canonical 常量省略单位。

settings 必须包含 units、coordinateSystem、tolerances 和 fieldConvention。本版 canonical 坐标系必须明确 handedness、up axis 与 forward axis。fieldConvention 必须固定为本文定义的 negative/zero/positive,保留该字段是为了让 adapter 错误可被结构检查发现,而不是允许 Document 改变符号约定。

settings.tolerances 是内嵌、版本化的 ToleranceProfile,至少包含:

字段 类型 用途
profileId ToleranceProfileId 稳定配置身份
profileVersion SemVer 配置 schema/取值版本
modelingLinear Length 建模退化、重合与最小几何尺度基线
modelingAngular Angle 建模方向/角度判等基线
intersectionLinear Length 曲线/曲面相交判定
fuzzyBooleanLinear Length 仅供 descriptor 明确允许的 fuzzy Boolean 使用
sewingLinear Length sewing/healing 接合阈值
constraintLinearResidual Length 约束求解线性残差上限
constraintAngularResidual Angle 约束求解角度残差上限
validationDistance Length 跨执行几何距离与验证比较
quantityRelative Ratio 面积、体积、质量等量值的相对比较

所有数值字段都必须使用第 4.3 节的 canonical const Value。优先级固定为:Document ToleranceProfile → Operation descriptor 明确允许的普通 input override → adapter 计算出的 effective value。前两层属于模型语义并进入 model/subgraph hash;effective value 属于 ExecutionManifest、EvaluationId 和 Certificate。Adapter 不得静默放宽阈值;若内核不能满足请求,必须失败或由显式 Patch 修改 profile/input 后重新验证。

Tessellation、Field sampling/cell size 和导出精度不是可被全局 epsilon 偷偷替代的容差:canonical conversion Node 必须把它们写成普通 input 并进入 modelHash;仅用于视图或导出的值写入独立 view/delivery quality profile,并进入对应 Evaluation/job hash。

本版必须识别:

  • 长度:um、mm、cm、m、in、ft;
  • 角度:rad、deg;
  • 时间:ms、s;
  • 质量:g、kg;
  • 面积和体积:上述长度单位的 ^2、^3 形式,例如 mm^2、m^3;
  • 比例:1,百分比必须在表层解析时转换为 Ratio,canonical 值不保存 %。

单位区分大小写。实现必须用固定单位表进行转换,禁止使用当前 locale。角度不是普通 Real;三角函数必须接受 Angle,返回 Real。允许的隐式赋值只有:

  1. Int 到 Real;
  2. 同一量纲内的单位归一化;
  3. 第 4.5 节明确规定的 Field 子类型提升。

Length 与 Angle、Length 与 Real、Area 与 Length 之间禁止隐式转换。

为避免不同 JSON parser 和语言对浮点字面量的解释差异,所有 Int、Count、Real 和有量纲数值的 canonical value 必须是十进制字符串。它必须为有限值,不得为 NaN、Infinity、指数或十六进制;-0 必须规范化为 0。

  • Int 使用 ^-?(?:0|[1-9][0-9]*)$,但禁止 -0。
  • Count 使用 ^(?:0|[1-9][0-9]*)$。
  • Real 与有量纲十进制使用 ^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*[1-9])?$,禁止尾随零、小数点无小数和正号;物理值为零时统一写 0。

实现必须对数位总长度设置一致的 schema 上限,并在 conformance fixtures 中覆盖极小值、极大值、负值、零和等价非规范输入。

{ "const": { "type": "Length", "value": "12.5", "unit": "mm" } }
{ "const": { "type": "Vec3<Length>", "value": ["0", "0", "25"], "unit": "mm" } }
{ "const": { "type": "Bool", "value": true } }

Enum 值使用其名义类型和字符串值,例如:

{ "const": { "type": "PrincipalPlane", "value": "XY" } }
类型 契约
Sketch2D 位于明确 Plane3D 上的稳定 2D entity 集、约束及求解状态;允许 under-constrained,但必须报告 DOF
Profile2D 已求值、闭合、定向、无自交的平面区域,可含孔;不满足条件时不得产出此类型
ExactSolid 以拓扑 B-Rep 和解析/参数曲面为权威表示的有效 solid;允许内部容差和浮点算法,不等于数学精确证明
ExactSurface B-Rep surface/shell,不承诺封闭体积
RawMesh 未经 solid 契约验证的顶点/面数据,可开放、自交或非流形
MeshSurface 已验证索引和定向的表面网格,但可开放
MeshSolid 定向、封闭、watertight 的 2-manifold 网格;可有多个连通分量,分量数写入证书
Field3D<K> 三维标量场,K 为第 4.5 节的场契约;AMIR 统一采用负内、零面、正外
Assembly 具名 part/assembly instance、变换和 mate 的层级图;它本身不是 fused solid
DisplayMesh Runtime-only 派生三角网格,用于显示、拾取和 source mapping;禁止作为 canonical Node output、Body authority 或 authoring root

每个 root part/body 必须有且只有一个权威表示。一个 Feature DAG 可以同时包含不同表示,但转换必须是显式 Node。ExactSolid、MeshSolid 与 Field3D<K> 之间不存在隐式可赋值关系。

导入 STL 或任意 BufferGeometry 必须先得到 RawMesh;只有验证或修复操作满足 MeshSolid 后置条件后,才可以产出 MeshSolid。

Assembly 中的实例必须引用已存在的 part/assembly root 和显式 Transform3D。Assembly 实例图必须无环。对 Assembly 做 Boolean、体积或制造检查前,必须显式选择 flatten、fuse 或逐实例策略。

Field 的统一符号约定为:内部 < 0、表面 = 0、外部 > 0。Field 表达式图本身必须是有限、纯数据且可静态估算的,但其数学定义域可以是全空间。适配使用正内负外的内核时,adapter 必须翻转符号并在 provenance 中记录;调用方不得自行猜测。

三种 Field 契约为:

  • Field3D<TrueSDF>:值的绝对值在声明误差内等于到零面的欧氏最短距离;值类型必须是 Length,并满足符号约定。
  • Field3D<ConservativeDistance>:符号正确,且绝对值不高估到零面的距离;Operation 可以另行声明 Lipschitz 上界。适合安全步进,但不是精确距离。
  • Field3D<GeneralImplicit>:只保证符号和零等值面语义;值可以是 Length 或 Real,不得被距离步进器当作 SDF 使用。

子类型关系为:

Field3D<TrueSDF>
<: Field3D<ConservativeDistance>
<: Field3D<GeneralImplicit>

提升可以隐式发生,降级转换禁止隐式发生。Operation 必须在 Catalog 中声明 Field kind 的传播规则。例如刚体变换保持 kind;正确缩放场值的均匀缩放可保持 kind;非均匀缩放、warp、平滑 Boolean 默认降级为 GeneralImplicit,除非 Operation descriptor 提供更强且可验证的契约。

Field 输出 Port 必须声明:

  • kind;
  • value type;
  • 符号约定;
  • mathematicalDomain:allSpace 或显式有界 domain;
  • surfaceBounds:若能证明零面的有限 Box3D 包围盒则提供,否则为 null;
  • 已知 Lipschitz bound,未知时为 null;
  • 梯度能力:analytic、automaticDifferentiation、finiteDifference 或 none。
  • normalizationOrder:已证明时为正整数,否则为 null;依赖正规化的 offset/shell capability 必须要求 足够的已证明 order,禁止从 TrueSDF 类型名自行猜测。

evaluationClip 是一次预览、测量或采样 job 的有限求值裁剪范围,属于 Evaluation/job identity,不改变 Field 的数学语义。meshingBounds 是 Field → Mesh conversion 的必需、有限 Box3D input,属于模型语义并进入 modelHash。数学上无界或 surfaceBounds = null 的 Field 合法,但任何有限成本的求值都必须显式提供 evaluationClip,任何权威 meshing 都必须显式提供 meshingBounds;不得依赖隐藏默认包围盒。

当前最小闭合实现见 Field IR v0.1 与 field-ir.schema.json。它只实现 sphere/box/union/intersection/difference,不是完整 Phase 2 Field language。sphere 发布 normalizationOrder=1;box 因边/角不可微保留 null;Boolean 按本节规则降级为 GeneralImplicit 且 order 为 null。每个 node 的派生 contract 与 root contract 都进入 fieldId,runtime 必须重算并拒绝篡改。

Node input、Parameter、Root、Constraint value 和事务值均使用同一个 Value tagged union。一个 Value object 必须且只能包含下列 discriminator 之一:

{ "const": { "type": "Length", "value": "10", "unit": "mm" } }
{ "parameter": "p.width" }
{ "expression": "e.depth" }
{ "port": { "node": "n.profile", "port": "profile" } }
{ "semanticRef": "s.outerEdges" }
{ "constraint": "c.horizontal" }
{ "body": "body.main" }
{ "list": [{ "parameter": "p.a" }, { "parameter": "p.b" }] }
{ "record": { "x": { "const": { "type": "Real", "value": "1" } } } }

list 的所有元素必须满足目标 List<T> 的元素类型。record 只能赋给 Operation Catalog 中具名的 record type,禁止作为绕过静态类型的任意 object。

Expression 使用受限的 ExprTerm:它的叶子只能是 Value 中的 const、parameter 或 expression,并额外允许第 6.2 节的 call。PortRef、SemanticRef、ConstraintRef、list 和 record 不得直接出现在本版 Expression 中。