Skip to content

Commit cba6196

Browse files
committed
[hermes] Add generate subcommand
gherrit-pr-id: Go47kyyj6ojyz5dbcvuuavbfyxdlpsdyb
1 parent ea22443 commit cba6196

File tree

8 files changed

+62
-5
lines changed

8 files changed

+62
-5
lines changed

hermes/docs/agent/07_workflow.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,7 @@ When writing a proof, follow these tips:
5151
You will use these two commands to interact with Hermes. Both accept `--help`.
5252

5353
1. Run `cargo run verify` to verify a target.
54-
2. Use `cargo run expand` to see the generated Lean code.
54+
2. Use `cargo run expand` to see the generated Lean code.
55+
3. Use `cargo run generate` to generate `.lean` files on the filesystem. You can use these to iterate on specifications and proofs using normal Lean tooling (`lake`, `lean`, etc) and copy results back to `.rs` files when you are done.
56+
57+
You will likely want to start with `cargo run generate`, then iterate on `.lean` files directly, and only use `cargo run verify` for final verification once you have copied your work from temporary `.lean` files back to the source of truth `.rs` files.

hermes/llms-full.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,10 @@ You will use these two commands to interact with Hermes. Both accept `--help`.
786786

787787
1. Run `cargo run verify` to verify a target.
788788
2. Use `cargo run expand` to see the generated Lean code.
789+
3. Use `cargo run generate` to generate `.lean` files on the filesystem. You can use these to iterate on specifications and proofs using normal Lean tooling (`lake`, `lean`, etc) and copy results back to `.rs` files when you are done.
790+
791+
You will likely want to start with `cargo run generate`, then iterate on `.lean` files directly, and only use `cargo run verify` for final verification once you have copied your work from temporary `.lean` files back to the source of truth `.rs` files.
792+
789793

790794
<!-- File: src/Hermes.lean -->
791795

hermes/src/aeneas.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,12 @@ open Lake DSL
298298
299299
package hermes_verification
300300
301+
@[default_target]
301302
lean_lib «Generated» where
302303
srcDir := "generated"
303304
roots := #[{roots_str}]
304305
306+
@[default_target]
305307
lean_lib «Hermes» where
306308
srcDir := "hermes"
307309
roots := #[`Config, `Hermes]
@@ -343,9 +345,8 @@ lean_lib «User» where
343345
Ok(())
344346
}
345347

346-
/// Completes Lean verification by generating Hermes `Specs.lean`, writing `Generated.lean`,
347-
/// and running `lake build` + diagnostics.
348-
pub fn verify_lean_workspace(roots: &LockedRoots, artifacts: &[HermesArtifact]) -> Result<()> {
348+
/// Generates Hermes `Specs.lean` and writes `Generated.lean`, but does not run the `lake build`.
349+
pub fn generate_lean_workspace(roots: &LockedRoots, artifacts: &[HermesArtifact]) -> Result<()> {
349350
let lean_generated_root = roots.lean_generated_root();
350351
let mut generated_imports = String::new();
351352

@@ -386,6 +387,13 @@ pub fn verify_lean_workspace(roots: &LockedRoots, artifacts: &[HermesArtifact])
386387
write_if_changed(&lean_generated_root.join("Generated.lean"), &generated_imports)
387388
.context("Failed to write Generated.lean")?;
388389

390+
Ok(())
391+
}
392+
393+
/// Completes Lean verification by generating Hermes `Specs.lean`, writing `Generated.lean`,
394+
/// and running `lake build` + diagnostics.
395+
pub fn verify_lean_workspace(roots: &LockedRoots, artifacts: &[HermesArtifact]) -> Result<()> {
396+
generate_lean_workspace(roots, artifacts)?;
389397
run_lake(roots, artifacts)
390398
}
391399

@@ -627,7 +635,14 @@ fn run_lake(roots: &LockedRoots, artifacts: &[HermesArtifact]) -> Result<()> {
627635
}
628636

629637
if has_errors {
630-
bail!("Lean verification failed");
638+
let cmd = if std::env::var("__ZEROCOPY_LOCAL_DEV").is_ok() {
639+
"cargo run generate"
640+
} else {
641+
"cargo hermes generate"
642+
};
643+
bail!(
644+
"Lean verification failed. Consider running `{cmd}`, iterating on generated `.lean` files, and copying results back to `.rs` files."
645+
);
631646
}
632647

633648
Ok(())

hermes/src/main.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ enum Commands {
2929
Setup(resolve::SetupArgs),
3030
/// Expand a crate's Lean output
3131
Expand(ExpandArgs),
32+
/// Generate Lean workspace and print paths without building
33+
Generate(resolve::Args),
3234
#[command(hide = true)]
3335
ToolchainPath,
3436
}
@@ -73,6 +75,18 @@ fn main() -> anyhow::Result<()> {
7375
aeneas::verify_lean_workspace(locked_roots, packages)
7476
})?;
7577
}
78+
Commands::Generate(resolve_args) => {
79+
prepare_and_run(&resolve_args, |locked_roots, packages| {
80+
aeneas::generate_lean_workspace(locked_roots, packages)?;
81+
let lean_root = locked_roots.lean_root();
82+
println!("Lean workspace generated at: {}", lean_root.display());
83+
println!();
84+
println!("To manually build and experiment:");
85+
println!(" 1. cd {}", lean_root.display());
86+
println!(" 2. lake build");
87+
Ok(())
88+
})?;
89+
}
7690
Commands::Setup(resolve::SetupArgs {}) => {
7791
setup::run_setup()?;
7892
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Lean workspace generated at: [PROJECT_ROOT]/target/hermes/hermes_test_target/lean
2+
3+
To manually build and experiment:
4+
1. cd [PROJECT_ROOT]/target/hermes/hermes_test_target/lean
5+
2. lake build
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
description = "Test the `generate` subcommand"
2+
3+
[[test.phases]]
4+
name = "Generate"
5+
args = ["generate", "--allow-sorry"]
6+
expected_status = "success"
7+
stdout_file = "expected-generate.stdout"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "expand_output"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[workspace]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// ```lean, hermes
2+
/// ```
3+
pub fn foo() {}

0 commit comments

Comments
 (0)