# MoonAqueousSpec：同源分样处理历史核对与零净转移检验

**核对同一原水分样后的检测值，检验它们能否来自同一个处理历史。** 面向 Ca–碳酸盐–Na–Cl–水的有限、显式模型：样瓶分配、稀释/蒸发、CO₂ 净转移、方解石净转移和带 Na/Cl 反离子的加酸/加碱。检测值绑定到实际样瓶，原水和上游剂量在所有后代中保持同一个未知量。

例如：A、B 两瓶分别都能解释，不代表能来自同一原水；体积校正后 TA 没变，不代表没有等量加酸/加碱。程序同时核对 Ca、DIC、TA、Na、Cl，输出一段共同可行历史，或可用原始检测约束复算的矛盾；证据不足和计算资源不足各有明确结果。

主要贡献落实在**跨样瓶的共同原水/处理约束，以及“指定处理步骤净转移为零”的解释检验**。质量守恒、碳酸盐计量、精确分数、Fourier–Motzkin、Farkas 证书均为已有基础。当前公开源码审查尚未确认完整同职责实现；不声称全球唯一、零相似或赛事免判重，见 [近邻与贡献边界](docs/independent-contribution.md)。

## 核心职责与可复核证据

目标用户是核对受控水样配制、分样与处理记录的人。核心问题是：多个实际样瓶的检测结果，能否由同一原水和同一组处理参数共同解释？若指定步骤的净转移全为零，现有检测是否仍允许这样的历史？

| 核心职责 | 实现与证据 |
|---|---|
| 实际样瓶谱系与体积分配 | [lineage.mbt](lineage.mbt) 记录父子状态，检查兄弟分样总体积及处理顺序。 |
| 跨瓶共享原水与上游剂量 | 同一次上游未知处理在所有后代中保持同一个变量；[联合测试](reconcile_wbtest.mbt) 覆盖各瓶独立可行但共同冲突。 |
| 检测绑定具体样瓶 | 联合使用 Ca/DIC/TA/Na/Cl 检测区间与实际体积，不把 pH 当作可加检测量。 |
| 基线后的联合零净转移检验 | [claims.mbt](claims.mbt) 先检查共同历史，再检验所选步骤是否能同时为零；[反例](claims_wbtest.mbt) 展示增加检测后结论变化。 |
| 可复核输出和明确未决 | [reconcile.mbt](reconcile.mbt) 返回共同历史或原始约束的矛盾证书；[独立验证器](scripts/verify_aliquots.py) 重算，超预算返回 `ResourceLimit`。 |

这五项构成当前专用工作流的差异化重点；每项所用的化学与数学基础均有先例，组合也没有被证明绝对独有。

## 安装 MoonBit 库

Mooncakes 包名为 `alicedhaha/moonaqueousspec`：

```bash
moon add alicedhaha/moonaqueousspec
```

在使用方的 `moon.pkg` 中导入 `alicedhaha/moonaqueousspec`，即可调用下文列出的根包 API。文件命令行示例需要检出本仓库后运行。

## 先运行三个核心反例

需要 MoonBit 和 Python 3.9+。Python 适配器只做 JSON 文件读写；全部判断在 MoonBit 主库中执行。已有项目本地 `.moon` 时自动使用它，否则使用 PATH 的 `moon`。

```bash
python3 scripts/aliquots.py reconcile --input examples/aliquots/common-source-conflict.json
python3 scripts/aliquots.py challenge --input examples/aliquots/masked-acid-base.claim.json
python3 scripts/aliquots.py challenge --input examples/aliquots/mineral-acid.claim.json
```

| 核心反例 | 实际判断 | 增加了什么判断能力 |
|---|---|---|
| 同源分瓶冲突 | 完整输入为 `Conflict`；分别保留单瓶检测时各为 `Compatible` | 阻止把各瓶独立选择的原水值拼成不存在的共同历史。 |
| 酸碱效应在 TA 上抵消 | 完整输入为 `ZeroTransferRuledOut`；删去 Na/Cl 后为 `ZeroTransferPossible` | 显示反离子检测能排除 TA 单独无法排除的解释。 |
| 方解石/酸效应在 TA 上抵消 | Ca/Cl 证据排除“矿物和酸都为零”；CO₂ 为零仍可行 | 区分明确的净计量解释；不从 SI 推断沉淀，也不把联合排除解释为每一步必然非零。 |

完整输入的单次运行只产生表中的完整输入结果。下述独立验证命令会实际构造单瓶子例、删去 Na/Cl 或 Ca/Cl 的对照，以及单独 CO₂ 零转移假设，并逐条复算结果：

```bash
python3 scripts/verify_aliquots.py
```

另外两个例子展示共享上游剂量和证据不足的边界：

```bash
python3 scripts/aliquots.py reconcile --input examples/aliquots/acidified-split.json
python3 scripts/aliquots.py challenge --input examples/aliquots/underdetermined-gas.claim.json
```

前者返回共享原水与酸剂量的一段 `Compatible` 历史；后者返回 `ZeroTransferPossible`，保留零气体净转移解释。以上均为合成案例，无实测水样或实验准确性主张。详见 [场景与对照](docs/scenarios.md)。

## 与近邻的具体边界

| 相关项目 | 承认的共同基础 | 当前主任务的区别 |
|---|---|---|
| [moonbit-biogeochem](https://mooncakes.io/docs/lqlnvj/moonbit-biogeochem) | DIC、TA、碳酸盐和 CO₂ | 所查源码为海洋箱模型与气海交换；当前处理样瓶谱系、共享上游量和跨瓶检测的共同历史。 |
| [moonkinetics](https://mooncakes.io/docs/jqlssg/moonkinetics) | 化学计量与守恒 | 所查项目演化反应网络；当前检验有限处理记录与检测是否相容。 |
| [membrane](https://mooncakes.io/docs/wskwsk68/membrane) | 物料网络、并联流与可行设计 | 当前输入是分样及检测，不进行膜分离工艺设计。 |
| [moonopt](https://mooncakes.io/docs/Freon793/moonopt) | 可行性与 Farkas 不可行核验 | 当前只接受有限水样处理模型，证书方法本身不是新增贡献。 |
| [moonbit-vle](https://mooncakes.io/docs/Zxy666668/moonbit-vle)、[moonbit_extractor](https://mooncakes.io/docs/zhaoyuanjuns/moonbit_extractor) | 活度、平衡、物料衡算 | 当前主任务不求相平衡或萃取；保留平衡支持包仍有领域交集。 |

对化工报告、分数库和一般约束求解器的交集也已列入 [贡献与近邻说明](docs/independent-contribution.md)。截至 2026-10-27 17:36（北京时间）的 [公开发布包审查](audit/originality-review-2026-10-27/review.md) 尚未确认完整同职责实现；这不是其他项目都没有该能力的证明，也不是赛事判定。全量筛查、重点人工读源和覆盖缺口分别记录，不能把扫描数量解释为原创性证书。

## API 与状态

根包仅提供 `reconcile_aliquots`、`challenge_zero_transfer`、`replay_handling` 及对应 JSON 函数。公开类型和准确签名在 [生成接口](pkg.generated.mbti)。

- `Compatible`：存在一段同时满足所有包含端点的检测范围的共同历史，不代表历史唯一或真实发生。
- `Conflict`：声明模型下不存在共同历史；返回原始约束的非负权重，精确合并得到 `0 <= 负数`。
- `ZeroTransferPossible` / `ZeroTransferRuledOut`：一组指定步骤可以/不可以**同时**净转移为零；后一状态只说明其中至少一项非零。
- `BaseConflict`：未加零转移假设的基线已经矛盾，不据此推断过程必然发生。
- `ResourceLimit`：计算未决，不能解释为可行、冲突或通过核验。

文件适配器退出码：有效完成的分析为 0（包括 `Conflict`，需读取状态）；模型拒绝为 1；文件/运行失败为 2；资源不足未决为 3。`--output FILE` 保存完整 JSON。回放接收 `{"study": ..., "parameters": [...]}`，用 `replay` 命令检查指定历史。

## 验证与复查

```bash
export MOON_HOME="$PWD/.moon"  # 系统工具链使用者跳过这两行
export PATH="$MOON_HOME/bin:$PATH"
moon check --deny-warn
moon test --deny-warn
python3 scripts/verify_aliquots.py
python3 scripts/generate_aliquot_examples.py --check
python3 scripts/verify_local.py
```

独立验证器使用 Python `Fraction` 直接计算各瓶物质量，从单位基向量重建输入约束，并用高斯消元/有界多面体顶点枚举独立判定最多三个未知量的案例；它不调用 MoonBit 的仿射编译或消元实现。共同历史逐瓶核对，矛盾逐约束复算；另做体积、计量系数、反离子、样瓶身份、权重与截断输出的错误注入。资源上限另由 MoonBit 测试验证。报告位于 `audit/differentiation/verification/aliquots/report.json`。

每个可独立审查的功能批次完成后都刷新 Mooncakes 在线清单、重新读取发布包并人工复核近邻，记录在 [逐批证据](audit/differentiation/README.md)。哈希和扫描数量只说明检查范围，不能证明没有语义等价实现。

## 有限模型与职责边界

只接受 Ca–碳酸盐–Na–Cl–水；须声明全部离子、体积和可能过程。源样强离子/碱度关系为 `2 Ca + Na - Cl - TA = 0`。输入使用整数 µL、nmol/L、neq/L 和 nmol，输出精确分数；pH 不作为可加分析量。未知 JSON 字段拒绝。最多 16 步、32 个检测范围和 10 个不确定量；消元预算超出即未决。方程、符号和边界见 [模型](docs/model.md)、[输入契约](docs/schema.md) 和 [单位](docs/conventions.md)。

根包不提供通用水相物种分配、任意电解质平衡、相平衡 flash、一般反应网络 ODE/SSA/CME、沉淀动力学或通用 LP/SMT/任意矩阵优化 API。当前模型也未提供盐水/天然水的完整组分、未知体积、误差概率、最优实验设计或真实反应归因。方解石和 CO₂ 的值是声明的净转移，不是自动求出的沉淀量或气体平衡量。未知过程可以使结论失效。

早期物种分配、活度、矿物 SI、敏感性与 PHREEQC 数据核验保存在 `equilibrium/` 独立支持包；根包及默认 CLI 不依赖它。旧工作流使用 `scripts/aqueous.py` 或 `moon run equilibrium/cmd/main`，见 [支持包职责说明](equilibrium/README.md) 与 [操作指南](docs/equilibrium-guide.md)。这些保留功能仍与既有科学软件及 Mooncakes 项目有交集，不能通过移动目录消除其先例。

代码 [Apache-2.0](LICENSE)。支持包的 PHREEQC 数据保留 [第三方许可](THIRD_PARTY_NOTICES.md)。[申报草稿](PROJECT_APPLICATION.md) 需要本人改写和审核；本地验证不代表公开发布、报名、提交或评审通过。

## 项目结构与申报范围

| 路径 | 职责 |
|---|---|
| `lineage.mbt`、`reconcile.mbt`、`claims.mbt` | 当前主任务：处理谱系、共同历史与联合零净转移检验。 |
| `cmd/main/`、`scripts/aliquots.py` | 默认 MoonBit 入口与文件适配器。 |
| `examples/aliquots/`、`docs/scenarios.md` | 当前主任务的五个合成场景及对照说明。 |
| `equilibrium/`、`scripts/aqueous.py` | 独立保留的水相平衡支持功能，有自己的入口和已知先例。 |
| `docs/equilibrium-*.md`、根目录早期规划书 | 支持包文档与历史规划，不作为主任务新增承诺。 |

[申报草稿](PROJECT_APPLICATION.md) 以根包的样品处理历史核对为核心交付，主动披露支持包和近邻。保留支持包仍属于仓库，参赛范围说明不能替代组委会对完整提交内容的审查。
