1 ポイント 投稿者 GN⁺ 2024-05-16 | 1件のコメント | WhatsAppで共有

Rustのcoreおよびallocクレートの翻訳

初回実行 🐥

  • coq-of-rust を使って Rust の alloc および core クレートを初回実行した結果、数十万行の Coq コードファイルが2つ生成された。
  • これはツールが大規模なコードベースでも動作することを意味するが、生成された Coq コードはコンパイルできない。エラーの発生頻度は低い(数千行に1回程度)。

入力 Rust コードの規模(cloc コマンド基準)

  • alloc: 26,299 行の Rust コード

  • core: 54,192 行の Rust コード

  • マクロを展開して翻訳する必要があるため、実際に翻訳すべき規模はさらに大きい。

生成されたコードの分割 🪓

  • 主な変更点は、coq-of-rust が生成した出力を、各入力 Rust ファイルごとに1つのファイルへ分割したこと。
  • これは定義順序に依存せず翻訳できるため可能である。Rust ファイル間の循環依存は Coq では禁止されるが、それでも分割は可能。

出力規模

  • alloc: 54 個の Coq ファイル、171,783 行の Coq コード
  • core: 190 個の Coq ファイル、592,065 行の Coq コード

コード分割の利点

  • 生成されたコードを読みやすく、探索しやすい
  • 並列コンパイルが可能になり、コンパイルしやすい
  • 1つのファイルに集中してデバッグしやすい
  • コンパイルできないファイルを無視しやすい
  • 単一ファイルの変更追跡がしやすく、保守しやすい

いくつかのバグ修正 🐞

  • モジュール名同士の衝突によるバグがあった。これは impl ブロックのモジュール名を選ぶ際に発生していた。
  • モジュール名により多くの情報を追加して一意性を高めた。たとえば where 句を追加した。

  • Default トレイトの Mapping 型実装:

    #[derive(Default)]
    struct Mapping<K, V> {
      // ...
    }
    
  • 以前の Coq コード:

    Module Impl_core_default_Default_for_dns_Mapping_K_V.
    (* ...trait implementation ... *)
    End Impl_core_default_Default_for_dns_Mapping_K_V.
    
  • 修正後の Coq コード:

    Module Impl_core_default_Default_where_core_default_Default_K_where_core_default_Default_V_for_dns_Mapping_K_V.
    (* ... *)
    

コンパイルできないファイル一覧

  • alloc/boxed.v

  • core/any.v

  • core/array/mod.v

  • core/cmp/bytewise.v

  • core/error.v

  • core/escape.v

  • core/iter/adapters/flatten.v

  • core/net/ip_addr.v

  • これは全ファイルの 4% を占める。コンパイルできるファイルにも未処理の Rust 構造が存在する可能性がある。

例 🔎

Option 型の unwrap_or_default メソッドの元コード

pub fn unwrap_or_default(self) -> T
where
  T: Default,
{
  match self {
    Some(x) => x,
    None => T::default(),
  }
}

翻訳された Coq コード

Definition unwrap_or_default (T : Ty.t) (τ : list Ty.t) (α : list Value.t) : M :=
  let Self : Ty.t := Self T in
  match τ, α with
  | [], [ self ] =>
    ltac:(M.monadic
      (let self := M.alloc (| self |) in
      M.read (|
        M.match_operator (|
          self,
          [
            fun γ =>
              ltac:(M.monadic
                (let γ0_0 :=
                  M.get_struct_tuple_field_or_break_match (|
                    γ,
                    "core::option::Option::Some",
                    0
                  |) in
                let x := M.copy (| γ0_0 |) in
                x));
            fun γ =>
              ltac:(M.monadic
                (M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (| "core::default::Default", T, [], "default", [] |),
                    []
                  |)
                |)))
          ]
        |)
      |)))
  | _, _ => M.impossible
  end.

単純化した関数コード

Definition unwrap_or_default {T : Set}
  {_ : core.simulations.default.Default.Trait T}
  (self : Self T) :
  T :=
  match self with
  | None => core.simulations.default.Default.default (Self := T)
  | Some x => x
  end.
  • この単純化された定義はコード検証時に使用される。同値性の証明は CoqOfRust/core/proofs/option.v にある。

結論

  • 標準ライブラリを形式化することで、Rust プログラムの検証作業を信頼できるものにできる。

  • 次の目標は、依然として煩雑な証明プロセスを単純化すること。特に、シミュレーションが元の Rust コードと同値であることを示す過程で、名前解決、高度な型の導入、副作用の除去といった段階を分離したい。

  • Rust プロジェクトの形式検証に関心がある場合は、contact@formal.land まで連絡してほしい。形式検証は、与えられた仕様に対してバグがないことを数学的に保証する、最高水準の安全性を提供する。

タグ:

  • coq-of-rust
  • Rust
  • Coq
  • 翻訳
  • core
  • alloc

GN⁺の意見

  1. Rust と Coq の統合: Rust と Coq の統合は、Rust プログラムの安定性向上に大きく役立つ。Rust の安全性と Coq の形式検証を組み合わせれば、特に重要なアプリケーションで非常に有用である。
  2. 自動化の重要性: coq-of-rust ツールを用いた自動翻訳は、手作業よりも信頼性が高い。しかし、検証過程では依然としてエラーが発生しうるため注意が必要。
  3. 複雑なコードベース管理: 大規模コードベースを扱ううえで、コード分割は保守やデバッグに大いに役立つ。これは特にチーム開発で重要な要素である。
  4. 形式検証の必要性: 形式検証は、特に金融、医療、航空などの重要分野で不可欠である。Rust と Coq の組み合わせは、これらの分野で大きな価値を提供しうる。
  5. 技術導入時の考慮事項: 新しい技術を導入する際は、学習コストと既存システムとの互換性を考慮すべきである。Coq のような形式検証ツールは学習コストが高い可能性があるため、十分な教育と準備が必要。

1件のコメント

 
GN⁺ 2024-05-16
Hacker Newsの意見

Hacker Newsコメントまとめ要約

  • 自動翻訳ツールの信頼性

    • 自動翻訳ツールは信頼を得つつある。coq-of-rustはRustで書かれており、Coqに変換して正しさを証明できる。これはKen Thompsonの攻撃を防ぐ方法と似ている。
  • プログラム規模と検証

    • Coqのような半自動証明システムで検証されたプログラムの規模は小さい。100%保証のコストは99.9999%保証のコストの10倍になり得る。
  • 翻訳プロセスにおけるエラーの可能性

    • コードをCoqへ翻訳する過程でエラーが発生する可能性が高い。元のコードに対する検証の有効性に疑問を呈している。
  • 暗号資産関連の投稿

    • 暗号資産に関する内容が少ないブログ記事が投稿されている。Pythonに対する同様のアプローチを扱った記事もある。
  • 形式検証の限界

    • 形式検証されたCコンパイラでバグが見つかった事例を覚えている。Coq自体と翻訳に対する信頼性の問題を提起している。
  • Rustの形式検証

    • Rustの基本ライブラリが形式検証されれば、unsafeコードを使わない限り、メモリ処理について形式検証相当の品質を得られるのかと疑問を持っている。
  • 形式検証仕様の作成

    • 形式検証仕様を書くことが、より複雑なプロパティテストを書くのに似ているのかと疑問を持っている。プロパティテストの作成は難しく、時間もかかる。
  • 他のアプローチとの比較

    • AeneasやRustHornBeltとのアプローチの違いを比較してほしいという要望。ポインタと可変借用をどう扱うのかが気になっている。
  • Rustのカーネル採用

    • こうした取り組みがRustのカーネル採用を加速させるかどうかに関心がある。
  • F*へのRustバックエンド追加

    • F*にRustバックエンドを追加するには、どれほどの作業が必要なのかと疑問を持っている。