Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,220 changes: 339 additions & 2,881 deletions tools/Cargo.lock

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions tools/hermes/src/Hermes.lean
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ class IsValid (α : Type) where
instance (priority := low) defaultIsValid {α : Type} : IsValid α where
isValid _ := True

instance [IsValid α] [IsValid β] : IsValid (α × β) where
isValid
| (a, b) => IsValid.isValid a ∧ IsValid.isValid b

instance [IsValid α] : IsValid (Option α) where
isValid
| none => True
| some a => IsValid.isValid a

-- A tactic that queries the environment for the `Hermes.allow_sorry` axiom.
-- If it exists, runs `sorry`. If not, fails with the provided error string.
elab "eval_allow_sorry_or_fail" err:term : tactic => do
Expand Down
3 changes: 3 additions & 0 deletions tools/hermes/tests/fixtures/option_is_valid/expected.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[External Error] generated/OptionIsValidOptionIsValid<HASH>/OptionIsValidOptionIsValid<HASH>.lean: could not synthesize default value for field 'h_ret_is_valid' of 'option_is_valid.invalid_option.Post' using tactics
[External Error] generated/OptionIsValidOptionIsValid<HASH>/OptionIsValidOptionIsValid<HASH>.lean: This error comes from the implicit `simp_all` proof for `h_ret_is_valid`. Lean cannot automatically prove that this value satisfies the `isValid` type invariant. Consider providing a manual proof via `proof (h_ret_is_valid)`.
Error: Lean verification failed
9 changes: 9 additions & 0 deletions tools/hermes/tests/fixtures/option_is_valid/hermes.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
description = """
Purpose: Verifies that `isValid` recurses through `Option`.
Behavior: An invalid `Some Positive` return value should fail verification.
"""

[test]
stderr_file = "expected.stderr"
args = ["verify", "--unsound-allow-is-valid"]
expected_status = "failure"
7 changes: 7 additions & 0 deletions tools/hermes/tests/fixtures/option_is_valid/source/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions tools/hermes/tests/fixtures/option_is_valid/source/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "option_is_valid"
version = "0.1.0"
edition = "2021"

[lib]
path = "src/lib.rs"

[workspace]
12 changes: 12 additions & 0 deletions tools/hermes/tests/fixtures/option_is_valid/source/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/// ```hermes
/// isValid self := self.x > 0
/// ```
pub struct Positive {
pub x: u32,
}

/// ```hermes
/// ```
pub fn invalid_option() -> Option<Positive> {
Some(Positive { x: 0 })
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
description = """
Purpose: Verifies that `isValid` recurses through `Option`.
Behavior: A valid `Some Positive` return value should verify successfully.
"""

[test]
args = ["verify", "--unsound-allow-is-valid"]
expected_status = "success"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "option_is_valid_success"
version = "0.1.0"
edition = "2021"

[lib]
path = "src/lib.rs"

[workspace]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/// ```hermes
/// isValid self := self.x > 0
/// ```
pub struct Positive {
pub x: u32,
}

/// ```hermes
/// proof (h_ret_is_valid):
/// have h_ret : some { x := 1#u32 } = ret := by
/// simpa [valid_option] using h_returns
/// rw [← h_ret]
/// simp [Hermes.IsValid.isValid]
/// decide
/// ```
pub fn valid_option() -> Option<Positive> {
Some(Positive { x: 1 })
}
3 changes: 3 additions & 0 deletions tools/hermes/tests/fixtures/product_is_valid/expected.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[External Error] generated/ProductIsValidProductIsValid<HASH>/ProductIsValidProductIsValid<HASH>.lean: could not synthesize default value for field 'h_ret_is_valid' of 'product_is_valid.invalid_pair.Post' using tactics
[External Error] generated/ProductIsValidProductIsValid<HASH>/ProductIsValidProductIsValid<HASH>.lean: This error comes from the implicit `simp_all` proof for `h_ret_is_valid`. Lean cannot automatically prove that this value satisfies the `isValid` type invariant. Consider providing a manual proof via `proof (h_ret_is_valid)`.
Error: Lean verification failed
9 changes: 9 additions & 0 deletions tools/hermes/tests/fixtures/product_is_valid/hermes.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
description = """
Purpose: Verifies that `isValid` recurses through Lean product types.
Behavior: An invalid `(Positive, u32)` return value should fail verification.
"""

[test]
stderr_file = "expected.stderr"
args = ["verify", "--unsound-allow-is-valid"]
expected_status = "failure"

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "product_is_valid"
version = "0.1.0"
edition = "2021"

[lib]
path = "src/lib.rs"

[workspace]
12 changes: 12 additions & 0 deletions tools/hermes/tests/fixtures/product_is_valid/source/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/// ```hermes
/// isValid self := self.x > 0
/// ```
pub struct Positive {
pub x: u32,
}

/// ```hermes
/// ```
pub fn invalid_pair() -> (Positive, u32) {
(Positive { x: 0 }, 0)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
description = """
Purpose: Verifies that `isValid` recurses through Lean product types.
Behavior: A valid `(Positive, u32)` return value should verify successfully.
"""

[test]
args = ["verify", "--unsound-allow-is-valid"]
expected_status = "success"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "product_is_valid_success"
version = "0.1.0"
edition = "2021"

[lib]
path = "src/lib.rs"

[workspace]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/// ```hermes
/// isValid self := self.x > 0
/// ```
pub struct Positive {
pub x: u32,
}

/// ```hermes
/// proof (h_ret_is_valid):
/// have h_ret : ({ x := 1#u32 }, 0#u32) = ret := by
/// simpa [valid_pair] using h_returns
/// rw [← h_ret]
/// simp [Hermes.IsValid.isValid]
/// decide
/// ```
pub fn valid_pair() -> (Positive, u32) {
(Positive { x: 1 }, 0)
}
Loading