Skip to content

Commit f869a4c

Browse files
Edits to the README and other markdown files. (#7)
This fixes typos in the README and gives links to the RustString.md and Iterators.md. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.
1 parent d185505 commit f869a4c

File tree

3 files changed

+57
-41
lines changed

3 files changed

+57
-41
lines changed

README.md

+48-35
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@
55

66
## rust-lean-models
77

8-
Lean models of various Rust libraries to facilitate Lean-based verification of Rust programs.
8+
Lean models of various functions and data types from Rust libraries to facilitate Lean-based verification of Rust programs.
99

1010

1111
## Description
12-
The library defines equivalent Lean versions of functions from the Rust standard library.
13-
This library is intended to be used for verifying Rust programs via Lean.
12+
This library is intended to be used for verifying Rust programs via Lean. It
13+
defines equivalent Lean versions of functions from the Rust standard library.
14+
15+
The Lean definitions are based on the description of the Rust functions, which is published at https://doc.rust-lang.org/std.
1416

15-
The Lean implementation is based on the description of the Rust functions, which are published at https://doc.rust-lang.org/std.
1617
The library includes:
17-
- Definitions of functions equivalent to those from the Rust standard library
18+
- Definitions of Lean functions equivalent to those from the Rust standard library
1819
- Proofs that these definitions are consistent with the description of the Rust functions
1920
- Supporting lemmas and theorems for proof construction
2021

@@ -42,40 +43,48 @@ The library includes:
4243
## Usage
4344
### Translating a Rust program
4445

45-
For any Rust built-in functions which are used in user code, map it with
46-
the corresponding function name in the library (see the Tables below).
46+
Replace the Rust built-in functions that are used in your code with the
47+
corresponding Lean function in this library.
48+
49+
Tables in [RustString.md](RustLeanModels/RustString.md)
50+
and [Iterators.md](RustLeanModels/Iterator.md) give the mapping from Rust types
51+
and functions to their Lean equivalents.
4752

4853
### Proof Tutorial
54+
4955
We demonstrate the applications of the library and some proof techniques
50-
for String programs in
51-
[ProofTutorial.lean](https://github.com/model-checking/rust-lean-models/tree/main/RustLeanModels/ProofTutorial.lean)
52-
through two simple programs that compute the longest common prefix
53-
and longest common substring of the two input strings.
56+
for string programs in
57+
[ProofTutorial.lean](https://github.com/model-checking/rust-lean-models/tree/main/RustLeanModels/ProofTutorial.lean).
58+
This tutorial shows the correctness of two simple programs that compute the longest common prefix
59+
and longest common substring of the two strings.
5460
More examples can be found in
5561
[ProofExample.lean](https://github.com/model-checking/rust-lean-models/tree/main/RustLeanModels/ProofExample.lean).
5662

57-
## Implementation
63+
## Details
5864

65+
### Recursive function definitions
5966

60-
### Recursive function definition
6167
For each Rust function, we provide a recursive Lean function. Implementing
62-
the equivalent functions in Lean recursively enables user to construct
68+
the equivalent functions in Lean recursively enables users to construct
6369
induction proofs conveniently. The Lean function has the same name as the Rust original,
64-
except when the Rust name clashes with a Lean keyword. In case of a clash, a Rust function 'func_name'
70+
except when the Rust name clashes with a Lean keyword. In case of a clash, a Rust function `func_name`
6571
is renamed to `rust_func_name` in Lean.
6672

6773
Implementing a function recursively may requires some extra parameters.
68-
In those cases, first, we implement an auxiliary function (name: `func_name_aux`) which is defined
69-
recursively with the parameters, then we define the function `func_name` based on the auxiliary function
70-
with initial values for the parameters.
74+
In those cases, we first define an auxiliary function (name: `func_name_aux`) which is defined
75+
recursively with the extra parameters, then we define the function `func_name` based on the auxiliary function
76+
with initial values for the parameters.
7177
For example, `char_indices` is defined based on `char_indices_aux` as
72-
`def char_indices (s: Str) := char_indices_aux s 0`.
78+
```lean
79+
def char_indices (s: Str) := char_indices_aux s 0
80+
```
7381

74-
For Rust functions involving the `Pattern` type, we implement two recursive sub-functions
75-
(name: `func_name_char_filter` and `func_name_substring`) which replace the `Pattern` type
76-
in the input by either a char filter (or type`Char → Bool`) or a `List Char`. Then we define
77-
the function `func_name` based on these two sub-functions by matching the input of `Pattern` type.
78-
For example, `split` is defined by two sub-functions `split_char_filter` and `split_substring` as:
82+
For Rust functions that use the Rust `Pattern` type, we implement two recursive sub-functions
83+
(name: `func_name_char_filter` and `func_name_substring`) that replace the `Pattern` type
84+
in the input with either a char filter (of type`Char → Bool`) or a string (of type `List Char`).
85+
Then we define the function `func_name` based on these two sub-functions by matching the
86+
input of `Pattern` type. For example, `split` is defined by two sub-functions
87+
`split_char_filter` and `split_substring` as:
7988

8089
```lean
8190
def split (s: Str) (p: Pattern) := match p with
@@ -84,7 +93,8 @@ def split (s: Str) (p: Pattern) := match p with
8493
| Pattern.FilterFunction f => split_char_filter s f
8594
| Pattern.WholeString s1 => split_substring s s1
8695
```
87-
All recursive implementations are proven to be "correct" in the sense that
96+
97+
All recursive implementations are proven to be "correct" in the sense that
8898
they are consistent with the descriptions of the Rust versions (see below for more details).
8999

90100
## Correctness Proofs
@@ -118,7 +128,6 @@ In some cases, constructing a non-induction proof using the definitional version
118128
if i < Char.utf8Size h then false else is_char_boundary t (i - Char.utf8Size h)
119129
```
120130
121-
122131
and an equivalence theorem
123132
124133
```lean
@@ -128,7 +137,7 @@ In some cases, constructing a non-induction proof using the definitional version
128137
When the description of a Rust function cannot be efficiently expressed in Lean (requires recursions, or is unintuitive),
129138
we can:
130139
- Define the definitional version (similar to Case 1) based on a recursive trivial function, then prove the equivalence theorem.
131-
For example, the `byteSize_def` function is defined on the simple function `sum_list_Nat`
140+
For example, the `byteSize_def` function is based on the function `sum_list_Nat`
132141
that computes the sum of a list of natural numbers:
133142
134143
```lean
@@ -138,20 +147,23 @@ that computes the sum of a list of natural numbers:
138147
139148
- Define and prove the correctness of one/some subordinate function(s),
140149
then define the definitional version based on them.
141-
For example, to define `split_inclusive_char_filter_def`, firstly we define and prove the coreectness of two functions:
150+
For example, to define `split_inclusive_char_filter_def`, we first define and prove the correctness of two functions:
142151
- `list_char_filter_charIndex (s: Str) (f: Char → Bool)`: returns the list of positions of characters in `s` satisfying the filter `f`
143152
144-
- `split_at_charIndex_list (s: Str) (l: List Nat)`: split the strings `s` at positions in `l`
153+
- `split_at_charIndex_list (s: Str) (l: List Nat)`: splits the strings `s` at positions in `l`
145154
146-
then define `split_inclusive_char_filter_def` based on them:
155+
then we define `split_inclusive_char_filter_def` as follows:
147156
148157
```lean
149-
def split_inclusive_char_filter_def (s: Str) (f: Char → Bool):= split_at_charIndex_list s (List.map (fun x => x+1) (list_char_filter_charIndex s f))
158+
def split_inclusive_char_filter_def (s: Str) (f: Char → Bool) :=
159+
split_at_charIndex_list s (List.map (fun x => x+1) (list_char_filter_charIndex s f))
150160
```
151161
152-
### When the Rust documentation describes properties of the return value
162+
### When the Rust documentation describes properties of the return value
163+
153164
We state and prove a soundness theorem for the function with
154165
name: `func_name_sound` and type: `x = func_name input1 input2 ... ↔ properties of x`.
166+
155167
For example, the soundness theorem for the function `floor_char_boundary` defined as:
156168
157169
```lean
@@ -174,16 +186,17 @@ theorem floor_char_boundary_sound: flp = floor_char_boundary s p
174186
- The modus ponens (→) direction of the theorem is enough to ensure the correctness of the recursive version
175187
if the properties in the right-hand-side ensure that the function in the left-hand-side is deterministic.
176188
- The modus ponens reverse (←) direction ensures that we stated enough properties in right-hand-side such that
177-
it can be satisfied by only one function.
178-
- If the function returns an option, we separately state and prove two soundness theorems for the two cases
189+
it can be satisfied by only one function.
190+
191+
If the function returns an option, we separately state and prove two soundness theorems for the two cases
179192
of the return value: `func_name_none_sound` and `func_name_some_sound`. For example:
180193

181194
```lean
182195
theorem split_at_none_sound : split_at s p = none ↔ ¬ ∃ s1, List.IsPrefix s1 s ∧ byteSize s1 = p
183196
theorem split_at_some_sound : split_at s p = some (s1, s2) ↔ byteSize s1 = p ∧ s = s1 ++ s2
184197
```
185198

186-
- For functions involving the `Pattern` type, we separately state and prove two equivalent/soundness
199+
For functions involving the `Pattern` type, we separately state and prove two equivalent/soundness
187200
theorems for the two sub-functions discussed previously (`func_name_char_filter_EQ` and `func_name_substring_EQ`)
188201
or (`func_name_char_filter_sound` and `func_name_substring_sound`). For example:
189202

RustLeanModels/Iterator.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,19 @@
55
## Rust Iterator
66

77
## Data type conversion
8-
- Iterator is converted to `List` in Lean. There are many equivalences in Lean library of List for Iterator's functions.
8+
- The `Iterator` trait is converted to `List` in Lean. Many functions defined in Lean's core are
9+
equivalent to Rust functions that operate on iterators.
910

1011

11-
## Implemented functions in Iterator.lean
12+
## Functions implemented in Iterator.lean
1213

1314
| Rust Iterator function | Lean equivalent function | Description link |
1415
| ----------------------------- | ------------------- | ---------------------- |
1516
| std::iter::Iterator::flatten | flatten | https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.flatten |
1617
| std::iter::Iterator::next | next | https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.next |
1718
| std::iter::Iterator::peek | peek | https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.peek |
1819

19-
## Implemented functions in Lean library of List
20+
## Functions already defined in Lean
2021

2122
| Rust Iterator function | Lean equivalent function | Description link |
2223
| ----------------------------- | ------------------- | ---------------------- |

RustLeanModels/RustString.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ This assumes that overflow exceptions will not happen. Note that overflow except
1111
in Rust programs which use usize for String indexing when the Strings size are GBs.
1212
- Byte Lists (for UTF8 conversion) are represented as `List Nat` in Lean. Strings are converted from `List Char` to `List Nat` by the function `Str_toUTF8`.
1313
This function ensures that the output is a valid UTF8 string. We use three axioms: `Char_Pos0`, `Char_Diff`, and `Char_Size` which describe
14-
the properties of UTF8 encoding (see `RustLeanModels\UTF8Str.lean`).
14+
the properties of UTF8 encoding (see [RustLeanModels/UTF8Str.lean](UTF8Str.lean)).
1515
- The trait std::str::pattern::Pattern is converted to the inductive type `Pattern` (see RustString.lean).
1616

1717

1818

19-
## Implemented functions in RustString
19+
## Functions defined in RustString
2020
| Rust String function | Equivalent Lean function | Description link |
2121
| ----------------------------- | ------------------- | ---------------------- |
2222
| core::str::bytes | UTF8Str.Str_toUTF8 | https://doc.rust-lang.org/std/primitive.str.html#method.bytes |
@@ -67,14 +67,16 @@ in Rust programs which use usize for String indexing when the Strings size are G
6767

6868

6969

70-
## Implemented functions in Lean library for List
70+
## Functions that already exist in Lean
7171
| Rust String function | Lean equivalent function | Description link |
7272
| ----------------------------- | ------------------- | ---------------------- |
7373
| core::str::chars | <em>self | https://doc.rust-lang.org/std/primitive.str.html#method.chars |
7474
| core::str::is_empty | List.isEmpty | https://doc.rust-lang.org/std/primitive.str.html#method.is_empty |
7575
| core::str::len | List.length | https://doc.rust-lang.org/std/primitive.str.html#method.len |
7676

77+
7778
## Limitations
79+
7880
The RustString library does not include:
7981
- Functions that mutate their input (e.g., `make_ascii_lowercase`), but it includes the cloning version (e.g. `to_ascii_lowercase`).
8082
- Functions which may panic (e.g., slice indexing), but it includes the non-panicking version (e.g. `str::get`)

0 commit comments

Comments
 (0)