Skip to content

Commit 79677a5

Browse files
Print print intermediate configurations after some function events in kore-proof-trace (#1139)
This PR introduces a new feature to `kore-proof-trace` to build a configuration with the contents of a top-level function before its evaluation. Due to the new way that function arguments are evaluated and printed in the trace before the actual function, I talked with Mircea, and we decided that printing the top-level function with the evaluated arguments would be better than printing all the nested non-evaluated functions.
1 parent 5ecfcc0 commit 79677a5

39 files changed

+44775
-17
lines changed

bindings/python/ast.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ void bind_proof_trace(py::module_ &m) {
454454
[](py::bytes const &bytes, kore_header const &header) {
455455
proof_trace_parser parser(false, false, header);
456456
auto str = std::string(bytes);
457-
return parser.parse_proof_trace(str);
457+
return parser.parse_proof_trace(str, false);
458458
},
459459
py::arg("bytes"), py::arg("header"));
460460

include/kllvm/binary/ProofTraceParser.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,9 @@ class llvm_rewrite_trace {
314314
}
315315
void add_trace_event(llvm_event const &event) { trace_.push_back(event); }
316316

317-
void print(std::ostream &out, bool expand_terms, unsigned indent = 0U) const;
317+
void print(
318+
std::ostream &out, bool expand_terms, unsigned indent = 0U,
319+
bool intermediate_configs = false) const;
318320
};
319321

320322
class proof_trace_parser {
@@ -686,9 +688,10 @@ class proof_trace_parser {
686688
bool verbose, bool expand_terms, kore_header const &header,
687689
std::optional<kore_definition> kore_definition = std::nullopt);
688690

691+
std::optional<llvm_rewrite_trace> parse_proof_trace_from_file(
692+
std::string const &filename, bool intermediate_configs);
689693
std::optional<llvm_rewrite_trace>
690-
parse_proof_trace_from_file(std::string const &filename);
691-
std::optional<llvm_rewrite_trace> parse_proof_trace(std::string const &data);
694+
parse_proof_trace(std::string const &data, bool intermediate_configs);
692695

693696
friend class llvm_rewrite_trace_iterator;
694697
};
@@ -699,13 +702,16 @@ class llvm_rewrite_trace_iterator {
699702
std::unique_ptr<proof_trace_buffer> buffer_;
700703
llvm_event_type type_ = llvm_event_type::PreTrace;
701704
proof_trace_parser parser_;
705+
std::shared_ptr<kore_composite_pattern> current_config_;
702706

703707
public:
704708
llvm_rewrite_trace_iterator(
705709
std::unique_ptr<proof_trace_buffer> buffer, kore_header const &header);
706710
[[nodiscard]] uint32_t get_version() const { return version_; }
707711
std::optional<annotated_llvm_event> get_next_event();
708-
void print(std::ostream &out, bool expand_terms, unsigned indent = 0U);
712+
void print(
713+
std::ostream &out, bool expand_terms, unsigned indent = 0U,
714+
bool intermediate_configs = false);
709715
};
710716

711717
} // namespace kllvm
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef KLLVM_PROOF_TRACE_UTILS_CPP
2+
#define KLLVM_PROOF_TRACE_UTILS_CPP
3+
4+
#include <kllvm/ast/AST.h>
5+
#include <kllvm/binary/ProofTraceParser.h>
6+
7+
namespace kllvm {
8+
9+
/*
10+
* This file contains utility functions that are used to pretty print
11+
* the Proof Trace and manipulate its data structures.
12+
*/
13+
14+
std::vector<int> parse_relative_location(std::string location);
15+
16+
llvm_event *build_post_function_event(
17+
sptr<kore_composite_pattern> &current_config,
18+
sptr<llvm_function_event> &function_event, bool expand_terms);
19+
20+
} // namespace kllvm
21+
22+
#endif // KLLVM_PROOF_TRACE_UTILS_CPP

lib/binary/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ add_library(BinaryKore
22
serializer.cpp
33
deserializer.cpp
44
ProofTraceParser.cpp
5+
ProofTraceUtils.cpp
56
)
67

78
target_link_libraries(BinaryKore

lib/binary/ProofTraceParser.cpp

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include <kllvm/binary/ProofTraceParser.h>
1+
#include <kllvm/binary/ProofTraceUtils.h>
22

33
#include <fmt/format.h>
44
#include <fstream>
@@ -174,24 +174,74 @@ llvm_rewrite_trace_iterator::get_next_event() {
174174
}
175175

176176
void llvm_rewrite_trace_iterator::print(
177-
std::ostream &out, bool expand_terms, unsigned ind) {
177+
std::ostream &out, bool expand_terms, unsigned ind,
178+
bool intermediate_configs) {
178179
std::string indent(ind * indent_size, ' ');
179180
out << fmt::format("{}version: {}\n", indent, version_);
180181
while (auto event = get_next_event()) {
181182
event.value().event.print(out, expand_terms, false, ind);
183+
if (intermediate_configs) {
184+
if (event.value().type == llvm_event_type::InitialConfig) {
185+
current_config_ = std::dynamic_pointer_cast<kore_composite_pattern>(
186+
event.value().event.getkore_pattern());
187+
} else if (event.value().type == llvm_event_type::Trace) {
188+
if (event.value().event.is_pattern()) {
189+
current_config_ = std::dynamic_pointer_cast<kore_composite_pattern>(
190+
event.value().event.getkore_pattern());
191+
} else {
192+
if (auto function_event
193+
= std::dynamic_pointer_cast<llvm_function_event>(
194+
event.value().event.get_step_event())) {
195+
auto *new_config_event = build_post_function_event(
196+
current_config_, function_event, expand_terms);
197+
if (new_config_event) {
198+
current_config_
199+
= std::dynamic_pointer_cast<kore_composite_pattern>(
200+
new_config_event->getkore_pattern());
201+
new_config_event->print(out, expand_terms, false, ind);
202+
}
203+
}
204+
}
205+
}
206+
}
182207
}
183208
}
184209

185210
void llvm_rewrite_trace::print(
186-
std::ostream &out, bool expand_terms, unsigned ind) const {
211+
std::ostream &out, bool expand_terms, unsigned ind,
212+
bool intermediate_configs) const {
187213
std::string indent(ind * indent_size, ' ');
188214
out << fmt::format("{}version: {}\n", indent, version_);
189215
for (auto const &pre_trace_event : pre_trace_) {
190216
pre_trace_event.print(out, expand_terms, false, ind);
191217
}
192218
initial_config_.print(out, expand_terms, false, ind);
193-
for (auto const &trace_event : trace_) {
194-
trace_event.print(out, expand_terms, false, ind);
219+
if (intermediate_configs) {
220+
auto current_config = std::dynamic_pointer_cast<kore_composite_pattern>(
221+
initial_config_.getkore_pattern());
222+
for (auto const &trace_event : trace_) {
223+
trace_event.print(out, expand_terms, false, ind);
224+
if (trace_event.is_pattern()) {
225+
current_config = std::dynamic_pointer_cast<kore_composite_pattern>(
226+
trace_event.getkore_pattern());
227+
} else {
228+
if (auto function_event
229+
= std::dynamic_pointer_cast<llvm_function_event>(
230+
trace_event.get_step_event())) {
231+
auto *new_config_event = build_post_function_event(
232+
current_config, function_event, expand_terms);
233+
if (new_config_event) {
234+
current_config = std::dynamic_pointer_cast<kore_composite_pattern>(
235+
new_config_event->getkore_pattern());
236+
new_config_event->print(out, expand_terms, false, ind);
237+
}
238+
}
239+
}
240+
}
241+
} else {
242+
for (auto const &trace_event : trace_) {
243+
trace_event.print(out, expand_terms, false, ind);
244+
}
195245
}
196246
}
197247

@@ -203,8 +253,8 @@ proof_trace_parser::proof_trace_parser(
203253
, header_(header)
204254
, kore_definition_(std::move(kore_definition)) { }
205255

206-
std::optional<llvm_rewrite_trace>
207-
proof_trace_parser::parse_proof_trace(std::string const &data) {
256+
std::optional<llvm_rewrite_trace> proof_trace_parser::parse_proof_trace(
257+
std::string const &data, bool intermediate_configs) {
208258
proof_trace_memory_buffer buffer(data.data(), data.data() + data.length());
209259
llvm_rewrite_trace trace;
210260
bool result = parse_trace(buffer, trace);
@@ -214,14 +264,15 @@ proof_trace_parser::parse_proof_trace(std::string const &data) {
214264
}
215265

216266
if (verbose_) {
217-
trace.print(std::cout, expand_terms_);
267+
trace.print(std::cout, expand_terms_, 0U, intermediate_configs);
218268
}
219269

220270
return trace;
221271
}
222272

223273
std::optional<llvm_rewrite_trace>
224-
proof_trace_parser::parse_proof_trace_from_file(std::string const &filename) {
274+
proof_trace_parser::parse_proof_trace_from_file(
275+
std::string const &filename, bool intermediate_configs) {
225276
std::ifstream file(filename, std::ios_base::binary);
226277
proof_trace_file_buffer buffer(std::move(file));
227278
llvm_rewrite_trace trace;
@@ -232,7 +283,7 @@ proof_trace_parser::parse_proof_trace_from_file(std::string const &filename) {
232283
}
233284

234285
if (verbose_) {
235-
trace.print(std::cout, expand_terms_);
286+
trace.print(std::cout, expand_terms_, 0U, intermediate_configs);
236287
}
237288

238289
return trace;

lib/binary/ProofTraceUtils.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include <kllvm/ast/AST.h>
2+
#include <kllvm/binary/ProofTraceUtils.h>
3+
4+
using namespace kllvm;
5+
6+
std::vector<int> kllvm::parse_relative_location(std::string location) {
7+
if (location.empty()) {
8+
return {};
9+
}
10+
std::vector<int> positions;
11+
std::string delimiter = ":";
12+
size_t pos = 0;
13+
std::string token;
14+
while ((pos = location.find(delimiter)) != std::string::npos) {
15+
token = location.substr(0, pos);
16+
positions.push_back(std::stoi(token));
17+
location.erase(0, pos + delimiter.length());
18+
}
19+
positions.push_back(std::stoi(location));
20+
return positions;
21+
}
22+
23+
llvm_event *kllvm::build_post_function_event(
24+
sptr<kore_composite_pattern> &current_config,
25+
sptr<llvm_function_event> &function_event, bool expand_terms) {
26+
sptr<kore_composite_pattern> new_config = nullptr;
27+
28+
// The name of the function is actually the kore_symbol
29+
// corresponding to the function's constructor: function_name{...}
30+
// We need to extract only the function name to build the composite pattern
31+
auto function_name = function_event->get_name();
32+
auto const *delimiter = "{";
33+
auto pos = function_name.find(delimiter);
34+
if (pos != std::string::npos) {
35+
function_name = function_name.substr(0, pos);
36+
}
37+
38+
// Construct the composite pattern for the function
39+
auto function = sptr<kore_composite_pattern>(
40+
kore_composite_pattern::create(function_name));
41+
for (auto const &arg : function_event->get_arguments()) {
42+
function->add_argument(arg.getkore_pattern());
43+
}
44+
45+
// Construct location
46+
std::string location = function_event->get_relative_position();
47+
std::vector<int> positions = kllvm::parse_relative_location(location);
48+
49+
// We can only replace the argument and build a new configuration if we have a location
50+
// And it's a top level function.
51+
if (positions.size() == 1) {
52+
53+
// Create a new configuration, set the ith argument to be replaced by the function or a pattern with it
54+
sptr<kore_composite_pattern> new_config
55+
= kore_composite_pattern::create(current_config->get_constructor());
56+
int index = positions[0];
57+
58+
// Add the new pattern to the new configuration
59+
for (int i = 0; i < current_config->get_arguments().size(); i++) {
60+
auto argument
61+
= i == index ? function : current_config->get_arguments()[i];
62+
new_config->add_argument(argument);
63+
}
64+
65+
// Get new configuration size
66+
std::stringstream ss;
67+
new_config->print(ss);
68+
auto new_config_size = ss.str().size();
69+
70+
auto *new_config_event = new llvm_event();
71+
new_config_event->setkore_pattern(new_config, new_config_size);
72+
73+
return new_config_event;
74+
}
75+
76+
return nullptr;
77+
}

test/lit.cfg.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,28 @@ def exclude_macos(s):
212212
fi
213213
done
214214
''')),
215+
216+
('%check-dir-proof-intermediate-out', one_line('''
217+
%kore-rich-header %s > %t.header.bin
218+
for out in %test-dir-out/*.proof.intermediate.out.diff; do
219+
in=%test-dir-in/`basename $out .proof.intermediate.out.diff`.in
220+
hint=%t.`basename $out .proof.intermediate.out.diff`.hint
221+
rm -f $hint
222+
%t.interpreter $in -1 $hint --proof-output
223+
%kore-proof-trace --verbose --expand-terms --intermediate-configs %t.header.bin $hint | diff - $out
224+
result="$?"
225+
if [ "$result" -ne 0 ]; then
226+
echo "kore-proof-trace error while parsing proof hint trace with expanded kore terms"
227+
exit 1
228+
fi
229+
%kore-proof-trace --streaming-parser --verbose --expand-terms --intermediate-configs %t.header.bin $hint | diff - $out
230+
result="$?"
231+
if [ "$result" -ne 0 ]; then
232+
echo "kore-proof-trace error while parsing proof hint trace with expanded kore terms and streaming parser"
233+
exit 1
234+
fi
235+
done
236+
''')),
215237

216238
('%run-binary-out', 'rm -f %t.out.bin && %t.interpreter %test-input -1 %t.out.bin --binary-output'),
217239
('%run-binary', 'rm -f %t.bin && %convert-input && %t.interpreter %t.bin -1 /dev/stdout'),
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
version: 13
2+
hook: MAP.element Lbl'UndsPipe'-'-GT-Unds'{} ()
3+
arg: kore[\dv{SortKConfigVar{}}("$PGM")]
4+
arg: kore[\dv{SortString{}}("input_file")]
5+
hook result: kore[Lbl'UndsPipe'-'-GT-Unds'{}(\dv{SortKConfigVar{}}("$PGM"),\dv{SortString{}}("input_file"))]
6+
hook: MAP.unit Lbl'Stop'Map{} ()
7+
hook result: kore[Lbl'Stop'Map{}()]
8+
hook: MAP.concat Lbl'Unds'Map'Unds'{} ()
9+
arg: kore[Lbl'Stop'Map{}()]
10+
arg: kore[Lbl'UndsPipe'-'-GT-Unds'{}(\dv{SortKConfigVar{}}("$PGM"),\dv{SortString{}}("input_file"))]
11+
hook result: kore[Lbl'UndsPipe'-'-GT-Unds'{}(\dv{SortKConfigVar{}}("$PGM"),\dv{SortString{}}("input_file"))]
12+
function: LblinitGeneratedTopCell{} ()
13+
arg: kore[Lbl'UndsPipe'-'-GT-Unds'{}(\dv{SortKConfigVar{}}("$PGM"),\dv{SortString{}}("input_file"))]
14+
rule: 2761 1
15+
VarInit = kore[Lbl'UndsPipe'-'-GT-Unds'{}(\dv{SortKConfigVar{}}("$PGM"),\dv{SortString{}}("input_file"))]
16+
function: LblinitKCell{} (0)
17+
arg: kore[Lbl'UndsPipe'-'-GT-Unds'{}(\dv{SortKConfigVar{}}("$PGM"),\dv{SortString{}}("input_file"))]
18+
rule: 2762 1
19+
VarInit = kore[Lbl'UndsPipe'-'-GT-Unds'{}(\dv{SortKConfigVar{}}("$PGM"),\dv{SortString{}}("input_file"))]
20+
hook: MAP.lookup LblMap'Coln'lookup{} (0:0:0:0:0)
21+
arg: kore[Lbl'UndsPipe'-'-GT-Unds'{}(\dv{SortKConfigVar{}}("$PGM"),\dv{SortString{}}("input_file"))]
22+
arg: kore[\dv{SortKConfigVar{}}("$PGM")]
23+
hook result: kore[\dv{SortString{}}("input_file")]
24+
function: Lblproject'Coln'String{} (0:0:0)
25+
arg: kore[kseq{}(\dv{SortString{}}("input_file"),dotk{}())]
26+
rule: 2841 1
27+
VarK = kore[\dv{SortString{}}("input_file")]
28+
function: LblinitFdCell{} (1)
29+
rule: 2759 0
30+
function: LblinitBufferCell{} (2)
31+
rule: 2758 0
32+
function: LblinitGeneratedCounterCell{} (3)
33+
rule: 2760 0
34+
config: kore[Lbl'-LT-'generatedTop'-GT-'{}(Lbl'-LT-'k'-GT-'{}(kseq{}(LblreadFromFile'LParUndsRParUnds'BUILTIN-IO'Unds'KItem'Unds'String{}(\dv{SortString{}}("input_file")),dotk{}())),Lbl'-LT-'fd'-GT-'{}(\dv{SortInt{}}("-1")),Lbl'-LT-'buffer'-GT-'{}(\dv{SortString{}}("")),Lbl'-LT-'generatedCounter'-GT-'{}(\dv{SortInt{}}("0")))]
35+
rule: 2712 4
36+
Var'Unds'Gen0 = kore[Lbl'-LT-'fd'-GT-'{}(\dv{SortInt{}}("-1"))]
37+
Var'Unds'Gen1 = kore[Lbl'-LT-'buffer'-GT-'{}(\dv{SortString{}}(""))]
38+
Var'Unds'Gen2 = kore[Lbl'-LT-'generatedCounter'-GT-'{}(\dv{SortInt{}}("0"))]
39+
VarFILE = kore[\dv{SortString{}}("input_file")]
40+
function: Lbl'Hash'open'LParUndsRParUnds'K-IO'Unds'IOInt'Unds'String{} (0:0:0:0)
41+
arg: kore[\dv{SortString{}}("input_file")]
42+
rule: 2702 1
43+
VarS = kore[\dv{SortString{}}("input_file")]
44+
hook: IO.open Lbl'Hash'open'LParUndsCommUndsRParUnds'K-IO'Unds'IOInt'Unds'String'Unds'String{} ()
45+
arg: kore[\dv{SortString{}}("input_file")]
46+
arg: kore[\dv{SortString{}}("r+")]
47+
hook result: kore[Lbl'Hash'ENOENT{}()]
48+
config: kore[Lbl'-LT-'generatedTop'-GT-'{}(Lbl'-LT-'k'-GT-'{}(kseq{}(Lblopen'LParUndsRParUnds'BUILTIN-IO'Unds'KItem'Unds'IOInt{}(Lbl'Hash'ENOENT{}()),dotk{}())),Lbl'-LT-'fd'-GT-'{}(\dv{SortInt{}}("-1")),Lbl'-LT-'buffer'-GT-'{}(\dv{SortString{}}("")),Lbl'-LT-'generatedCounter'-GT-'{}(\dv{SortInt{}}("0")))]
49+
rule: 2710 4
50+
Var'Unds'Gen0 = kore[\dv{SortInt{}}("-1")]
51+
Var'Unds'Gen1 = kore[Lbl'-LT-'buffer'-GT-'{}(\dv{SortString{}}(""))]
52+
Var'Unds'Gen2 = kore[Lbl'-LT-'generatedCounter'-GT-'{}(\dv{SortInt{}}("0"))]
53+
VarE = kore[Lbl'Hash'ENOENT{}()]
54+
config: kore[Lbl'-LT-'generatedTop'-GT-'{}(Lbl'-LT-'k'-GT-'{}(kseq{}(Lbl'Hash'ENOENT{}(),dotk{}())),Lbl'-LT-'fd'-GT-'{}(\dv{SortInt{}}("-2")),Lbl'-LT-'buffer'-GT-'{}(\dv{SortString{}}("")),Lbl'-LT-'generatedCounter'-GT-'{}(\dv{SortInt{}}("0")))]

0 commit comments

Comments
 (0)