Skip to content

Rational / Complex / Range / Set — ConstantFolding カバレッジ監査

2026-05-22 生成。Ruby 4.0 の Rational(3,4).methods - Object.new.methods 等から型ごとに 固有メソッドを抽出し、現在の精度カバレッジを分類する。
実際の fold 動作は Rigor::Inference::MethodDispatcher.dispatch を使ったライブ計測による。


記号意味
ConstantFolding(カタログ経由 invoke_unary/invoke_binary・特殊リフト)または RbsDispatch の定数特化で実装済み
🔷別ティア処理済み(RBS で十分精度が出る、または purity:dispatch で fold 不可)
🔲未実装だが Constant[T] 精度向上の価値あり
🚫非対象(破壊的変更・例外を投げる・Enumerator 返却・ランタイム依存)

列挙元: Rational(3,4).methods - Object.new.methods → Ruby 4.0.5
実装ファイル: lib/rigor/inference/method_dispatcher/constant_folding.rb
カタログ: data/builtins/ruby_core/rational.yml — C 実装のメソッドのみ記録。

メソッド状態計測値(Rational(3,4))備考
numerator3カタログ :leaf → invoke_unary
denominator4同上
-@(-3/4)同上
abs(3/4)同上
magnitude(3/4)abs の別名
floor0同上
ceil1同上
truncate0同上
round1同上
to_i0同上
to_f0.75同上
to_r(3/4)同上
rationalize(3/4)同上
hash1516034510...同上
to_s"3/4"同上
inspect"(3/4)"同上
positive?true同上
negative?false同上
real?trueRbsDispatch 定数特化(Numeric RBS に () -> true
imag0RbsDispatch 定数特化(() -> 0
imaginary0imag の別名、同上
+(5/4)カタログ :leaf_when_numeric、Rational 引数で fold
-(1/4)同上
*(3/8)同上
/(3/2)同上
**0.866…同上(結果が Float に変わる場合あり)
<false同上(比較演算子)
<=false同上
>true同上
>=true同上
<=>1同上
quo(3/2)カタログ :leaf_when_numeric
divmod[1, (1/4)]try_fold_divmodTuple[Constant[q], Constant[r]]
==🔷purity: dispatch。RBS bool で十分
infinite?🔷Integer | nilRBS が Integer?。Rational は常に有限だが Numeric の RBS を共有するため特殊化困難
finite?🔷false | true同上。常に true だが特殊化はカタログ構造変更が必要
+@🔷self を返す unary + — RBS で Rational に解決。現行で十分
between?🔷Comparable モジュール経由。RBS で bool
clamp🚫引数の組み合わせが多く戻り型が複雑
coerce🔷[Numeric, Numeric]戻りが [Numeric, Numeric] — RBS で十分
zero?false | trueRATIONAL_UNARY に追加済み。Constant[bool] に畳める。
integer?false | trueRATIONAL_UNARY に追加済み。Constant[bool]
nonzero?Rational | nilRATIONAL_UNARY に追加済み。Constant[Rational|nil]
realRationalRATIONAL_UNARY に追加済み。Constant[Rational]
rect / rectangular[Rational, Numeric]NUMERIC_ARRAY_UNARY_METHODS に追加済み(Rational チェック含む)。Tuple リフト。
polar[Rational, Float | Integer]NUMERIC_ARRAY_UNARY_METHODS に追加済み。Tuple リフト。
abs2RationalRATIONAL_UNARY に追加済み。Constant[Rational]
arg / angle / phase0 | FloatRATIONAL_UNARY に追加済み。Constant[Numeric]
conj / conjugateRationalRATIONAL_UNARY に追加済み。Constant[Rational]
divIntegerRATIONAL_BINARY に追加済み。Constant[Integer]
modulo / %RationalRATIONAL_BINARY に追加済み。Constant[Rational]
remainderRationalRATIONAL_BINARY に追加済み。
fdivFloatRATIONAL_BINARY に追加済み。Constant[Float]
to_c🔲ComplexComplex(self, 0)Constant[Complex]。Complex が SCALAR_CLASSES にあれば可。低優先度
i🔲ComplexComplex(0, self) を返す。同上。低優先度
step🚫反復子
singleton_method_added🚫内部フック
to_intto_i の別名、同等の fold

🔴 高優先度(なし — 主要な数値演算はすべて実装済み)

🟡 中優先度(全項目実装済み)

  • zero?, integer?RATIONAL_UNARY Set に追加済み
  • real, abs2, conj/conjugate → 同上
  • rect/rectangularNUMERIC_ARRAY_UNARY_METHODS 拡張済み
  • divRATIONAL_BINARY Set に追加済み

🟢 低優先度(全項目実装済み)

  • nonzero?, polar, arg/angle/phase → 上記 Set 追加で対応済み
  • modulo, %, remainder, fdiv → 上記 Set 追加で対応済み
  • to_c, i → Complex が Constant キャリアに入っているため原理的に可

列挙元: Complex(3,4).methods - Object.new.methods → Ruby 4.0.5
実装ファイル: constant_folding.rb (catalog + COMPLEX_ARRAY_UNARY_METHODS)
カタログ: data/builtins/ruby_core/complex.yml

メソッド状態計測値(Complex(3,4))備考
real3カタログ :leaf → invoke_unary
imaginary / imag4同上
-@(-3-4i)同上
abs / magnitude5.0同上
abs225同上
arg / angle / phase0.927…同上
rect / rectangular[3, 4]COMPLEX_ARRAY_UNARY_METHODS → Tuple リフト(前セッションで実装)
polar[5.0, 0.927…]同上
conjugate / conj(3-4i)カタログ :leaf
real?falseカタログ :leaf
numerator(3+4i)同上
denominator1同上
hash821720373…同上
finite?true同上
infinite?nil同上(Complex が NaN/Infinite 要素を持つ場合 nil でない)
to_c(3+4i)同上(self を返す)
+(4+6i)カタログ :leaf_when_numeric
-(2+2i)同上
*(-5+10i)同上
/((11/5)-(2/5)*i)同上
**(-0.41…-0.66…i)同上
quo((11/5)-(2/5)*i)カタログ :leaf
fdiv(2.2-0.4i)同上
==falseカタログ :leaf
eql?false同上
integer?🔷false | true常に false だが RBS bool を返す。RBS で十分
+@🔷self を返す unary +。RBS Complex で十分
coerce🔷[Complex, Complex]戻り型複雑。RBS で十分
<=>🔷purity:dispatch。Complex には全順序なし(nil を返す)。RBS で十分
to_s🔷Stringpurity: dispatch(複素数の文字列化が部品に依存)。fold 不可
inspect🔷String同上
rationalize🚫虚部が 0 でない場合 RangeError を raise。推論時安全でない
to_i🚫同上
to_f🚫同上
to_r🚫同上
to_int🚫同上
nonzero?Complex | nilCOMPLEX_UNARY に追加済み。Constant[Complex|nil]
zero?false | trueCOMPLEX_UNARY に追加済み。Constant[bool]
singleton_method_added🚫内部フック

🔴 高優先度(なし — 前セッションで主要ギャップを解消済み)

🟡 中優先度(全項目実装済み)

  • zero?, nonzero?COMPLEX_UNARY Set に追加済み(unary_ops_forComplex ケース追加)

🟢 低優先度(上記のみ)


列挙元: (1..5).methods - Object.new.methods → Ruby 4.0.5
実装ファイル: constant_folding.rbRANGE_FOLD_METHODS, try_fold_range_constant_unary
カタログ: data/builtins/ruby_core/range.yml

メソッド状態計測値((1..5))備考
begin1カタログ :leaf → invoke_unary
end5同上
exclude_end?false同上
hash-800979437…同上
to_s"1..5"同上
first (0引数)1try_fold_range_constant_unary
last (0引数)5同上
min (0引数)1同上
max (0引数)5同上
size5同上(RANGE_FOLD_METHODS:size あり)
count (0引数)5同上(:count あり)
to_a[1, 2, 3, 4, 5]range_to_a_tupleTuple[Constant…]
to_setSet[1, 2, 3, 4, 5]meta_newset_new_lift 経由 → Constant[Set]
include?trueカタログ :leaf + binary fold
member?trueinclude? の別名(カタログに同エントリ)
cover?trueカタログ :leaf + binary fold
===trueカタログ :leaf + binary fold
inspect🔷Stringpurity: dispatch(begin/end の inspect を呼ぶ)。fold 不可
==🔷purity: dispatch。RBS bool で十分
eql?🔷purity: dispatch。同上
overlap?🔷false | truepurity: dispatch。RBS bool で十分
bsearch🚫purity: dispatch、ブロック依存
step🚫反復子
each🚫反復子
reverse_each🚫反復子
%🚫Enumerator / ブロック反復子
all? / any? / none? / one?🔷BlockFolding 経由
map / select / reject / flat_map🔷BlockFolding / RBS
sum🔲Integer 等差数列は n*(a+b)/2 で Constant に畳める。中優先度
entriesArray[Dynamic[top]]RANGE_FOLD_METHODS:entries 追加 + range_constant_unarywhen :entries 追加済み。
minmax[Dynamic[top]|nil, Dynamic[top]|nil]range_constant_unarywhen :minmax + range_minmax_tuple 追加済み。
first(n)🔲Array[Dynamic[top]]整数引数あり形式。Tuple リフト可。中優先度
last(n)🔲Array[Dynamic[top]]同上
to_h🚫Range 要素が [k, v] の 2 要素 Array でない限り raise

🔴 高優先度(実装済み)

  • entriesRANGE_FOLD_METHODS:entries 追加 + range_constant_unarywhen :entries then range_to_a_tuple(range) 追加済み

🟡 中優先度(実装済み)

  • minmaxrange_constant_unarywhen :minmax + range_minmax_tuple 追加済み
  • first(n) / last(n)try_fold_binary_set または専用の try_fold_range_constant_binary で整数引数 n ≤ LIMIT の場合に Tuple リフト

🟢 低優先度

  • sum → 等差数列公式で Constant に畳む(ただし Integer Range のみ対象)

列挙元: Set.new.methods - Object.new.methods → Ruby 4.0.5
実装ファイル: constant_folding.rbSET_ARRAY_UNARY_METHODS, catalog 経由)
カタログ: data/builtins/ruby_core/set.yml, set_catalog.rb

Set.yml の aliases: セクション(length → size, member? → include?, + → |, === → include?)は catalog_allows?method_entry から見えない(instance_methods キーにはない)。 そのため、これらの別名メソッドは現在すべて fold できずに RBS へ fallback する。

メソッド状態計測値(Set[1,2,3])備考
size3カタログ :leaf → invoke_unary
empty?false同上
compare_by_identity?false同上
flattenSet[1, 2, 3]同上(結果が Constant[Set]
join"123"同上(引数なし区切り文字なし)
hash-379102493…同上
to_a[1, 2, 3]SET_ARRAY_UNARY_METHODS → Tuple リフト
entries[1, 2, 3]同上(:entriesSET_ARRAY_UNARY_METHODS に含まれる)
include?false(Set 引数)/ true(整数引数)カタログ :leaf + binary fold
subset?falseカタログ :leaf + binary fold
superset?false同上
proper_subset?false同上
proper_superset?false同上
-Set[1]カタログ :leafset_i_difference)→ Constant[Set]
|Set[1, 2, 3, 4]カタログ :leafset_i_union)→ Constant[Set]
^Set[1, 4]カタログ :leafset_i_xor)→ Constant[Set]
<=>nilカタログ :leaf
<カタログ :leafproper_subset? の別名だが直接登録)
>カタログ :leafproper_superset? の別名)
<=カタログ :leafsubset? の別名)
>=カタログ :leafsuperset? の別名)
==🔷false | truepurity: dispatchrb_equal 呼び出し)。RBS bool で十分
inspect🔷Stringpurity: dispatch。RBS String で十分
to_s🔷Stringinspect の別名。同上
to_set🔷Set[Dynamic[top]]purity: block_dependent。RBS で十分
to_h🔷Enumerable 経由。RBS で十分
disjoint?🔷false | trueset_catalog.rbmutating_selectors でブロック済み(内部で rb_funcall(other, :any?, ...) を呼ぶ)。RBS bool で十分
intersect?🔷false | truepurity: dispatch。同上
&🔷Setpurity: block_dependentset_i_intersectionset_iter 呼び出し)。fold 不可
add / add?🚫破壊的変更
<<🚫add の別名。破壊的変更
clear / delete / delete? / delete_if🚫破壊的変更
replace / merge / subtract🚫破壊的変更
collect! / map! / select! / filter! / reject! / keep_if🚫破壊的変更
flatten!🚫破壊的変更
each🚫反復子
classify🚫ブロック依存、戻り型複雑
divide🚫同上
compare_by_identity🚫破壊的変更
reset🚫内部構造リビルド
lengthIntegerMethodCatalog#method_entry のエイリアス解決で対応済み。
member?false | true同上。
+Set同上。
===false | true同上。
Enumerable 継承メソッド(all?, any?, map, select 等)🔷BlockFolding / RBS

🔴 高優先度(なし — 主要な集合演算は実装済み)

🟡 中優先度(全項目実装済み)

  • length, member?, + の YAML エイリアス解決
    • MethodCatalog#method_entryresolve_alias_entry を追加し、aliases セクションも参照するよう拡張
    • === も同一の仕組みで解決

🟢 低優先度(実装済み)

  • === → 同上の対応に含める

5. Phase 2 — ギャップのティア分類

Section titled “5. Phase 2 — ギャップのティア分類”

Tier A — UNARY / BINARY Set への追加

Section titled “Tier A — UNARY / BINARY Set への追加”

invoke_unary / invoke_binary が呼ぶだけで結果が Constant[T] になるもの。unary_ops_for / ops_for に新しい when ケースを追加し、RATIONAL_UNARY, COMPLEX_UNARY, RATIONAL_BINARY 定数 Set を定義済み。

メソッド期待戻り型優先度
Rationalzero?Constant[bool]🟡
Rationalinteger?Constant[bool]🟡
RationalrealConstant[Rational]🟡
Rationalabs2Constant[Rational]🟡
Rationalconj, conjugateConstant[Rational]🟢
Rationalnonzero?Constant[Rational|nil]🟢
RationaldivConstant[Integer]🟡
Rationalmodulo, %Constant[Rational]🟢
RationalremainderConstant[Rational]🟢
RationalfdivConstant[Float]🟢
Complexzero?Constant[bool]🟡
Complexnonzero?Constant[Complex|nil]🟢

実装手順(完了):

  1. constant_folding.rbRATIONAL_UNARY = Set[:zero?, :integer?, :real, :abs2, :conj, :conjugate, :nonzero?].freeze を追加
  2. RATIONAL_BINARY = Set[:div, :modulo, :%, :remainder, :fdiv].freeze を追加
  3. unary_ops_forelse Set.new の前に when Rational then RATIONAL_UNARY / when Complex then COMPLEX_UNARY ケースを追加
  4. ops_forwhen Rational then RATIONAL_BINARY を追加
  5. 同様に COMPLEX_UNARY = Set[:zero?, :nonzero?].freeze を追加

Tier A(Tuple リフト拡張)— RANGE_FOLD_METHODS 追加

Section titled “Tier A(Tuple リフト拡張)— RANGE_FOLD_METHODS 追加”
ファイル変更優先度
constant_folding.rbRANGE_FOLD_METHODS:entries 追加済み🔴
constant_folding.rbrange_constant_unarywhen :entries 追加済み(to_a と同じ range_to_a_tuple 実装)🔴
constant_folding.rbRANGE_FOLD_METHODS:minmax 追加 + range_constant_unarywhen :minmax + range_minmax_tuple 追加済み🟡
対象修正箇所優先度
Set#length, Set#member?, Set#+method_catalog.rbresolve_alias_entry 追加 + method_entry にエイリアス解決フォールバック追加済み🟡
Set#===同上🟢

なし(Rational / Complex / Range / Set は ShapeDispatch が扱う構造型ではない)。

なし(本スコープ外。Range#sum, Range#first(n) 等はブロックなしの数値計算なので Tier A が適切)。

Tier D — 新 singleton-folding モジュール

Section titled “Tier D — 新 singleton-folding モジュール”

なし(Rational / Complex / Range / Set の singleton メソッドに新モジュールが必要なものはない)。


作業変更先ファイル
RATIONAL_UNARY / RATIONAL_BINARY 追加lib/rigor/inference/method_dispatcher/constant_folding.rb
COMPLEX_UNARY 追加同上
Range#entries / minmax同上(RANGE_FOLD_METHODS, range_constant_unary
Set エイリアス解決lib/rigor/inference/builtins/set_catalog.rb + method_catalog.rb
ユニットスペックspec/rigor/inference/method_dispatcher/constant_folding_spec.rb
統合フィクスチャ(Rational/Complex)spec/integration/fixtures/rational_catalog.rb
統合フィクスチャ(Range/Set)spec/integration/fixtures/range_catalog.rb

© 2026 TypedDuck. Licensed under CC BY-SA 4.0.