-
Notifications
You must be signed in to change notification settings - Fork 274
Log SMT formula to file for new incremental backend. #7126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Log SMT formula to file for new incremental backend. #7126
Conversation
0bf0711
to
a506981
Compare
Codecov ReportBase: 77.88% // Head: 77.89% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## develop #7126 +/- ##
========================================
Coverage 77.88% 77.89%
========================================
Files 1576 1576
Lines 181856 181886 +30
========================================
+ Hits 141645 141675 +30
Misses 40211 40211
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
a506981
to
43439bc
Compare
43439bc
to
b2b7199
Compare
regression/cbmc-outfile/chain.py
Outdated
@@ -0,0 +1,71 @@ | |||
#!/usr/bin/env python3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need that script? Couldn't it also be done by using --outfile /dev/stdout
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, unfortunately we need it as:
- We test on windows where
/dev/stdout
may not work - By adding
--outfile /dev/stdout
we will know that the SMT formula is printed on the screen, not that it is added to the out file, so we cannot distinguish file from normal output. - The way the test output is checked is not in a certain order while the python script enforce a certain ordering, so if we want to have 2
(check-sat)
calls the old system will be satisfied with one(check-sat)
in the output, the new one instead will require 2 in the specified order
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I believe you can use
-
instead of/dev/stdout
, which will then work across platforms. - Granted, but I'm not sure this one aspect is a sufficient reason to warrant yet another piece of code that needs to be maintained.
- You can use
activate-multi-line-match
to handle this case.
I don't intend to block on that, but every line of code that is written has a (future) cost. So I ask for careful consideration whether this really is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately in the new SMT backend we do not support the old --outfile -
behaviour as, because of the interactive behaviour, the output will be interleaved with other messages (defying the sense of --outfile
).
It is still possible to get the SMT formula on the stdout
by using --verbosity 10
and then filtering the lines sent to the solver.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, good point. So I guess you have to keep the Python script, and I'm just hoping it won't break...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I believe you can use
-
instead of/dev/stdout
, which will then work across platforms.
The -
option is special cased in the solver factory. So tests which rely on this aren't fully testing the code path for writing to file.
I think this python script has value beyond the new incremental smt backend, because it could also be used to test the dimacs output for example.
// Using std::endl to flush the stream as it is a debugging functionality, | ||
// and we can guarantee a consistent output in case of hanging after | ||
// (check-sat) | ||
*out_stream << command_string << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you perhaps just want to use std::flush
instead? Most of the comment would remain useful to keep, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we want a new line and a flush
I prefer std::endl
instead of adding a new line + adding an explicit std::flush
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, but then you might want the comment to say "Using std::endl instead of \n"
@@ -35,9 +37,12 @@ class smt_piped_solver_processt : public smt_base_solver_processt | |||
/// The command and arguments for invoking the smt2 solver. | |||
/// \param message_handler: | |||
/// The messaging system to be used for logging purposes. | |||
/// \param out_stream: | |||
/// Pointer to the stream to print the SMT formula. `nullptr` if no output. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
smt_piped_solver_processt( | ||
std::string command_line, | ||
message_handlert &message_handler); | ||
message_handlert &message_handler, | ||
std::unique_ptr<std::ostream> out_stream); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is passing the std::unique_ptr
by value rather than as a reference the right thing to do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes as we want to extend the lifetime of the passed stream to the one of the smt_solver_proces
object that is longer than the one of the solver_factory
where the pointer is created.
src/cbmc/cbmc_parse_options.cpp
Outdated
if( | ||
cmdline.isset("stop-on-fail") || cmdline.isset("dimacs") || | ||
(cmdline.isset("outfile") && !cmdline.isset("incremental-smt2-solver"))) | ||
{ | ||
options.set_option("stop-on-fail", true); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm either failing to parse the commit message or don't understand why the incremental SMT2 solver now interacts with "outfile" in this way. Is it the case that "outfile" has a very different semantics with the incremental SMT2 solver?! Does not seem like a good idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we stop on fail, then we stop processing after the first round of solving. If we want to dump the SMT2 formula to file for all rounds of solving for ease of debugging (human reading) of the written file then we need to not stop on failure. Otherwise only the first round of solving is written to file, because we stopped on failure.
My somewhat related question would be why do we automatically stop on failure when --outfile
is used with any of the decision procedures?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To your "somewhat related question:" no actual solving takes place with other back-ends with --outfile
, and also: what would be the semantics of having only a single output file but multiple formulae having to be written?
So if the incremental SMT2 back-end has substantially different behaviour (solving actually takes place, multiple formulae are written) then we really shouldn't be using the same command-line option name. This confusing user-experience is a blocker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise only the first round of solving is written to file, because we stopped on failure.
But if you specified --stop-on-fail then this is exactly what you asked for. So, I don't see the point of having special behaviour here, @thomasspriggs. If you want all rounds to be written to the file then remove the --stop-on-fail flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this is for when we aren't explicitly specifying --stop-on-fail
. The argument parsing is currently adding "stop-on-fail" implicitly when --outfile
is specified. Do we need to add an explicit --continue-on-fail
to override the implicit option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Then I'd call the current behaviour somewhat confusing... not sure how to fix that without having different behaviour for incremental vs non-incremental, or having multiple options. (Definitely not a --continue-on-fail option)
b2b7199
to
ca83774
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partial review only.
src/goto-checker/solver_factory.cpp
Outdated
{ | ||
throw invalid_command_line_argument_exceptiont( | ||
"failed to open file: " + outfile, "--outfile"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⛏️ This section of code appears to have been duplicated from the get_smt2
, can you separate it into a function. I guess the function should take the (potentially empty) outfile
string and either throw or return an std::unique_ptr<std::ofstream>
.
src/cbmc/cbmc_parse_options.cpp
Outdated
if( | ||
cmdline.isset("stop-on-fail") || cmdline.isset("dimacs") || | ||
(cmdline.isset("outfile") && !cmdline.isset("incremental-smt2-solver"))) | ||
{ | ||
options.set_option("stop-on-fail", true); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we stop on fail, then we stop processing after the first round of solving. If we want to dump the SMT2 formula to file for all rounds of solving for ease of debugging (human reading) of the written file then we need to not stop on failure. Otherwise only the first round of solving is written to file, because we stopped on failure.
My somewhat related question would be why do we automatically stop on failure when --outfile
is used with any of the decision procedures?
// Using std::endl to flush the stream as it is a debugging functionality, | ||
// and we can guarantee a consistent output in case of hanging after | ||
// (check-sat) | ||
*out_stream << command_string << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to print a message that this action has been performed? E.g.
std::cout << "Outputting SMTLib to $file"
Probably somewhere else (constructor maybe?) so that the user can see what's going on (now I can use that, but there's no indication that this worked at all, which I found a bit surprising).
ca83774
to
95a411c
Compare
95a411c
to
06b377d
Compare
Re-opened as it was closed in error. |
ecfd902
to
7fd76e6
Compare
Due to review comments, some extra work has been done so that now the There will be a subsequent PR that will add a new argument |
5f22a32
to
821b9ad
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
regression/cbmc-incr-smt2/nondeterministic-int-assert/stdout-match.desc
Outdated
Show resolved
Hide resolved
regression/cbmc-incr-smt2/nondeterministic-int-assert/stdout-match.desc
Outdated
Show resolved
Hide resolved
821b9ad
to
1dc2e03
Compare
@tautschnig I think the new reworked commits should address your comments and concerns, especially as now the old |
Add the possibility to log the SMT formula generated by the new SMT2 incremental backend to a file.
To use the feature add
--outfile <filename>
to command-line arguments.