style: pi-lens 对 flow/vocab/tests 的引号与换行格式重排(无行为变化;check 与 477 条测试通过)
This commit is contained in:
+103
-21
@@ -1,5 +1,13 @@
|
||||
import type { Content } from "../../ledger/index.ts";
|
||||
import { Board, cellId, CELL_NOT_RUN, explanationId, protocolMetrics, splitCell, validScore } from "../../materials/index.ts";
|
||||
import {
|
||||
Board,
|
||||
cellId,
|
||||
CELL_NOT_RUN,
|
||||
explanationId,
|
||||
protocolMetrics,
|
||||
splitCell,
|
||||
validScore,
|
||||
} from "../../materials/index.ts";
|
||||
import {
|
||||
chooseBet,
|
||||
decisionSeed,
|
||||
@@ -30,7 +38,11 @@ import type { Study } from "../study.ts";
|
||||
export function selectCells(s: Study, round: number): void {
|
||||
const board = new Board(s.ledger.records());
|
||||
const { config, steps } = s.frozen;
|
||||
const seed = decisionSeed({ studyId: config.studyId, round, version: SEED_VERSIONS.cells });
|
||||
const seed = decisionSeed({
|
||||
studyId: config.studyId,
|
||||
round,
|
||||
version: SEED_VERSIONS.cells,
|
||||
});
|
||||
const input: CellRuleInput = {
|
||||
...modelInput(board, s, round),
|
||||
balance: runBalance(config.runs, board.runStates()).balance,
|
||||
@@ -39,7 +51,8 @@ export function selectCells(s: Study, round: number): void {
|
||||
decay: config.flow.decay,
|
||||
seed,
|
||||
};
|
||||
const rule = steps.round.find((x) => x.id === "selectCells")!.rule!.name as CellRuleName;
|
||||
const rule = steps.round.find((x) => x.id === "selectCells")!.rule!
|
||||
.name as CellRuleName;
|
||||
const { rule: used, ...output } = runCellRule(rule, input);
|
||||
// SAFETY: rules 是纯计算,输入输出都是纯 Json 值;账本在写入时校验 Json。
|
||||
s.ledger.append("decision", {
|
||||
@@ -55,14 +68,30 @@ export function selectCells(s: Study, round: number): void {
|
||||
}
|
||||
|
||||
/** ⑯ 消融运行:用核验过的这一格快照,复用正式运行的登记、扣次、判分入口。完整代码和基线的分数取本批已有的运行结果,不重跑。 */
|
||||
export function ablationRun(s: Study, round: number, cell: string, run: string): Promise<RunOutcome> {
|
||||
export function ablationRun(
|
||||
s: Study,
|
||||
round: number,
|
||||
cell: string,
|
||||
run: string,
|
||||
): Promise<RunOutcome> {
|
||||
const board = new Board(s.ledger.records());
|
||||
return formalRun(s, { run, purpose: "ablation", round, object: cell }, board.code(cell).version, ablationMetrics(board, splitCell(cell).candidate));
|
||||
return formalRun(
|
||||
s,
|
||||
{ run, purpose: "ablation", round, object: cell },
|
||||
board.code(cell).version,
|
||||
ablationMetrics(board, splitCell(cell).candidate),
|
||||
);
|
||||
}
|
||||
|
||||
/** 消融格正式运行登记的指标:照被采纳候选的冻结协议取;消融格里假设专用指标缺失一律只记缺失、不作废这一格(方法.md 第五部分"指标")。 */
|
||||
export function ablationMetrics(board: Board, candidate: string): HypothesisMetric[] {
|
||||
return protocolMetrics(board, board.protocol(candidate)).map((m) => ({ ...m, missing: "recordMissing" }));
|
||||
export function ablationMetrics(
|
||||
board: Board,
|
||||
candidate: string,
|
||||
): HypothesisMetric[] {
|
||||
return protocolMetrics(board, board.protocol(candidate)).map((m) => ({
|
||||
...m,
|
||||
missing: "recordMissing",
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,21 +102,37 @@ export function ablationMetrics(board: Board, candidate: string): HypothesisMetr
|
||||
export function settle(s: Study, round: number): void {
|
||||
const board = new Board(s.ledger.records());
|
||||
const { candidate, keys } = ablationOf(board, round)!;
|
||||
const events = s.ledger.records().flatMap((r) => (r.kind === "event" ? [r.content] : []));
|
||||
const events = s.ledger
|
||||
.records()
|
||||
.flatMap((r) => (r.kind === "event" ? [r.content] : []));
|
||||
const model = modelInput(board, s, round);
|
||||
const input: SettleInput = { ...model, cells: keys.map((key) => ({ factor: key, outcome: outcomeOf(board, events, round, candidate, key) })) };
|
||||
const input: SettleInput = {
|
||||
...model,
|
||||
cells: keys.map((key) => ({
|
||||
factor: key,
|
||||
outcome: outcomeOf(board, events, round, candidate, key),
|
||||
})),
|
||||
};
|
||||
const output = settleAblation(input);
|
||||
const betInput = { ...model, cells: input.cells };
|
||||
const bet = chooseBet(betInput);
|
||||
// SAFETY: rules 是纯计算,结算和决定的输入输出都是纯 Json 值;账本在写入时校验 Json。
|
||||
s.ledger.transaction(() => {
|
||||
s.ledger.append("settlement", { round, result: { candidate, input, output } as unknown as Json });
|
||||
s.ledger.append("settlement", {
|
||||
round,
|
||||
result: { candidate, input, output } as unknown as Json,
|
||||
});
|
||||
s.ledger.append("decision", {
|
||||
decision: "bet",
|
||||
round,
|
||||
rule: "chooseBet",
|
||||
ruleVersion: 1,
|
||||
params: { direction: model.direction, epsilon: model.epsilon, knownBest: model.knownBest, lambda: model.lambda },
|
||||
params: {
|
||||
direction: model.direction,
|
||||
epsilon: model.epsilon,
|
||||
knownBest: model.knownBest,
|
||||
lambda: model.lambda,
|
||||
},
|
||||
seed: null,
|
||||
input: betInput as unknown as Json,
|
||||
output: bet as unknown as Json,
|
||||
@@ -96,19 +141,40 @@ export function settle(s: Study, round: number): void {
|
||||
}
|
||||
|
||||
/** 一格的结局(方法.md 6.6"一格的几种结局"):没测、跑不起来、证据不足、一起关、有效分数。 */
|
||||
function outcomeOf(board: Board, events: readonly Content<"event">[], round: number, candidate: string, key: string): CellOutcome {
|
||||
if (!board.decision("cells", round)!.output.chosen.includes(key)) return { kind: "untested" };
|
||||
function outcomeOf(
|
||||
board: Board,
|
||||
events: readonly Content<"event">[],
|
||||
round: number,
|
||||
candidate: string,
|
||||
key: string,
|
||||
): CellOutcome {
|
||||
if (!board.decision("cells", round)!.output.chosen.includes(key))
|
||||
return { kind: "untested" };
|
||||
const cell = cellId(candidate, key);
|
||||
const impl = lastAblationImpl(board, cell)!;
|
||||
if (impl.content.cannotRun !== null) return { kind: "cannotRun" };
|
||||
if (events.some((e) => e.event === CELL_NOT_RUN && e.objects.includes(cell))) return { kind: "insufficient" };
|
||||
if (events.some((e) => e.event === CELL_NOT_RUN && e.objects.includes(cell)))
|
||||
return { kind: "insufficient" };
|
||||
const off = [key, ...impl.content.alsoOff];
|
||||
// 几格实际关掉的因子完全相同时,沿用同设置第一格的运行结果(不重跑,方法.md 6.6"一起关")。
|
||||
const alive = aliveCells(board, events, round);
|
||||
const sameAs = new Map(sharedSettings(alive.map((x) => ({ factor: splitCell(x.cell).key, off: x.off }))).map((x) => [x.factor, x.sameAs]));
|
||||
const sameAs = new Map(
|
||||
sharedSettings(
|
||||
alive.map((x) => ({ factor: splitCell(x.cell).key, off: x.off })),
|
||||
).map((x) => [x.factor, x.sameAs]),
|
||||
);
|
||||
const first = sameAs.get(key);
|
||||
const ranCell = first === null || first === undefined ? cell : cellId(candidate, first);
|
||||
const run = board.runs().filter((r) => r.plan.purpose === "ablation" && r.plan.round === round && r.plan.object === ranCell).at(-1)!;
|
||||
const ranCell =
|
||||
first === null || first === undefined ? cell : cellId(candidate, first);
|
||||
const run = board
|
||||
.runs()
|
||||
.filter(
|
||||
(r) =>
|
||||
r.plan.purpose === "ablation" &&
|
||||
r.plan.round === round &&
|
||||
r.plan.object === ranCell,
|
||||
)
|
||||
.at(-1)!;
|
||||
const score = validScore(run.result!.judged);
|
||||
if (off.length > 1) return { kind: "joint", off, score };
|
||||
return score === null ? { kind: "insufficient" } : { kind: "valid", score };
|
||||
@@ -125,11 +191,21 @@ export function unsealChosen(s: Study, round: number): void {
|
||||
const chosen = board.decision("batch", round)!.output.chosen;
|
||||
s.ledger.transaction(() => {
|
||||
for (const candidate of chosen) {
|
||||
if (records.some((r) => r.kind === "unseal" && r.content.candidate === candidate)) continue;
|
||||
if (
|
||||
records.some(
|
||||
(r) => r.kind === "unseal" && r.content.candidate === candidate,
|
||||
)
|
||||
)
|
||||
continue;
|
||||
const seals = board.proposalsOf(candidate).map((id) => {
|
||||
const seq = board.proposal(id).seq;
|
||||
const seal = records.find((r) => r.kind === "seal" && r.content.proposal === seq);
|
||||
if (seal === undefined) throw new Error(`提案 ${id}(记录 ${seq})没有封存记录:提案的作者自评在写入提案时一并封存`);
|
||||
const seal = records.find(
|
||||
(r) => r.kind === "seal" && r.content.proposal === seq,
|
||||
);
|
||||
if (seal === undefined)
|
||||
throw new Error(
|
||||
`提案 ${id}(记录 ${seq})没有封存记录:提案的作者自评在写入提案时一并封存`,
|
||||
);
|
||||
return seal.seq;
|
||||
});
|
||||
s.ledger.append("unseal", { candidate, seals });
|
||||
@@ -158,5 +234,11 @@ function explanationsOf(board: Board, round: number): AblationExplanation[] {
|
||||
return board
|
||||
.published("explanation")
|
||||
.filter((x) => x.round === round)
|
||||
.flatMap((x) => x.content.explanations.map((e, i) => ({ id: explanationId(round, x.author, i + 1), author: x.author, cells: e.cells! })));
|
||||
.flatMap((x) =>
|
||||
x.content.explanations.map((e, i) => ({
|
||||
id: explanationId(round, x.author, i + 1),
|
||||
author: x.author,
|
||||
cells: e.cells!,
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user