Skip to content

Commit 2aafd9b

Browse files
authored
Merge pull request #3524 from diffblue/no-identifiers-in-domain
separate parameter identifiers from (mathematical) function signature
2 parents 0b31412 + 60d2680 commit 2aafd9b

File tree

4 files changed

+56
-58
lines changed

4 files changed

+56
-58
lines changed

src/solvers/smt2/smt2_parser.cpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -987,18 +987,21 @@ typet smt2_parsert::sort()
987987
}
988988
}
989989

990-
typet smt2_parsert::function_signature_definition()
990+
smt2_parsert::signature_with_parameter_idst
991+
smt2_parsert::function_signature_definition()
991992
{
992993
if(next_token()!=OPEN)
993994
throw error("expected '(' at beginning of signature");
994995

995996
if(peek()==CLOSE)
996997
{
998+
// no parameters
997999
next_token(); // eat the ')'
998-
return sort();
1000+
return signature_with_parameter_idst(sort());
9991001
}
10001002

10011003
mathematical_function_typet::domaint domain;
1004+
std::vector<irep_idt> parameters;
10021005

10031006
while(peek()!=CLOSE)
10041007
{
@@ -1008,14 +1011,12 @@ typet smt2_parsert::function_signature_definition()
10081011
if(next_token()!=SYMBOL)
10091012
throw error("expected symbol in parameter");
10101013

1011-
mathematical_function_typet::variablet var;
1012-
std::string id=buffer;
1013-
var.set_identifier(id);
1014-
var.type()=sort();
1015-
domain.push_back(var);
1014+
irep_idt id = buffer;
1015+
parameters.push_back(id);
1016+
domain.push_back(sort());
10161017

10171018
auto &entry=id_map[id];
1018-
entry.type=var.type();
1019+
entry.type = domain.back();
10191020
entry.definition=nil_exprt();
10201021

10211022
if(next_token()!=CLOSE)
@@ -1026,7 +1027,8 @@ typet smt2_parsert::function_signature_definition()
10261027

10271028
typet codomain = sort();
10281029

1029-
return mathematical_function_typet(domain, codomain);
1030+
return signature_with_parameter_idst(
1031+
mathematical_function_typet(domain, codomain), parameters);
10301032
}
10311033

10321034
typet smt2_parsert::function_signature_declaration()
@@ -1050,9 +1052,7 @@ typet smt2_parsert::function_signature_declaration()
10501052
if(next_token()!=SYMBOL)
10511053
throw error("expected symbol in parameter");
10521054

1053-
mathematical_function_typet::variablet var;
1054-
var.type()=sort();
1055-
domain.push_back(var);
1055+
domain.push_back(sort());
10561056

10571057
if(next_token()!=CLOSE)
10581058
throw error("expected ')' at end of parameter");
@@ -1161,9 +1161,9 @@ void smt2_parsert::command(const std::string &c)
11611161
const auto body = expression();
11621162

11631163
// check type of body
1164-
if(signature.id() == ID_mathematical_function)
1164+
if(signature.type.id() == ID_mathematical_function)
11651165
{
1166-
const auto &f_signature = to_mathematical_function_type(signature);
1166+
const auto &f_signature = to_mathematical_function_type(signature.type);
11671167
if(body.type() != f_signature.codomain())
11681168
{
11691169
std::ostringstream msg;
@@ -1173,19 +1173,20 @@ void smt2_parsert::command(const std::string &c)
11731173
throw error(msg.str());
11741174
}
11751175
}
1176-
else if(body.type() != signature)
1176+
else if(body.type() != signature.type)
11771177
{
11781178
std::ostringstream msg;
11791179
msg << "type mismatch in function definition: expected `"
1180-
<< smt2_format(signature) << "' but got `" << smt2_format(body.type())
1181-
<< '\'';
1180+
<< smt2_format(signature.type) << "' but got `"
1181+
<< smt2_format(body.type()) << '\'';
11821182
throw error(msg.str());
11831183
}
11841184

11851185
// create the entry
1186-
auto &entry=id_map[id];
1187-
entry.type=signature;
1188-
entry.definition=body;
1186+
auto &entry = id_map[id];
1187+
entry.type = signature.type;
1188+
entry.parameters = signature.parameters;
1189+
entry.definition = body;
11891190
}
11901191
else if(c=="exit")
11911192
{

src/solvers/smt2/smt2_parser.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class smt2_parsert:public smt2_tokenizert
3737

3838
typet type;
3939
exprt definition;
40+
std::vector<irep_idt> parameters;
4041
};
4142

4243
using id_mapt=std::map<irep_idt, idt>;
@@ -73,13 +74,35 @@ class smt2_parsert:public smt2_tokenizert
7374
irep_idt get_fresh_id(const irep_idt &);
7475
irep_idt rename_id(const irep_idt &) const;
7576

77+
struct signature_with_parameter_idst
78+
{
79+
typet type;
80+
std::vector<irep_idt> parameters;
81+
82+
explicit signature_with_parameter_idst(const typet &_type) : type(_type)
83+
{
84+
}
85+
86+
signature_with_parameter_idst(
87+
const typet &_type,
88+
const std::vector<irep_idt> &_parameters)
89+
: type(_type), parameters(_parameters)
90+
{
91+
PRECONDITION(
92+
(_type.id() == ID_mathematical_function &&
93+
to_mathematical_function_type(_type).domain().size() ==
94+
_parameters.size()) ||
95+
(_type.id() != ID_mathematical_function && _parameters.empty()));
96+
}
97+
};
98+
7699
void ignore_command();
77100
exprt expression();
78101
exprt function_application();
79102
typet sort();
80103
exprt::operandst operands();
81104
typet function_signature_declaration();
82-
typet function_signature_definition();
105+
signature_with_parameter_idst function_signature_definition();
83106
exprt multi_ary(irep_idt, const exprt::operandst &);
84107
exprt binary_predicate(irep_idt, const exprt::operandst &);
85108
exprt binary(irep_idt, const exprt::operandst &);

src/solvers/smt2/smt2_solver.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,18 @@ void smt2_solvert::expand_function_applications(exprt &expr)
103103
const auto f_type=
104104
to_mathematical_function_type(f.type);
105105

106-
DATA_INVARIANT(f_type.domain().size()==
107-
app.arguments().size(),
108-
"number of function parameters");
106+
const auto &domain = f_type.domain();
107+
108+
DATA_INVARIANT(
109+
domain.size() == app.arguments().size(),
110+
"number of function parameters");
109111

110112
replace_symbolt replace_symbol;
111113

112114
std::map<irep_idt, exprt> parameter_map;
113-
for(std::size_t i=0; i<f_type.domain().size(); i++)
115+
for(std::size_t i = 0; i < domain.size(); i++)
114116
{
115-
const auto &var = f_type.domain()[i];
116-
const symbol_exprt s(var.get_identifier(), var.type());
117+
const symbol_exprt s(f.parameters[i], domain[i]);
117118
replace_symbol.insert(s, app.arguments()[i]);
118119
}
119120

src/util/mathematical_types.h

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -59,33 +59,8 @@ class mathematical_function_typet : public type_with_subtypest
5959
{
6060
public:
6161
// the domain of the function is composed of zero, one, or
62-
// many variables
63-
class variablet : public irept
64-
{
65-
public:
66-
// the identifier is optional
67-
irep_idt get_identifier() const
68-
{
69-
return get(ID_identifier);
70-
}
71-
72-
void set_identifier(const irep_idt &identifier)
73-
{
74-
return set(ID_identifier, identifier);
75-
}
76-
77-
typet &type()
78-
{
79-
return static_cast<typet &>(add(ID_type));
80-
}
81-
82-
const typet &type() const
83-
{
84-
return static_cast<const typet &>(find(ID_type));
85-
}
86-
};
87-
88-
using domaint = std::vector<variablet>;
62+
// many variables, given by their type
63+
using domaint = std::vector<typet>;
8964

9065
mathematical_function_typet(const domaint &_domain, const typet &_codomain)
9166
: type_with_subtypest(ID_mathematical_function)
@@ -105,11 +80,9 @@ class mathematical_function_typet : public type_with_subtypest
10580
return (const domaint &)to_type_with_subtypes(subtypes()[0]).subtypes();
10681
}
10782

108-
variablet &add_variable()
83+
void add_variable(const typet &_type)
10984
{
110-
auto &d = domain();
111-
d.push_back(variablet());
112-
return d.back();
85+
domain().push_back(_type);
11386
}
11487

11588
/// Return the codomain, i.e., the set of values that the function maps to

0 commit comments

Comments
 (0)