Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
128a6cb
verify: Replay a Lean project into one kernel environment, importing …
SwayamInSync Oct 23, 2026
62cac8d
test: Add a program whose first goal sorts before the other function'…
SwayamInSync Oct 23, 2026
9d85f6e
test: Add a proof of the first goal that defines a goal of its own un…
SwayamInSync Oct 23, 2026
fe6fc92
test: Expect a proof file that redeclares its goal to be the module l…
SwayamInSync Oct 23, 2026
f716cd7
test: Add a wrapper that bounds the peak memory of the processes a co…
SwayamInSync Oct 23, 2026
a9098e0
test: Bound the Lean checker's memory where a proof imports Lean thro…
SwayamInSync Oct 23, 2026
f814f9f
docs: Say that certification imports the toolchain once and rejects a…
SwayamInSync Oct 23, 2026
ed50d74
docs: Say in the release notes that the checker replays into one envi…
SwayamInSync Oct 23, 2026
e918963
docs: Describe the checker's single kernel environment in the design.
SwayamInSync Oct 23, 2026
c55de5b
docs: Describe the checker's single kernel environment and its memory…
SwayamInSync Oct 23, 2026
51a9a6a
verify: Declare a Lean project's generated modules and the prelude's …
SwayamInSync Oct 23, 2026
34ef6d0
verify: Emit a project's spec declarations apart from its goals, and …
SwayamInSync Oct 23, 2026
cdcaec5
verify: Let the Lean backend write the modules of a project.
SwayamInSync Oct 23, 2026
505cf15
verify: Write each function's Lean goals to its module and the specs …
SwayamInSync Oct 23, 2026
86e4a9d
verify: Import only the prelude in the module of cppverify_auto.
SwayamInSync Oct 23, 2026
c23e58c
verify: Check each goal against its own module, and fail every goal w…
SwayamInSync Oct 23, 2026
2ef7e14
verify: Give each function's Lean goals a module, and compile a proof…
SwayamInSync Oct 23, 2026
da1845a
test: Add a helper that prints a Lean project's generated text in imp…
SwayamInSync Oct 23, 2026
548094c
test: Read a Lean project's goals from its modules in the fidelity gate.
SwayamInSync Oct 23, 2026
2c9de79
test: Add the five functions of the Lean modules test.
SwayamInSync Oct 23, 2026
28af37d
test: Add the proof of tri_zero's postcondition for the Lean modules …
SwayamInSync Oct 23, 2026
901c3ca
test: Add the proof of plus_tri_zero's postcondition for the Lean mod…
SwayamInSync Oct 23, 2026
adf19a3
test: Check the module of each function's Lean goals and incremental …
SwayamInSync Oct 23, 2026
0350c69
test: Expect the goal module among the imports of an automatic proof.
SwayamInSync Oct 23, 2026
56a9fb0
test: Expect the goal module in the message for a shadowed goal.
SwayamInSync Oct 23, 2026
9f9fbb2
test: Expect an admitted User lemma to fail every goal through the ch…
SwayamInSync Oct 23, 2026
e261a4d
test: Read the fallback project's generated text from its modules.
SwayamInSync Oct 23, 2026
4cbeefd
test: Find spec bodies in their goal module and the goal module in a …
SwayamInSync Oct 23, 2026
accb2c9
test: Read the Lean projects' generated text from their modules.
SwayamInSync Oct 23, 2026
66be53e
test: Read the Lean project's generated text from its modules.
SwayamInSync Oct 23, 2026
97f3776
test: Read and edit the readable goals in their function's module.
SwayamInSync Oct 23, 2026
6ae6209
test: Read the exported Lean semantics from the project's modules.
SwayamInSync Oct 23, 2026
7e119a1
test: Expect the trial of cppverify_auto to build the goal modules too.
SwayamInSync Oct 23, 2026
71ce0e1
docs: Explain the module of each function's Lean goals and incrementa…
SwayamInSync Oct 23, 2026
e406b75
docs: Describe the modules of a Lean project in the tooling reference.
SwayamInSync Oct 23, 2026
0c43c5c
docs: Note the Lean module per function in the release notes.
SwayamInSync Oct 23, 2026
f2558ec
docs: Describe a Lean project's modules in the design.
SwayamInSync Oct 23, 2026
a989960
docs: Describe a Lean project's modules and proof keys in the archite…
SwayamInSync Oct 23, 2026
f178db1
test: Import its function's goal module in the proof cppverify_fine_5…
SwayamInSync Oct 23, 2026
b138c4b
test: Import its function's goal module in the proof cppverify_fine_5…
SwayamInSync Oct 23, 2026
1bf5460
test: Import its function's goal module in the proof cppverify_one_99…
SwayamInSync Oct 23, 2026
77bdebb
test: Import its function's goal module in the proof cppverify_one_99…
SwayamInSync Oct 23, 2026
e0d4296
test: Import its function's goal module in the proof Lemmas.lean.
SwayamInSync Oct 23, 2026
98d82b0
test: Import its function's goal module in the proof cppverify_one_99…
SwayamInSync Oct 23, 2026
71886e0
test: Import its function's goal module in the proof cppverify_one_99…
SwayamInSync Oct 23, 2026
aaf0ec7
test: Import its function's goal module in the proof lean_dependencie…
SwayamInSync Oct 23, 2026
910acbe
test: Import its function's goal module in the proof lean_dependencie…
SwayamInSync Oct 23, 2026
69d1177
test: Import its function's goal module in the proof lean_dependencie…
SwayamInSync Oct 23, 2026
6ce1435
test: Import its function's goal module in the proof lean_dependencie…
SwayamInSync Oct 23, 2026
d69832d
test: Import its function's goal module in the proof lean_dependencie…
SwayamInSync Oct 23, 2026
1d6af47
test: Import its function's goal module in the proof lean_dependencie…
SwayamInSync Oct 23, 2026
fad7045
test: Import its function's goal module in the proof lean_dependencie…
SwayamInSync Oct 23, 2026
49a0e1f
test: Import its function's goal module in the proof lean_dependencie…
SwayamInSync Oct 23, 2026
23e010b
test: Import its function's goal module in the proof lean_fallback_go…
SwayamInSync Oct 23, 2026
64c6570
test: Import its function's goal module in the proof lean_fallback_go…
SwayamInSync Oct 23, 2026
cc18009
test: Import its function's goal module in the proof lean_fallback_go…
SwayamInSync Oct 23, 2026
ce46518
test: Import its function's goal module in the proof lean_fallback_go…
SwayamInSync Oct 23, 2026
8d1523b
test: Import its function's goal module in the proof lean_fallback_pa…
SwayamInSync Oct 23, 2026
df33419
test: Import its function's goal module in the proof lean_fallback_pa…
SwayamInSync Oct 23, 2026
2f1a006
test: Import its function's goal module in the proof cppverify_bump_c…
SwayamInSync Oct 23, 2026
5daf121
test: Import its function's goal module in the proof cppverify_one_99…
SwayamInSync Oct 23, 2026
16a8c93
test: Import its function's goal module in the proof cppverify_one_99…
SwayamInSync Oct 23, 2026
6be02b0
test: Import its function's goal module in the proof cppverify_one_99…
SwayamInSync Oct 23, 2026
ca6c465
test: Import its function's goal module in the proof cppverify_one_99…
SwayamInSync Oct 23, 2026
7b861cb
test: Import its function's goal module in the proof cppverify_six_6a…
SwayamInSync Oct 23, 2026
5eedfdf
test: Import its function's goal module in the proof cppverify_six_6a…
SwayamInSync Oct 23, 2026
c318e4c
test: Import its function's goal module in the proof cppverify_tri_de…
SwayamInSync Oct 23, 2026
201ea08
test: Import its function's goal module in the proof cppverify_twice_…
SwayamInSync Oct 23, 2026
9bacf87
test: Import its function's goal module in the proof cppverify_twice_…
SwayamInSync Oct 23, 2026
451f38f
test: Import its function's goal module in the proof cppverify_twice_…
SwayamInSync Oct 23, 2026
05003b5
test: Import its function's goal module in the proof cppverify_twice_…
SwayamInSync Oct 23, 2026
93b75ad
test: Import its function's goal module in the proof lean_semantics_c…
SwayamInSync Oct 23, 2026
d49e8f9
test: Import its function's goal module in the proof lean_semantics_m…
SwayamInSync Oct 23, 2026
1136d88
test: Import its function's goal module in the proof lean_semantics_n…
SwayamInSync Oct 23, 2026
9359c25
test: Import its function's goal module in the proof cppverify_readin…
SwayamInSync Oct 23, 2026
cf3fc2c
test: Import its function's goal module in the proof cppverify_readin…
SwayamInSync Oct 23, 2026
1e8a0a1
test: Import its function's goal module in the proof cppverify_readin…
SwayamInSync Oct 23, 2026
4eb310f
test: Import its function's goal module in the proof cppverify_readin…
SwayamInSync Oct 23, 2026
9b346cc
test: Import its function's goal module in the proof cppverify_readin…
SwayamInSync Oct 23, 2026
04706a9
test: Import its function's goal module in the proof cppverify_sensor…
SwayamInSync Oct 23, 2026
5683c25
verify: Let the Lean backend export goals over spec collections.
SwayamInSync Oct 23, 2026
d5c8a51
verify: State the spec collections in Lean with core types, prelude o…
SwayamInSync Oct 23, 2026
91bcccc
verify: Add machine equalities, collection extensionality, and spec u…
SwayamInSync Oct 23, 2026
dc6e821
test: Check that Lean evaluates every collection operation as the cer…
SwayamInSync Oct 23, 2026
e6287c9
test: Add the functions over each spec collection of the Lean collect…
SwayamInSync Oct 23, 2026
6dac71e
test: Add a proof by hand over a sequence for the Lean collections test.
SwayamInSync Oct 23, 2026
ce1c27c
test: Check the export, automation, and certification of goals over s…
SwayamInSync Oct 23, 2026
5a1bcfc
test: Expect revision 2 of cppverify_auto in the proof headers.
SwayamInSync Oct 23, 2026
fb9d7ee
test: Expect cppverify_auto to prove the goals over tri, and the proo…
SwayamInSync Oct 23, 2026
106cd5e
test: Say that the proofs over tri are also written by hand.
SwayamInSync Oct 23, 2026
511d17d
test: Expect cppverify_auto to certify fibo_step, and fibo_six to nee…
SwayamInSync Oct 23, 2026
1bbf954
docs: Explain collections in Lean and revision 2 of cppverify_auto in…
SwayamInSync Oct 23, 2026
98dfdd9
docs: Say in chapter 13 that a Lean project states the spec collections.
SwayamInSync Oct 23, 2026
20b4f96
docs: Drop the limitation that Lean lacks the spec collections.
SwayamInSync Oct 23, 2026
64bc948
docs: Show revision 2 of cppverify_auto in the tooling reference.
SwayamInSync Oct 23, 2026
5cc1e02
docs: Note collections in Lean and revision 2 of cppverify_auto in th…
SwayamInSync Oct 23, 2026
0d71ea4
docs: Describe the spec collections in Lean and the new automation st…
SwayamInSync Oct 23, 2026
a734035
docs: Describe the Lean collection prelude and revision 2 of cppverif…
SwayamInSync Oct 23, 2026
79094d8
verify: Declare a project's spec functions with their opaque declarat…
SwayamInSync Oct 23, 2026
f8701ea
verify: Print a spec's step definition for Lean, its conditions as hy…
SwayamInSync Oct 23, 2026
0f293cc
verify: Collect a project's spec functions by identity.
SwayamInSync Oct 23, 2026
842d4b1
verify: Define the spec functions that Lean proves terminating, and k…
SwayamInSync Oct 23, 2026
cc0fc2e
verify: Evaluate spec definitions by their equations and read C++ div…
SwayamInSync Oct 23, 2026
53c7ab5
test: Add the spec functions of the Lean spec definitions test.
SwayamInSync Oct 23, 2026
bc2d146
test: Add a proof by induction over tri for the Lean spec definitions…
SwayamInSync Oct 23, 2026
0a8d6e4
test: Check which spec functions become Lean definitions, and a proof…
SwayamInSync Oct 23, 2026
d690092
test: Add contracts that divide by constants for the Lean division test.
SwayamInSync Oct 23, 2026
30de5c8
test: Check that cppverify_auto proves contracts that divide by const…
SwayamInSync Oct 23, 2026
9f78611
test: Expect tri as a definition in the project's Specs module.
SwayamInSync Oct 23, 2026
5adb8f9
test: Expect total and members as definitions, and revision 3 of cppv…
SwayamInSync Oct 23, 2026
dc2f5d8
test: Expect revision 3 of cppverify_auto in the proof headers.
SwayamInSync Oct 23, 2026
b284bcc
test: Run the fallback test without cppverify_auto, so that its goals…
SwayamInSync Oct 23, 2026
2cdcfea
docs: Explain spec functions as Lean definitions in chapter 17.
SwayamInSync Oct 23, 2026
02d6e5b
docs: Say how a Lean project declares its spec functions.
SwayamInSync Oct 23, 2026
32486bc
docs: Note spec functions as Lean definitions in the release notes.
SwayamInSync Oct 23, 2026
8c79068
docs: Describe spec functions as Lean definitions in the design.
SwayamInSync Oct 23, 2026
50740fe
docs: Describe the spec definitions, their trial, and revision 3 of c…
SwayamInSync Oct 23, 2026
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
712 changes: 643 additions & 69 deletions clang/lib/Verify/Backend/LeanBackend.cpp

Large diffs are not rendered by default.

55 changes: 42 additions & 13 deletions clang/lib/Verify/Backend/LeanBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

#include "VerifyBackend.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <optional>
#include <set>
#include <string>
#include <vector>

namespace clang {
Expand Down Expand Up @@ -38,21 +40,47 @@ struct LeanProjectGoal {
/// The group of a module's goals in a project: its function's directory.
std::string leanProjectGroup(const ObligationModule &Module);

/// A logical function of a Lean project: its opaque declaration and, when it
/// has a definition Lean may accept, that definition, recursion measured by
/// its termination measures, with the functions it applies.
struct LeanSpecDeclaration {
/// Its Lean constant.
std::string Name;
std::string Opaque;
std::string Definition;
std::set<std::string> Applies;
};

/// The generated modules of a Lean project: the specs its goals apply, by
/// identity, which every goal module imports, and each group's spec
/// definitions and goals.
struct LeanProjectModules {
std::map<std::string, LeanSpecDeclaration> Specs;
std::map<std::string, std::string> Goals;
/// The groups in the order their functions were exported: the source's.
std::vector<std::string> Order;
};

/// The definitions every exported goal is stated with.
void emitLeanPrelude(llvm::raw_ostream &OS, bool Project);

/// Selection names the internal IDs to export; a project goal is named by
/// its function and semantic hash, so it keeps its name whatever else is
/// exported, and a scratch-pad goal keeps the positional name it has when
/// every obligation is exported. A project records every goal of the module,
/// the ones left out as not exported.
VerifyResult
exportLeanScratchPad(const ObligationModule &Module, llvm::raw_ostream &OS,
bool EmitPreamble, std::set<std::string> &EmittedFunctions,
std::set<std::string> &EmittedTheorems,
unsigned ModuleIndex,
std::vector<LeanProjectGoal> *ProjectGoals,
const std::set<std::string> *Selection = nullptr);
/// the ones left out as not exported. Specs, when given, receives each spec
/// once, as its project declares it, instead of OS.
VerifyResult exportLeanScratchPad(
const ObligationModule &Module, llvm::raw_ostream &OS, bool EmitPreamble,
std::set<std::string> &EmittedFunctions,
std::set<std::string> &EmittedTheorems, unsigned ModuleIndex,
std::vector<LeanProjectGoal> *ProjectGoals,
const std::set<std::string> *Selection = nullptr,
std::map<std::string, LeanSpecDeclaration> *Specs = nullptr);

class LeanVerifyBackend : public VerifyBackend {
llvm::raw_ostream *Out;
llvm::raw_ostream *Out = nullptr;
LeanProjectModules *Modules = nullptr;
bool PreambleEmitted = false;
std::set<std::string> EmittedFunctions;
std::set<std::string> EmittedTheorems;
Expand All @@ -64,12 +92,13 @@ class LeanVerifyBackend : public VerifyBackend {
LeanVerifyBackend(llvm::raw_ostream *OS,
std::vector<LeanProjectGoal> *ProjectGoals)
: Out(OS), ProjectGoals(ProjectGoals) {}
/// A project's export, into its modules.
LeanVerifyBackend(LeanProjectModules *Modules,
std::vector<LeanProjectGoal> *ProjectGoals)
: Modules(Modules), ProjectGoals(ProjectGoals) {}
llvm::StringRef getName() const override { return "lean"; }
BackendCapabilities getCapabilities() const override {
// Collections have no Lean semantics yet.
return {allLogicFeatures() & ~logicFeature(LogicFeature::Sequences) &
~logicFeature(LogicFeature::Collections),
false};
return {allLogicFeatures(), false};
}
/// Restrict later exports to these internal obligation IDs.
void selectObligations(std::optional<std::set<std::string>> Ids) {
Expand Down
29 changes: 23 additions & 6 deletions clang/lib/Verify/Backend/VerifyBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,31 @@ using namespace verify;

VerifyResult LeanVerifyBackend::verifyModule(const ObligationModule &Module) {
VerifyResult R;
if (!Out) {
if (!Out && !Modules) {
R.Status = VerifyStatus::Unresolved;
R.Reason = VerifyReason::LeanExportFailure;
R.Message = "no lean output stream";
return R;
}
const size_t Before = ProjectGoals ? ProjectGoals->size() : 0;
VerifyResult Result = exportLeanScratchPad(
Module, *Out, !PreambleEmitted, EmittedFunctions, EmittedTheorems,
++ModuleIndex, ProjectGoals, Selection ? &*Selection : nullptr);
PreambleEmitted = true;
VerifyResult Result;
if (Modules) {
// A project's goals go to their function's module, and the specs they
// apply are declared once, in the module every goal module imports.
const std::string Group = leanProjectGroup(Module);
if (!Modules->Goals.count(Group))
Modules->Order.push_back(Group);
llvm::raw_string_ostream Goals(Modules->Goals[Group]);
Result = exportLeanScratchPad(
Module, Goals, /*EmitPreamble=*/false, EmittedFunctions,
EmittedTheorems, ++ModuleIndex, ProjectGoals,
Selection ? &*Selection : nullptr, &Modules->Specs);
} else {
Result = exportLeanScratchPad(
Module, *Out, !PreambleEmitted, EmittedFunctions, EmittedTheorems,
++ModuleIndex, ProjectGoals, Selection ? &*Selection : nullptr);
PreambleEmitted = true;
}
if (ProjectGoals)
for (size_t I = Before; I < ProjectGoals->size(); ++I)
if ((*ProjectGoals)[I].Exported)
Expand Down Expand Up @@ -754,11 +768,14 @@ std::unique_ptr<VerifyBackend>
verify::createVerifyBackend(BackendKind K, llvm::raw_ostream *LeanOut,
unsigned BMCUnroll,
const BackendExecutionOptions &Execution,
std::vector<LeanProjectGoal> *LeanProjectGoals) {
std::vector<LeanProjectGoal> *LeanProjectGoals,
LeanProjectModules *LeanModules) {
switch (K) {
case BackendKind::Z3:
return std::make_unique<Z3VerifyBackend>(Execution, "z3");
case BackendKind::Lean:
if (LeanModules)
return std::make_unique<LeanVerifyBackend>(LeanModules, LeanProjectGoals);
return std::make_unique<LeanVerifyBackend>(LeanOut, LeanProjectGoals);
case BackendKind::BMC:
return std::make_unique<BMCVerifyBackend>(BMCUnroll, Execution);
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Verify/Backend/VerifyBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,12 +307,14 @@ inline unsigned moduleTimeoutMs(const ObligationModule &Module,
}

struct LeanProjectGoal;
struct LeanProjectModules;

std::unique_ptr<VerifyBackend>
createVerifyBackend(BackendKind K, llvm::raw_ostream *LeanOut = nullptr,
unsigned BMCUnroll = 10,
const BackendExecutionOptions &Execution = {},
std::vector<LeanProjectGoal> *LeanProjectGoals = nullptr);
std::vector<LeanProjectGoal> *LeanProjectGoals = nullptr,
LeanProjectModules *LeanModules = nullptr);

VerifyResult
lowerObligationModule(const ObligationModule &Module,
Expand Down
110 changes: 105 additions & 5 deletions clang/lib/Verify/Driver/LeanAutomation.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,32 @@ namespace verify {

/// Names this module's tactics: a stub or automatic proof that an earlier
/// revision wrote is tried again.
inline constexpr llvm::StringLiteral LeanAutomationRevision = "1";
inline constexpr llvm::StringLiteral LeanAutomationRevision = "3";

/// The steps of cppverify_auto, each the whole proof of a goal it proves.
inline constexpr llvm::StringLiteral LeanAutomationSteps[] = {
"cppverify_auto_grind", "cppverify_auto_heap", "cppverify_auto_bv",
"cppverify_auto_decide", "cppverify_auto_simp"};
"cppverify_auto_grind", "cppverify_auto_heap", "cppverify_auto_bv",
"cppverify_auto_decide", "cppverify_auto_simp", "cppverify_auto_bveq",
"cppverify_auto_ext", "cppverify_auto_unfold", "cppverify_auto_eval",
"cppverify_auto_div"};

/// CppVerify/Auto.lean, written with every export. Its steps were chosen by
/// what proves the goals of the test suite (heap stores as the functions
/// they define, machine arithmetic as integers, then grind; stating toInt
/// ranges and removing Int.bmod first proved nothing more, the latter less),
/// each with a heartbeat budget of its own, as Vermilion's discharger ladder.
/// Revision 2 adds the last three, after the others, so that every goal an
/// earlier step proves keeps its proof: machine equalities and sign
/// extensions as integer facts, collection equality element by element, and
/// the definition instances a goal states, by the bodies they name.
/// Revision 3 adds the last two: the spec functions with Lean definitions
/// evaluated by their equations, and C++ division and remainder by their
/// definitions.
inline constexpr llvm::StringLiteral LeanAutomationSource =
R"lean(/- Generated by CppVerify: the tactics of its automatic proofs, which proof
files may use too. Regeneration replaces this file. -/
import Lean
import CppVerify.Generated
import CppVerify.Prelude

register_option cppverify.autoBudget : Nat := {
defValue := 50000
Expand Down Expand Up @@ -82,6 +91,51 @@ elab "cppverify_unfold_readable" : tactic => withMainContext do
let unfolded ← deltaExpand target (· == name)
replaceMainGoal [← (← getMainGoal).change unfolded]

open Lean Elab Tactic Meta in
/-- Unfolds the definitions of spec bodies that a goal and its hypotheses
name, so that each definition instance a goal states says what the body
does. A body names only lower levels of its definition, so this ends. -/
elab "cppverify_unfold_bodies" : tactic => withMainContext do
let isBody : Name → Bool := fun
| .str _ s => s.startsWith "cppSpecBody_"
| _ => false
let rec expand (e : Expr) : Nat → MetaM Expr
| 0 => return e
| fuel + 1 => do
let e' ← deltaExpand e isBody
if e' == e then return e else expand e' fuel
let mut goal ← getMainGoal
goal ← goal.change (← expand (← instantiateMVars (← goal.getType)) 64)
for d in ← goal.withContext getLCtx do
if d.isImplementationDetail then continue
let t ← instantiateMVars d.type
let t' ← expand t 64
if t' != t then
goal ← goal.changeLocalDecl d.fvarId t'
replaceMainGoal [goal]

open Lean Elab Tactic Meta in
/-- Rewrites with the equations of every spec function that Specs.lean
defines, and C++ division and remainder, so that applications at known
arguments become values. On unknown arguments it unfolds until its budget
is spent. -/
elab "cppverify_eval_specs" : tactic => withMainContext do
let env ← getEnv
let mut lemmas : Array (TSyntax `Lean.Parser.Tactic.simpLemma) := #[]
let some idx := env.getModuleIdx? `CppVerify.Specs
| throwError "no spec function has a Lean definition"
let some data := env.header.moduleData[idx.toNat]?
| throwError "no spec function has a Lean definition"
for name in data.constNames do
if let .str .anonymous s := name then
if s.startsWith "cppSpec_" then
if let some (.defnInfo _) := env.find? name then
lemmas := lemmas.push
(← `(Lean.Parser.Tactic.simpLemma| $(mkIdent name):ident))
if lemmas.isEmpty then
throwError "no spec function has a Lean definition"
evalTactic (← `(tactic| simp [$lemmas,*, cppIntDiv, cppIntRem]))

/-- Machine comparisons, constants, and overflow conditions as facts about
integers. -/
macro "cppverify_norm" : tactic => `(tactic| (try simp only [cppBvSlt, cppBvSle,
Expand Down Expand Up @@ -118,6 +172,47 @@ macro "cppverify_auto_decide" : tactic =>
macro "cppverify_auto_simp" : tactic =>
`(tactic| (cppverify_unfold_readable; simp_all))

/-- Machine equalities, as of `x ≠ y` for distinct keys, and sign extensions
as facts about integers. -/
macro "cppverify_bveq" : tactic => `(tactic| (try simp (disch := omega) only
[ne_eq, ← BitVec.toInt_inj, BitVec.toInt_signExtend_of_le] at *))
macro "cppverify_auto_bveq" : tactic => `(tactic| (
cppverify_unfold_readable
intros
cppverify_bveq
cppverify_norm
all_goals grind))
/-- Two collections are equal when they agree at every element: equal
lengths and reads for sequences, membership for sets, counts for
multisets, and keys and values for maps. -/
macro "cppverify_auto_ext" : tactic => `(tactic| (
cppverify_unfold_readable
intros
(first | apply cppSeq_ext | apply cppSet_ext | apply cppMultiset_ext
| apply cppMap_ext)
all_goals (intros; cppverify_norm; all_goals grind)))
macro "cppverify_auto_unfold" : tactic => `(tactic| (
cppverify_unfold_readable
intros
cppverify_unfold_bodies
cppverify_bveq
cppverify_norm
all_goals grind))
macro "cppverify_auto_eval" : tactic => `(tactic| (
cppverify_unfold_readable
intros
cppverify_bveq
cppverify_eval_specs
all_goals grind))
/-- C++ division and remainder by their definitions, which grind reads by
constant divisors once the signs are split. -/
macro "cppverify_auto_div" : tactic => `(tactic| (
cppverify_unfold_readable
intros
cppverify_bveq
cppverify_norm
all_goals grind [cppIntDiv, cppIntRem]))

open Lean Elab Tactic in
/-- Tries each step on the goal, each with `cppverify.autoBudget` heartbeats
of its own, and keeps the first that proves it. A step that runs out of
Expand All @@ -132,7 +227,12 @@ elab "cppverify_auto" : tactic => do
("cppverify_auto_heap", ← `(tactic| cppverify_auto_heap)),
("cppverify_auto_bv", ← `(tactic| cppverify_auto_bv)),
("cppverify_auto_decide", ← `(tactic| cppverify_auto_decide)),
("cppverify_auto_simp", ← `(tactic| cppverify_auto_simp))]
("cppverify_auto_simp", ← `(tactic| cppverify_auto_simp)),
("cppverify_auto_bveq", ← `(tactic| cppverify_auto_bveq)),
("cppverify_auto_ext", ← `(tactic| cppverify_auto_ext)),
("cppverify_auto_unfold", ← `(tactic| cppverify_auto_unfold)),
("cppverify_auto_eval", ← `(tactic| cppverify_auto_eval)),
("cppverify_auto_div", ← `(tactic| cppverify_auto_div))]
for (name, step) in steps do
let attempt : TacticM Unit := do
let heartbeats ← IO.getNumHeartbeats
Expand Down
Loading
Loading