Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
139 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
747ba38
verify: Say that archives keep a logical function's measures and wher…
SwayamInSync Oct 23, 2026
d4592ba
verify: Validate a logical function's termination measures like its d…
SwayamInSync Oct 23, 2026
2ce8c54
verify: Keep the functions a termination measure applies when canonic…
SwayamInSync Oct 23, 2026
6a7d0a6
verify: Make obligation archives schema 3.
SwayamInSync Oct 23, 2026
d67c76f
verify: Archive termination measures and where each assumption of a g…
SwayamInSync Oct 23, 2026
4196eef
verify: Mark the unwinding goals of a Lean project.
SwayamInSync Oct 23, 2026
760896f
verify: State the bound of a bounded module with its Lean goals.
SwayamInSync Oct 23, 2026
ee37f71
verify: Declare the replay of archived modules into a Lean project.
SwayamInSync Oct 23, 2026
818ce9a
verify: Write Lean projects through one LeanProject, from source or f…
SwayamInSync Oct 23, 2026
4c0bc6a
verify: Replay archives into Lean projects, and bounded archives into…
SwayamInSync Oct 23, 2026
93f2c2c
test: Read schema 3 archives, and write schema 2 ones, in the archive…
SwayamInSync Oct 23, 2026
c474886
test: Expect schema 3, read schema 2, and reject a measure with a fre…
SwayamInSync Oct 23, 2026
f799055
test: Expect schema 3 in the obligation IR dump.
SwayamInSync Oct 23, 2026
b6e2857
test: Add the program of the Lean replay test.
SwayamInSync Oct 23, 2026
b5b3b06
test: Add the loops of the Lean replay test.
SwayamInSync Oct 23, 2026
7df524a
test: Check that an archive replays into a Lean project as its source…
SwayamInSync Oct 23, 2026
b255c43
docs: Explain archives in Lean projects in chapter 17.
SwayamInSync Oct 23, 2026
8ce4ce2
docs: Say how an archive replays into a Lean project.
SwayamInSync Oct 23, 2026
cdeb7df
docs: Note Lean projects from archives and schema 3 in the release no…
SwayamInSync Oct 23, 2026
76270a9
docs: Describe Lean replay and schema 3 in the design.
SwayamInSync Oct 23, 2026
cb86df1
docs: Describe LeanProject, Lean replay, and schema 3 in the architec…
SwayamInSync Oct 23, 2026
87dc023
docs: Say that archives keep where each assumption of a goal comes fr…
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
721 changes: 651 additions & 70 deletions clang/lib/Verify/Backend/LeanBackend.cpp

Large diffs are not rendered by default.

58 changes: 45 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 @@ -33,26 +35,55 @@ struct LeanProjectGoal {
/// False for an obligation of an exported function that a selection left
/// to the solver: its goal is known, but has no definition or proof file.
bool Exported = true;
/// An unwinding goal of a bounded module: that its loops end within the
/// bound.
bool Unwinding = false;
};

/// 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 +95,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
20 changes: 20 additions & 0 deletions clang/lib/Verify/Backend/Obligation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2578,6 +2578,26 @@ verify::validateObligationModule(const ObligationModule &M) {
ValidationError.c_str());
collectRequiredFeatures(Definition.get(), RequiredFeatures);
}
// A measure only chooses an induction or Lean's termination argument,
// so it adds no feature; it must still be an integer over the
// parameters.
for (const auto &Measure : Declaration.Decreases) {
if (!validateLogicExpr(Measure.get(), ValidationError))
return llvm::createStringError(llvm::inconvertibleErrorCode(), "%s",
ValidationError.c_str());
if (Measure->Sort.Kind != LogicSortKind::MathematicalInteger &&
Measure->Sort.Kind != LogicSortKind::BitVector)
return llvm::createStringError(
llvm::inconvertibleErrorCode(),
"logical function termination measure is not an integer");
if (!validateLogicCalls(Measure.get(), M.LogicFunctions,
ValidationError) ||
!validateVariableScopes(Measure.get(), ValidationError) ||
!validateDefinitionVariables(Measure.get(), Parameters, {},
ValidationError))
return llvm::createStringError(llvm::inconvertibleErrorCode(), "%s",
ValidationError.c_str());
}
}
return RequiredFeatures;
}
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/Verify/Backend/Obligation.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ class LogicExpr : public llvm::ThreadSafeRefCountedBase<LogicExpr> {
std::vector<LogicExprRef> Patterns;
/// For an Or that states one assumption of a goal (`!A || rest`): where A
/// comes from (`pre`, `call:f`, `def:x_1`), so a goal can be shown as
/// named hypotheses. Outside the term's meaning, identity, and archives.
/// named hypotheses. Outside the term's meaning and identity; archives
/// keep it with their source metadata.
std::string Premise;

explicit LogicExpr(Kind K) : K(K) {}
Expand Down Expand Up @@ -355,7 +356,8 @@ struct LogicFunctionDecl {
/// value; a verdict that does rests on them. Not archived.
std::vector<std::unique_ptr<LogicExpr>> Postconditions;
/// A recursive function's termination measure over the parameters, by
/// which an induction over its applications descends. Not archived.
/// which an induction over its applications descends and Lean proves its
/// definition terminates. Archived, never hashed.
std::vector<std::unique_ptr<LogicExpr>> Decreases;
static constexpr const char *ResultVariable = "cppverify.result";
};
Expand Down
30 changes: 25 additions & 5 deletions clang/lib/Verify/Backend/ObligationSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,17 +501,24 @@ class ArchiveWriter {
writeU8(collectionTag(Expr->CollectionOp));
writeString(Expr->SpecCallee);
writeSource(Expr->Source);
// Where an assumption comes from names its hypothesis in a readable
// Lean goal, as source points name a diagnostic's place.
if (IncludeSource && Expr->K == LogicExpr::Or)
writeString(Expr->Premise);
writeU64(Expr->Children.size());
for (const auto &Child : Expr->Children)
writeExpr(Child.get());
}

// A record keeps what a hash leaves out: the display name, and the
// termination measures, which change no meaning (Lean checks termination
// itself, and an induction descends by a well-founded relation whatever
// the measure).
void writeFunction(const std::string &MapIdentity,
const LogicFunctionDecl &Function,
bool IncludeDisplayName) {
const LogicFunctionDecl &Function, bool Archived) {
writeString(MapIdentity);
writeString(Function.Identity);
writeString(IncludeDisplayName ? Function.DisplayName : "");
writeString(Archived ? Function.DisplayName : "");
writeU64(Function.Parameters.size());
for (const LogicFunctionParameter &Parameter : Function.Parameters) {
writeString(Parameter.Name);
Expand All @@ -523,6 +530,11 @@ class ArchiveWriter {
writeU64(Function.DefinitionLevels.size());
for (const auto &Definition : Function.DefinitionLevels)
writeExpr(Definition.get());
if (!Archived)
return;
writeU64(Function.Decreases.size());
for (const auto &Measure : Function.Decreases)
writeExpr(Measure.get());
}

void writeFunctionSignature(const std::string &MapIdentity,
Expand All @@ -536,10 +548,10 @@ class ArchiveWriter {
}

void writeFunctions(const std::map<std::string, LogicFunctionDecl> &Functions,
bool IncludeDisplayNames) {
bool Archived) {
writeU64(Functions.size());
for (const auto &[Identity, Function] : Functions)
writeFunction(Identity, Function, IncludeDisplayNames);
writeFunction(Identity, Function, Archived);
}

void writeModule(const ObligationModule &Module,
Expand Down Expand Up @@ -804,6 +816,8 @@ class ArchiveReader {
}
Expr->SpecCallee = readString();
Expr->Source = readSource(IncludeSource);
if (Version >= 3 && IncludeSource && Expr->K == LogicExpr::Or)
Expr->Premise = readString();

uint64_t Children = readCount();
if (!Failure.empty())
Expand Down Expand Up @@ -839,6 +853,12 @@ class ArchiveReader {
Function.DefinitionLevels.reserve(Levels);
for (uint64_t I = 0; I != Levels && Failure.empty(); ++I)
Function.DefinitionLevels.push_back(readExpr());
if (Version >= 3) {
uint64_t Measures = readCount();
Function.Decreases.reserve(Measures);
for (uint64_t I = 0; I != Measures && Failure.empty(); ++I)
Function.Decreases.push_back(readExpr());
}
return Function;
}

Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Verify/Backend/ObligationSerialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
namespace clang {
namespace verify {

inline constexpr uint32_t ObligationSerializationVersion = 2;
/// Version 2 adds the precise obligation kinds; version 3 each logical
/// function's termination measures and, with source metadata, where each
/// assumption of a goal comes from. Readers read every earlier version.
inline constexpr uint32_t ObligationSerializationVersion = 3;
inline constexpr uint32_t ObligationSemanticHashVersion = 4;

/// Serialize one module as a deterministic, versioned binary record. Records
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Verify/Backend/ObligationSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,10 +363,14 @@ void simplifyFunctions(ObligationModule &Module,
auto Function = Module.LogicFunctions.find(Pending[I]);
if (Function == Module.LogicFunctions.end())
continue;
// A function's declaration depends on what its definition and its
// measures apply.
std::set<std::string> Dependencies;
collectCalledFunctions(Function->second.StepDefinition.get(), Dependencies);
for (const auto &Definition : Function->second.DefinitionLevels)
collectCalledFunctions(Definition.get(), Dependencies);
for (const auto &Measure : Function->second.Decreases)
collectCalledFunctions(Measure.get(), Dependencies);
for (const std::string &Dependency : Dependencies)
if (Reachable.insert(Dependency).second)
Pending.push_back(Dependency);
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
Loading
Loading