Skip to content

Commit 3a6341f

Browse files
authored
Merge pull request #6940 from diffblue/smt2-simple-symbol
SMT2 backend: generate simple symbols
2 parents e78eacf + baba52b commit 3a6341f

File tree

7 files changed

+90
-50
lines changed

7 files changed

+90
-50
lines changed

src/solvers/smt2/smt2_conv.cpp

Lines changed: 54 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ Author: Daniel Kroening, [email protected]
4141
#include <solvers/lowering/expr_lowering.h>
4242
#include <solvers/prop/literal_expr.h>
4343

44+
#include "smt2_tokenizer.h"
45+
4446
// Mark different kinds of error conditions
4547

4648
// Unexpected types and other combinations not implemented and not
@@ -218,7 +220,7 @@ void smt2_convt::write_footer()
218220
if(solver!=solvert::BOOLECTOR)
219221
{
220222
for(const auto &id : smt2_identifiers)
221-
out << "(get-value (|" << id << "|))"
223+
out << "(get-value (" << id << "))"
222224
<< "\n";
223225
}
224226

@@ -260,7 +262,7 @@ void smt2_convt::define_object_size(
260262
<< "((_ extract " << h << " " << l << ") ";
261263
convert_expr(ptr);
262264
out << ") (_ bv" << number << " " << config.bv_encoding.object_bits << "))"
263-
<< "(= |" << id << "| (_ bv" << *object_size << " " << size_width
265+
<< "(= " << id << " (_ bv" << *object_size << " " << size_width
264266
<< "))))\n";
265267

266268
++number;
@@ -837,16 +839,17 @@ literalt smt2_convt::convert(const exprt &expr)
837839
out << " () Bool)\n";
838840
out << "(assert (= ";
839841
convert_literal(l);
842+
out << ' ';
840843
convert_expr(prepared_expr);
841844
out << "))\n";
842845
}
843846
else
844847
{
845-
defined_expressions[expr] =
846-
std::string{"|B"} + std::to_string(l.var_no()) + "|";
847-
out << "(define-fun ";
848-
convert_literal(l);
849-
out << " () Bool ";
848+
auto identifier =
849+
convert_identifier(std::string{"B"} + std::to_string(l.var_no()));
850+
defined_expressions[expr] = identifier;
851+
smt2_identifiers.insert(identifier);
852+
out << "(define-fun " << identifier << " () Bool ";
850853
convert_expr(prepared_expr);
851854
out << ")\n";
852855
}
@@ -874,12 +877,15 @@ void smt2_convt::convert_literal(const literalt l)
874877
if(l.sign())
875878
out << "(not ";
876879

877-
out << "|B" << l.var_no() << "|";
880+
const auto identifier =
881+
convert_identifier("B" + std::to_string(l.var_no()));
882+
883+
out << identifier;
878884

879885
if(l.sign())
880886
out << ")";
881887

882-
smt2_identifiers.insert("B"+std::to_string(l.var_no()));
888+
smt2_identifiers.insert(identifier);
883889
}
884890
}
885891

@@ -900,18 +906,37 @@ void smt2_convt::pop()
900906
assumptions.clear();
901907
}
902908

909+
static bool is_smt2_simple_identifier(const std::string &identifier)
910+
{
911+
if(identifier.empty())
912+
return false;
913+
914+
if(isdigit(identifier[0]))
915+
return false;
916+
917+
for(auto ch : id2string(identifier))
918+
{
919+
if(!is_smt2_simple_symbol_character(ch))
920+
return false;
921+
}
922+
923+
return true;
924+
}
925+
903926
std::string smt2_convt::convert_identifier(const irep_idt &identifier)
904927
{
928+
// Is this a "simple identifier"?
929+
if(is_smt2_simple_identifier(id2string(identifier)))
930+
return id2string(identifier);
931+
905932
// Backslashes are disallowed in quoted symbols just for simplicity.
906933
// Otherwise, for Common Lisp compatibility they would have to be treated
907934
// as escaping symbols.
908935

909-
std::string result;
936+
std::string result = "|";
910937

911-
for(std::size_t i=0; i<identifier.size(); i++)
938+
for(auto ch : identifier)
912939
{
913-
char ch=identifier[i];
914-
915940
switch(ch)
916941
{
917942
case '|':
@@ -928,6 +953,8 @@ std::string smt2_convt::convert_identifier(const irep_idt &identifier)
928953
}
929954
}
930955

956+
result += '|';
957+
931958
return result;
932959
}
933960

@@ -989,7 +1016,7 @@ void smt2_convt::convert_floatbv(const exprt &expr)
9891016
if(expr.id()==ID_symbol)
9901017
{
9911018
const irep_idt &id = to_symbol_expr(expr).get_identifier();
992-
out << '|' << convert_identifier(id) << '|';
1019+
out << convert_identifier(id);
9931020
return;
9941021
}
9951022

@@ -1003,9 +1030,9 @@ void smt2_convt::convert_floatbv(const exprt &expr)
10031030
INVARIANT(
10041031
!expr.operands().empty(), "non-symbol expressions shall have operands");
10051032

1006-
out << "(|float_bv." << expr.id()
1007-
<< floatbv_suffix(expr)
1008-
<< '|';
1033+
out << '('
1034+
<< convert_identifier(
1035+
"float_bv." + expr.id_string() + floatbv_suffix(expr));
10091036

10101037
forall_operands(it, expr)
10111038
{
@@ -1023,13 +1050,13 @@ void smt2_convt::convert_expr(const exprt &expr)
10231050
{
10241051
const irep_idt &id = to_symbol_expr(expr).get_identifier();
10251052
DATA_INVARIANT(!id.empty(), "symbol must have identifier");
1026-
out << '|' << convert_identifier(id) << '|';
1053+
out << convert_identifier(id);
10271054
}
10281055
else if(expr.id()==ID_nondet_symbol)
10291056
{
10301057
const irep_idt &id = to_nondet_symbol_expr(expr).get_identifier();
10311058
DATA_INVARIANT(!id.empty(), "nondet symbol must have identifier");
1032-
out << '|' << convert_identifier("nondet_"+id2string(id)) << '|';
1059+
out << convert_identifier("nondet_" + id2string(id));
10331060
}
10341061
else if(expr.id()==ID_smt2_symbol)
10351062
{
@@ -2149,7 +2176,7 @@ void smt2_convt::convert_expr(const exprt &expr)
21492176
else if(
21502177
const auto object_size = expr_try_dynamic_cast<object_size_exprt>(expr))
21512178
{
2152-
out << "|" << object_sizes[*object_size] << "|";
2179+
out << object_sizes[*object_size];
21532180
}
21542181
else if(expr.id()==ID_let)
21552182
{
@@ -4619,7 +4646,7 @@ void smt2_convt::set_to(const exprt &expr, bool value)
46194646
smt2_identifiers.insert(smt2_identifier);
46204647

46214648
out << "; set_to true (equal)\n";
4622-
out << "(define-fun |" << smt2_identifier << '|';
4649+
out << "(define-fun " << smt2_identifier;
46234650

46244651
if(equal_expr.lhs().type().id() == ID_mathematical_function)
46254652
{
@@ -4803,7 +4830,7 @@ void smt2_convt::find_symbols(const exprt &expr)
48034830
smt2_identifiers.insert(smt2_identifier);
48044831

48054832
out << "; find_symbols\n";
4806-
out << "(declare-fun |" << smt2_identifier << '|';
4833+
out << "(declare-fun " << smt2_identifier;
48074834

48084835
if(expr.type().id() == ID_mathematical_function)
48094836
{
@@ -4982,8 +5009,9 @@ void smt2_convt::find_symbols(const exprt &expr)
49825009
{
49835010
if(object_sizes.find(*object_size) == object_sizes.end())
49845011
{
4985-
const irep_idt id = "object_size." + std::to_string(object_sizes.size());
4986-
out << "(declare-fun |" << id << "| () ";
5012+
const irep_idt id = convert_identifier(
5013+
"object_size." + std::to_string(object_sizes.size()));
5014+
out << "(declare-fun " << id << " () ";
49875015
convert_type(object_size->type());
49885016
out << ")"
49895017
<< "\n";
@@ -5016,8 +5044,8 @@ void smt2_convt::find_symbols(const exprt &expr)
50165044
to_multi_ary_expr(expr).op0().type().id() == ID_floatbv)))
50175045
// clang-format on
50185046
{
5019-
irep_idt function=
5020-
"|float_bv."+expr.id_string()+floatbv_suffix(expr)+"|";
5047+
irep_idt function =
5048+
convert_identifier("float_bv." + expr.id_string() + floatbv_suffix(expr));
50215049

50225050
if(bvfp_set.insert(function).second)
50235051
{

src/solvers/smt2/smt2_dec.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,14 @@ decision_proceduret::resultt smt2_dect::dec_solve()
130130
return read_result(in);
131131
}
132132

133+
static std::string drop_quotes(std::string src)
134+
{
135+
if(src.size() >= 2 && src.front() == '|' && src.back() == '|')
136+
return std::string(src, 1, src.size() - 2);
137+
else
138+
return src;
139+
}
140+
133141
decision_proceduret::resultt smt2_dect::read_result(std::istream &in)
134142
{
135143
std::string line;
@@ -199,22 +207,25 @@ decision_proceduret::resultt smt2_dect::read_result(std::istream &in)
199207

200208
for(auto &assignment : identifier_map)
201209
{
202-
std::string conv_id = convert_identifier(assignment.first);
210+
std::string conv_id = drop_quotes(convert_identifier(assignment.first));
203211
const irept &value = parsed_values[conv_id];
204212
assignment.second.value = parse_rec(value, assignment.second.type);
205213
}
206214

207215
// Booleans
208216
for(unsigned v=0; v<no_boolean_variables; v++)
209217
{
210-
const std::string boolean_identifier = "B" + std::to_string(v);
218+
const std::string boolean_identifier =
219+
convert_identifier("B" + std::to_string(v));
211220
boolean_assignment[v] = [&]() {
212-
const auto found_parsed_value = parsed_values.find(boolean_identifier);
221+
const auto found_parsed_value =
222+
parsed_values.find(drop_quotes(boolean_identifier));
213223
if(found_parsed_value != parsed_values.end())
224+
{
214225
return found_parsed_value->second.id() == ID_true;
226+
}
215227
// Work out the value based on what set_to was called with.
216-
const auto found_set_value =
217-
set_values.find('|' + boolean_identifier + '|');
228+
const auto found_set_value = set_values.find(boolean_identifier);
218229
if(found_set_value != set_values.end())
219230
return found_set_value->second;
220231
// Old code used the computation

src/solvers/smt2/smt2_tokenizer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Author: Daniel Kroening, [email protected]
88

99
#include "smt2_tokenizer.h"
1010

11-
bool smt2_tokenizert::is_simple_symbol_character(char ch)
11+
bool is_smt2_simple_symbol_character(char ch)
1212
{
1313
// any non-empty sequence of letters, digits and the characters
1414
// ~ ! @ $ % ^ & * _ - + = < > . ? /
@@ -32,7 +32,7 @@ smt2_tokenizert::tokent smt2_tokenizert::get_simple_symbol()
3232
char ch;
3333
while(in->get(ch))
3434
{
35-
if(is_simple_symbol_character(ch))
35+
if(is_smt2_simple_symbol_character(ch))
3636
{
3737
buffer+=ch;
3838
}
@@ -294,7 +294,7 @@ void smt2_tokenizert::get_token_from_stream()
294294
token = get_decimal_numeral();
295295
return;
296296
}
297-
else if(is_simple_symbol_character(ch))
297+
else if(is_smt2_simple_symbol_character(ch))
298298
{
299299
in->unget();
300300
token = get_simple_symbol();

src/solvers/smt2/smt2_tokenizer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ class smt2_tokenizert
120120
tokent get_simple_symbol();
121121
tokent get_quoted_symbol();
122122
tokent get_string_literal();
123-
static bool is_simple_symbol_character(char);
124123

125124
/// read a token from the input stream and store it in 'token'
126125
void get_token_from_stream();
@@ -135,4 +134,6 @@ operator<<(smt2_tokenizert::smt2_errort &&e, const T &message)
135134
return std::move(e);
136135
}
137136

137+
bool is_smt2_simple_symbol_character(char);
138+
138139
#endif // CPROVER_SOLVERS_SMT2_SMT2_PARSER_H

src/solvers/smt2_incremental/smt_to_smt2_string.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
static std::string escape_identifier(const irep_idt &identifier)
2121
{
22-
return std::string{"|"} + smt2_convt::convert_identifier(identifier) + "|";
22+
return smt2_convt::convert_identifier(identifier);
2323
}
2424

2525
class smt_index_output_visitort : public smt_index_const_downcast_visitort

unit/solvers/smt2/smt2_conv.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ TEST_CASE(
88
"smt2_convt::convert_identifier character escaping.",
99
"[core][solvers][smt2]")
1010
{
11-
const auto no_escaping_characters = "abcdefghijklmnopqrstuvwxyz0123456789$";
11+
const std::string no_escaping_characters =
12+
"abcdefghijklmnopqrstuvwxyz0123456789$";
1213
CHECK(
1314
smt2_convt::convert_identifier(no_escaping_characters) ==
1415
no_escaping_characters);
15-
CHECK(smt2_convt::convert_identifier("\\") == "&92;");
16-
CHECK(smt2_convt::convert_identifier("|") == "&124;");
17-
CHECK(smt2_convt::convert_identifier("&") == "&38;");
16+
CHECK(smt2_convt::convert_identifier("\\") == "|&92;|");
17+
CHECK(smt2_convt::convert_identifier("|") == "|&124;|");
18+
CHECK(smt2_convt::convert_identifier("&") == "&");
1819
}

unit/solvers/smt2_incremental/smt_to_smt2_string.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
TEST_CASE("Test smt_indext to string conversion", "[core][smt2_incremental]")
1515
{
16-
CHECK(smt_to_smt2_string(smt_symbol_indext{"green"}) == "|green|");
16+
CHECK(smt_to_smt2_string(smt_symbol_indext{"green"}) == "green");
1717
CHECK(smt_to_smt2_string(smt_numeral_indext{42}) == "42");
1818
}
1919

@@ -36,7 +36,7 @@ TEST_CASE(
3636
{
3737
CHECK(
3838
smt_to_smt2_string(smt_bit_vector_theoryt::extract(7, 3)(
39-
smt_bit_vector_constant_termt{0, 8})) == "((_ |extract| 7 3) (_ bv0 8))");
39+
smt_bit_vector_constant_termt{0, 8})) == "((_ extract 7 3) (_ bv0 8))");
4040
}
4141

4242
TEST_CASE(
@@ -55,7 +55,7 @@ TEST_CASE(
5555
{
5656
CHECK(
5757
smt_to_smt2_string(smt_identifier_termt{"abc", smt_bool_sortt{}}) ==
58-
"|abc|");
58+
"abc");
5959
CHECK(
6060
smt_to_smt2_string(smt_identifier_termt{"\\", smt_bool_sortt{}}) ==
6161
"|&92;|");
@@ -67,7 +67,7 @@ TEST_CASE(
6767
"foo",
6868
smt_bool_sortt{},
6969
{smt_symbol_indext{"bar"}, smt_numeral_indext{42}}}) ==
70-
"(_ |foo| |bar| 42)");
70+
"(_ foo bar 42)");
7171
}
7272
}
7373

@@ -78,8 +78,7 @@ TEST_CASE(
7878
CHECK(
7979
smt_to_smt2_string(smt_core_theoryt::equal(
8080
smt_identifier_termt{"foo", smt_bit_vector_sortt{32}},
81-
smt_identifier_termt{"bar", smt_bit_vector_sortt{32}})) ==
82-
"(|=| |foo| |bar|)");
81+
smt_identifier_termt{"bar", smt_bit_vector_sortt{32}})) == "(= foo bar)");
8382
}
8483

8584
TEST_CASE(
@@ -102,7 +101,7 @@ TEST_CASE(
102101
{
103102
CHECK(
104103
smt_to_smt2_string(smt_get_value_commandt{
105-
smt_identifier_termt{"foo", smt_bool_sortt{}}}) == "(get-value (|foo|))");
104+
smt_identifier_termt{"foo", smt_bool_sortt{}}}) == "(get-value (foo))");
106105
}
107106

108107
TEST_CASE(
@@ -138,7 +137,7 @@ TEST_CASE(
138137
smt_to_smt2_string(smt_declare_function_commandt{
139138
smt_identifier_termt{"f", smt_bit_vector_sortt{31}},
140139
{smt_bit_vector_sortt{32}, smt_bit_vector_sortt{33}}}) ==
141-
"(declare-fun |f| ((_ BitVec 32) (_ BitVec 33)) (_ BitVec 31))");
140+
"(declare-fun f ((_ BitVec 32) (_ BitVec 33)) (_ BitVec 31))");
142141
}
143142

144143
TEST_CASE(
@@ -151,8 +150,8 @@ TEST_CASE(
151150
CHECK(
152151
smt_to_smt2_string(smt_define_function_commandt{
153152
"f", {g, h}, smt_core_theoryt::equal(g, h)}) ==
154-
"(define-fun |f| ((|g| (_ BitVec 32)) (|h| (_ BitVec 32))) Bool (|=| |g| "
155-
"|h|))");
153+
"(define-fun f ((g (_ BitVec 32)) (h (_ BitVec 32))) Bool (= g "
154+
"h))");
156155
}
157156

158157
TEST_CASE(

0 commit comments

Comments
 (0)