
2026/07/09 20:16
Show HN:Wyrm ― オープンソースの正しさエンジンを用いて、触覚で代数問題を解く
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Wyrm-Math は、iOS および Android 向け的手勢操作に基づく代数アプリ「Wyrm Math」を通じて、モバイル数学における画期的な成果を象徴しています。このアプリケーションは、依存関係も DOM サポートもない純粋な TypeScript で記述された厳密な符号式代数エンジンを動力源としています。そのエンジン operates on(動作する)核心となる不変条件として、「条件付き正当性」を採用しており、ここでは等式の検証を行う従来の計算機とは異なり、法則的な書き換え遷移のみが実行可能で、変数を定義しない点などを近似値ではなく「未定義」として扱い、条件(例:分母がゼロでないこと)を 1 級の仮定として保持します。演算は bigint を介した有理数を用いて厳密に実施され、浮動小数点数誤差を防ぎつつ、未定義の点を単なる近似値ではなく「未定義」として扱います。エンジンでは不変な AST(抽象構文木)を採用し、安定したノード ID も確保しており、引き算や除法のノードを使用しない設計となっています。これには線形方程式、冪、二次方程式などを網羅する約 25 件の豊富なルールのセットを伴い、x²=9 といった場合分けも対応しています(例:x²=9 のようなケースの分割)。レイアウトジオメトリは静的な計量表を用いてこれらの木構造をアニメーション付きの記号に変換し、制限事項、拡張、固定された変数などを追跡するための判定システムを併用します。開発プロセスでは
pnpm、Vitest、fast-check を使用しており、MIT ライセンスの下でオープンソース化されています。また、誤りを生じやすい近似手法ではなく、すべての論理的パスを保持するシステムへと置き換えられ、その導出ログはポインタナビゲーションを通じてアクセス可能となっています。本文
Wyrm-Math: 厳密な条件付き妥当性を保証する符号計算エンジン
wyrm-math は、ドラッグ&ドロップ操作や数学的変形を通じて方程式を可視化・操作するための高性能な計算エンジンです。ユーザーは等号の項を移動させたり、指数に触れて展開させたりできますが、システムは「合法的な手順のみを可能にし、違法な手順を物理的に不可能にする」という不変則に基づいて動作します。
特徴と設計思想
-
条件付き妥当性 (Conditional Soundness)
- 方程式は検証されず、再定義ルールによってのみ変形されます。
- 操作の前後で**「仮定(Assumptions)」**が視覚化され、第一級市民として扱われます。
- 除外条件(例:$b \neq 0$)や外れ解を生む操作は禁止されることはありませんが、必ずしも保証されないことを明示的な仮定として表現します。
-
技術スタックと互換性
- 純粋な TypeScript で実装され、外部依存関係はありません。
- DOM を使用せず、Node.js、ブラウザ、Web Worker、ネイティブ Web View など、環境に制限されず動作します。
- iOS / Android アプリ「Wyrm Math」のバックエンドエンジンとしても機能しています。
-
ライセンスと収益モデル
- エンジン自体は MIT ライセンス。
- 開発の収益源は、「Wyrm Math」というアプリの販売により賄われています。
実装例
import { parseEquation, Derivation, enumerateMoves, ruleById, layoutNode, exprToString, } from "wyrm-math"; const d = new Derivation(parseEquation("2x + 3 = 11")); // ユーザーが合法的に行える操作の列挙 const moves = enumerateMoves(d.current); // 「3」を等号の右側にドラッグして移動させる // UI が Move を選択し、エンジンが合法性を保証(事前条件チェック済み) const move = moves.find((m) => m.ruleId === "move-term-across")!; d.apply(ruleById(move.ruleId), move.location, move.params); console.log(exprToString(d.current.equation)); // 出力:2x = 11 + -3 // デザイン用のメトリックテーブルからの配置済みボックス取得 const layout = layoutNode(d.current.equation);
内部構成(API グループ)
公開 API は
src/index.ts に集約され、以下の 10 つの機能グループに整理されています。
| グループ | 主な機能と特徴 |
|---|---|
| 表現木 (Expression trees) | 不変な抽象構文木(AST)を使用。N-ary Sum/Productを採用し、減算や除算の節ノードを持たず、$a-b$ は と表現します。 |
| 厳密算術 (Exact arithmetic) | 大きな整数 (bigint) および有理数を使用。浮動小数点はありません。$\sqrt{2}$ などは近似値ではなく「未定義の点」として扱われます。 |
| 評価 (Evaluation) | は、サンプル点で厳密な関係判定を行います(, , など)。片方が未定義の場合は を返します。 |
| 解析と出力 (Parsing & printing) | ⇄ で丸め出し性質をテスト可能です。暗黙的な乗算や累乗に対応しますが、小数は拒絶します。 |
| 判断と仮定 (Judgments & assumptions) | 基本単位は です。制限(解の喪失)、拡張(新解の獲得)、固定点(ユーザーの前提)を管理します。棄却された仮定は削除されません。 |
| ルールと導出 (Rules & derivations) | だけが方程式を変化させます。導出ログは付加専用木であり、アンロード操作はポインタ移動のみです。分岐(場合分け)はライブな兄弟節にフォークされます。 |
| 組み込みルール (Built-in rules) | 線形方程式、分配法則、指数法則、不等式処理など、約 25 のルールを備えます。すべてのルールのプロパティテストで仮定の下での解集合尊重を保証します。 |
| 移動列挙 (Move enumeration) | は、ハンドル付きの全合法な機能(アフォードンス)を返します。「x=0」をピン留めすると、「x で割る」操作は自動的に無効化されます。 |
| レイアウト幾何学 (Layout geometry) | は木構造を分数、上付き文字などで配置されたボックスにマッピングします。子ツリーの幾何学は文脈依存せず独立しており、ID キー付けによるアニメーションを実現します。 |
| ルール作成ツールキット | 再構築時の ID 保持、不変則修復、差分帳簿管理、新ルールの仮定ライフサイクルクエリを提供します。詳細は を参照ください。 |
デザインコミットメント
-
厳密さ (Exactness)
- すべての算術は bigint 有理数で実行されます。未定義となる点(ゼロ除算、無理数の根など)は近似的ではなく「未定義」として扱われます。
-
安定した ID (Stable ids)
- すべてのノードに安定した ID が付与され、操作によって子ツリーの ID は保持されます。これにより、レンダラーが剛体としてノードを移動・アニメーションさせることができます。
-
条件付き妥当性 (Conditional soundness)
- 制限ルールに対しては、仮定を満たさない置換を拒絶し真実の保持を保証します。
- 拡張ルールについては、「解を失わない」ことを弱体化チェックとし、
が獲得義務をカバーします。checkSolution
-
和集合 (Disjunction)
- 分岐ルール(例:$x^2 = 9 \Rightarrow x=3 \lor x=-3$)は、元の解集合との和集合となる複数の結果を返します。導出ツリーはすべての腕をライブに保ちます。
開発ガイド
ビルドとテストには以下のコマンドを使用してください。
pnpm install pnpm test # vitest + fast-check(プロパティテストがプロジェクトの魂) pnpm typecheck pnpm build # dist/ を出力(ESM + d.ts)
- 重要: エンジンは DOM フリーに保たれている必要があります。
には DOM ライブラリを記載しなくてはいけません。tsconfig.json - テスト
は、ソースコードをブラウザグローバル変数でスキャンします。test/boundary.test.ts