{"id":20910110,"url":"https://github.com/viperproject/mendel-verifier","last_synced_at":"2025-05-13T07:31:32.194Z","repository":{"id":229312712,"uuid":"733436909","full_name":"viperproject/mendel-verifier","owner":"viperproject","description":"Capability-based verifier for safe Rust clients of interior mutability","archived":false,"fork":false,"pushed_at":"2024-07-18T14:15:06.000Z","size":43242,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-01T19:48:59.692Z","etag":null,"topics":["formal-verification","rust","verification","viper"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/viperproject.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-19T10:25:12.000Z","updated_at":"2025-02-10T13:47:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"bfc01b0a-1f25-431a-99df-ed1f61262d3e","html_url":"https://github.com/viperproject/mendel-verifier","commit_stats":null,"previous_names":["viperproject/mendel-verifier"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperproject%2Fmendel-verifier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperproject%2Fmendel-verifier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperproject%2Fmendel-verifier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperproject%2Fmendel-verifier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/viperproject","download_url":"https://codeload.github.com/viperproject/mendel-verifier/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253894789,"owners_count":21980400,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["formal-verification","rust","verification","viper"],"created_at":"2024-11-18T14:13:56.210Z","updated_at":"2025-05-13T07:31:30.773Z","avatar_url":"https://github.com/viperproject.png","language":"Rust","funding_links":[],"categories":["Verifiers"],"sub_categories":[],"readme":"# Mendel, a verifier for safe Rust clients of interior mutability\n\n[![Test](https://github.com/viperproject/mendel-verifier/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/viperproject/mendel-verifier/actions/workflows/test.yml?query=branch%3Amaster)\n[![Deploy](https://github.com/viperproject/mendel-verifier/actions/workflows/deploy.yml/badge.svg?branch=master)](https://github.com/viperproject/mendel-verifier/actions/workflows/deploy.yml?query=branch%3Amaster)\n[![Test coverage](https://codecov.io/gh/viperproject/mendel-verifier/branch/master/graph/badge.svg)](https://codecov.io/gh/viperproject/mendel-verifier)\n[![Project chat](https://img.shields.io/badge/Zulip-join_chat-brightgreen.svg)](https://prusti.zulipchat.com/)\n\n![AI-generated logo of the Mendel verifier studying Rust](logo.jpg)\n\n**[Mendel](https://github.com/viperproject/mendel-verifier)** is a prototype verifier for safe Rust that uses a novel capability-based technique to enable reasoning about some cases of **interior mutability** of trusted real-world libraries, among which `Rc`, `Arc`, `Cell`, `RefCell`, `Atomic*`, `Mutex` and `RwLock`, requiring minimal client-side annotations.\nThe key concept is a novel notion of **implicit library capability**, which can be used to describe library properties that were decided by the library developers, such as the immutability implied by `Ref` or the non-aliasing implied by `RefMut`.\nIn contrast, the *explicit* properties of the Rust language, such as the immutability of shared references to primitive types, are defined by the Rust language and cannot be changed or defined by the library developers.\nThe implicit capabilities of a library cannot be discovered automatically just by inspecting the type declarations because these typically just contain opaque raw pointers or `UnsafeCell` instances.\nTo solve this, our verifier provides library annotations that make it possible to explicitly declare the implicit capabilities of library types, making them available for automated tools.\n\nThe implementation of Mendel largely reuses [Prusti's codebase](https://github.com/viperproject/prusti-dev), and all Mendel-specific code is contained in [`prusti-viper/src/encoder/safe_clients`](prusti-viper/src/encoder/safe_clients) (~12K lines of code).\nBoth verifiers internally encode Rust programs into the [Viper language](http://www.pm.inf.ethz.ch/research/viper.html).\nHowever, the verification techniques are different: Prusti employs separation logic to prove functional correctness and some memory safety properties, while Mendel fully trusts the compiler and uses its type information to encode capabilities into first-order logic.\nUnlike the current version of Prusti, Mendel natively supports reasoning about memory addresses (e.g., raw pointer comparisons, casts from references to pointers, `addr_of!`, etc.) and in general supports more types (e.g., structures containing references). However, (1) Mendel's technique is less complete than Prusti's when reasoning about safe code (e.g., mutably borrowing in a code branch), (2) unlike Prusti, Mendel does not verify postconditions with pledges, and (3) Mendel's language support is generally limited because of implementation time constraints, notably lacking support for loops and quantifications.\n\nThe goal of Mendel is to demonstrate the viability of a capability-based approach for verifying usages of Rust libraries implemented with unsafe code, making it possible to evaluate its pros and cons. Our aim is to help or inspire future versions of other deductive verifiers for Rust.\n\nIf you have any questions, please feel free to contact us on [Prusti's Zulip chat](https://prusti.zulipchat.com/).\n\n\u003e [!NOTE]\n\u003e The project's name refers to Gregor Mendel, the father of modern genetics, who paved the way for studies of _capabilities_ and _mutations_ of DNA. Our project, instead, studies the _capabilities_ and _interior mutability_ of Rust libraries.\n\n## Test suite and evaluation\n\nThe test suite and evaluation can be found in the [`prusti-tests/tests/verify_safe_clients/fail`](prusti-tests/tests/verify_safe_clients/fail) folder. Inside it, there are 3 subfolders:\n- **[`clients`](prusti-tests/tests/verify_safe_clients/fail/clients)** contains the verified clients used in the evaluation. Among many small hand-written programs, this folder includes two programs that show how to do [Verus](https://github.com/verus-lang/verus)-style reasoning using Mendel (`verus_*.rs`).\n- **[`tutorials`](prusti-tests/tests/verify_safe_clients/fail/tutorials)** contains two programs taken from the [interior mutability chapter](https://dhghomon.github.io/easy_rust/Chapter_41.html) of the Easy Rust tutorial.\n- **[`libraries`](prusti-tests/tests/verify_safe_clients/fail/libraries)** contains the annotations of the libraries used by the clients and tutorials.\n- **[`dev_tests`](prusti-tests/tests/verify_safe_clients/fail/dev_tests)** contains various programs used to test the end-to-end behavior of the verifier.\n\n## Capability annotations\n\n\u003e [!NOTE]\n\u003e This is a brief summary! Read chapter 4 of Federico Poli's PhD thesis (currently still under review) for more examples and an in-depth description.\n\nThis tool provides the following annotation to declare the implicit capabilities of library types with interior mutability:\n```rust\n#[capable(\u003csource\u003e if \u003ccondition\u003e =\u003e \u003ccapability\u003e(\u003ctarget\u003e))]\nimpl \u003ctype\u003e {}\n```\nThe meaning of this annotation is the following: As long as `\u003ccondition\u003e` holds (`true` if omitted), `\u003csource\u003e` holds a capability `\u003ccapability\u003e` for the memory location `\u003ctarget\u003e`.\n\n### Example\n\n```rust\n// The full specification of the library is in \"libraries/refcell_*.rs\"\n\n#[capable(\u0026self =\u003e readRef(self.refcell().as_ptr()))]\nimpl\u003c'b, T\u003e Ref\u003c'b, T\u003e {}\n\n#[capable(\u0026mut self =\u003e writeRef(self.refcell().as_ptr()))]\nimpl\u003c'b, T\u003e RefMut\u003c'b, T\u003e {}\n```\nMeaning: Any `\u0026Ref` instance holds a `readRef` capability for the content of the `RefCell` it refers to, and any `\u0026mut RefMut` instance holds instead a `writeRef` capability.\n\nIn other words, any `\u0026Ref` can be used to obtain a shared reference to the content of the `RefCell`, and any `\u0026mut RefMut` can be used to obtain a mutable reference. This has some useful implications: holding a `\u0026Ref` implies immutability of the content of the `RefCell`, and `RefMut` instances cannot refer to the content of other `Ref` or `RefMut` instances.\n\n### Capability kinds\n\nA brief summary of the capability kinds and their meaning:\n\n| Capability  | Description | Example |\n|-------------|-------------|---------|\n| `writeRef`  | The source can obtain a mutable reference to the target. | `\u0026mut` |\n| `readRef`   | The source can obtain a shared reference to the target. | `\u0026` |\n| `localRef`  | The target is `readRef` and `local`. | ... |\n| `unique`    | The target can be accessed only via the source place. | ... |\n| `local`     | The target is thread-local. | Content of `\u0026RefCell` |\n| `write`     | The target can be written via the source. | Content of `\u0026AtomicI32` |\n| `immutable` | The target is immutable. | The borrow-count of a `\u0026RefMut` |\n| `read`      | The target can be read via the source. | ... |\n| `noWriteRef`  | It is impossible to obtain a mutable reference to the target. | Content of `\u0026Cell`, content of a read-locked `\u0026RwLock` |\n| `noReadRef`   | It is impossible to obtain a shared reference to the target. | Content of `\u0026Cell` |\n\n### Capability properties\n\nA diagram representing the implication and non-aliasing relationships between the capabilities:\n\n```mermaid\nflowchart TD\n    subgraph \"Non-aliasing between capabilities\"\n        direction LR\n        AwriteRef[writeRef] -.- noWriteRef\n        AreadRef[readRef] -.- noReadRef\n        Aunique[unique] -.- Aread[read]\n        Aimmutable[immutable] -.- Awrite[write]\n    end\n    subgraph \"Implications between capabilities\"\n        writeRef --\u003e localRef\n        writeRef --\u003e unique\n        localRef --\u003e readRef\n        localRef --\u003e local\n        readRef --\u003e immutable\n        unique --\u003e local\n        unique --\u003e write\n        local --\u003e read\n        write --\u003e read\n        immutable --\u003e read\n    end\n```\n\n## Using Mendel\n\n**Command line**\n\nThere are two ways to obtain the binaries of the Mendel verifier:\n* Download the precompiled binaries for Ubuntu, Windows, or macOS x64 from a [GitHub release](https://github.com/viperproject/mendel-verifier/releases).\n* Compile from the source code, by installing [rustup](https://rustup.rs/), running `./x.py setup` and then `./x.py build --release`.\n\nBoth options provide the `prusti-rustc` and `cargo-prusti` programs that can be used analogously to, respectively, `rustc` and `cargo build`. The names of the binaries contain \"prusti\" because of compatibility reasons (and lack of time), but the verifier is actually Mendel.\n\n**IDE**\n\nThe binaries of Mendel are compatible with the [\"Prusti Assistant\"](https://marketplace.visualstudio.com/items?itemName=viper-admin.prusti-assistant) extension for VS Code. See the _requirements_ and the troubleshooting section in its [readme](https://github.com/viperproject/prusti-assistant/blob/master/README.md). To use Mendel in the IDE, you should configure the Prusti Assistant extension to use Mendel's binaries, specifying the \"Local\" version of the verifier and the path of the folder containing the binaries.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviperproject%2Fmendel-verifier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fviperproject%2Fmendel-verifier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviperproject%2Fmendel-verifier/lists"}