Menerjemahkan crate core dan alloc Rust
Eksekusi awal 🐥
- Hasil eksekusi awal crate
allocdancoreRust menggunakancoq-of-rustmenghasilkan dua berkas kode Coq yang masing-masing berukuran ratusan ribu baris. - Ini menunjukkan bahwa alat tersebut bekerja bahkan pada codebase besar, tetapi kode Coq yang dihasilkan tidak dapat dikompilasi. Error muncul relatif jarang (sekitar sekali tiap beberapa ribu baris).
Ukuran kode Rust input (berdasarkan perintah cloc)
-
alloc: 26.299 baris kode Rust -
core: 54.192 baris kode Rust -
Karena penerjemahan harus dilakukan setelah macro diekspansi, ukuran sebenarnya yang harus diterjemahkan lebih besar.
Pemisahan kode hasil generasi 🪓
- Perubahan utamanya adalah keluaran yang dihasilkan
coq-of-rustdibagi menjadi satu berkas untuk setiap berkas Rust input. - Ini dimungkinkan karena penerjemahan dapat dilakukan tanpa bergantung pada urutan definisi. Dependensi siklik antarberkas Rust memang dilarang di Coq, tetapi pemisahan tetap bisa dilakukan.
Ukuran output
alloc: 54 berkas Coq, 171.783 baris kode Coqcore: 190 berkas Coq, 592.065 baris kode Coq
Keuntungan pemisahan kode
- Kode yang dihasilkan lebih mudah dibaca dan ditelusuri
- Kompilasi lebih mudah karena bisa dilakukan secara paralel
- Debugging lebih mudah karena dapat fokus pada satu berkas
- Lebih mudah mengabaikan berkas yang tidak bisa dikompilasi
- Lebih mudah melacak perubahan pada satu berkas sehingga maintenance lebih sederhana
Perbaikan beberapa bug 🐞
- Ada bug akibat konflik antar nama modul. Ini terjadi saat memilih nama modul untuk blok
impl. - Lebih banyak informasi ditambahkan ke nama modul untuk meningkatkan keunikannya. Misalnya, dengan menambahkan klausa
where.
Contoh
-
Implementasi tipe
Mappinguntuk traitDefault:#[derive(Default)] struct Mapping<K, V> { // ... } -
Kode Coq sebelumnya:
Module Impl_core_default_Default_for_dns_Mapping_K_V. (* ...trait implementation ... *) End Impl_core_default_Default_for_dns_Mapping_K_V. -
Kode Coq setelah perbaikan:
Module Impl_core_default_Default_where_core_default_Default_K_where_core_default_Default_V_for_dns_Mapping_K_V. (* ... *)
Daftar berkas yang tidak dapat dikompilasi
-
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 -
Ini mencakup 4% dari seluruh berkas. Bahkan pada berkas yang berhasil dikompilasi pun masih mungkin ada struktur Rust yang belum tertangani.
Contoh 🔎
Kode asli metode unwrap_or_default pada tipe Option
pub fn unwrap_or_default(self) -> T
where
T: Default,
{
match self {
Some(x) => x,
None => T::default(),
}
}
Kode Coq hasil terjemahan
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.
Kode fungsi yang disederhanakan
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.
- Definisi yang disederhanakan ini digunakan saat verifikasi kode. Pembuktian ekuivalensinya ada di
CoqOfRust/core/proofs/option.v.
Kesimpulan
-
Dengan memformalkan standard library, pekerjaan verifikasi program Rust menjadi dapat dipercaya.
-
Target berikutnya adalah menyederhanakan proses pembuktian yang masih merepotkan. Secara khusus, mereka ingin memisahkan langkah-langkah seperti resolusi nama, pengenalan tipe tingkat lanjut, dan penghapusan efek samping dalam proses menunjukkan bahwa simulasi ekuivalen dengan kode Rust asli.
-
Jika tertarik pada verifikasi formal untuk proyek Rust, silakan hubungi contact@formal.land. Verifikasi formal memberikan tingkat keamanan tertinggi dengan menjamin secara matematis tidak adanya bug terhadap spesifikasi yang diberikan.
Tag:
- coq-of-rust
- Rust
- Coq
- terjemahan
- core
- alloc
Opini GN⁺
- Integrasi Rust dan Coq: Integrasi Rust dan Coq sangat membantu meningkatkan keandalan program Rust. Menggabungkan keamanan Rust dengan verifikasi formal Coq sangat berguna, terutama untuk aplikasi penting.
- Pentingnya otomasi: Penerjemahan otomatis menggunakan alat
coq-of-rustlebih andal dibanding kerja manual. Namun, karena error masih dapat muncul dalam proses verifikasi, kehati-hatian tetap diperlukan. - Pengelolaan codebase kompleks: Dalam menangani codebase besar, pemisahan kode sangat membantu maintenance dan debugging. Ini merupakan faktor penting terutama dalam kerja tim.
- Kebutuhan verifikasi formal: Verifikasi formal sangat penting khususnya di bidang kritis seperti keuangan, medis, dan penerbangan. Kombinasi Rust dan Coq dapat memberi nilai besar di bidang-bidang ini.
- Pertimbangan adopsi teknologi: Saat mengadopsi teknologi baru, perlu mempertimbangkan learning curve dan kompatibilitas dengan sistem yang ada. Alat verifikasi formal seperti Coq bisa memiliki learning curve yang tinggi, sehingga dibutuhkan pelatihan dan persiapan yang memadai.
1 komentar
Komentar Hacker News
Ringkasan kumpulan komentar Hacker News
Keandalan alat terjemahan otomatis
Ukuran program dan verifikasi
Kemungkinan kesalahan dalam proses penerjemahan
Postingan terkait kripto
Batasan verifikasi formal
Verifikasi formal Rust
unsafe.Penulisan spesifikasi verifikasi formal
Perbandingan dengan pendekatan lain
Adopsi Rust di kernel
Penambahan backend Rust untuk F*