@@ -1105,28 +1105,24 @@ namespace datatype {
1105
1105
*/
1106
1106
func_decl * util::get_non_rec_constructor (sort * ty) {
1107
1107
SASSERT (is_datatype (ty));
1108
- func_decl * r = nullptr ;
1109
- if (m_datatype2nonrec_constructor.find (ty, r))
1110
- return r;
1111
- r = nullptr ;
1108
+ cnstr_depth cd;
1109
+ if (m_datatype2nonrec_constructor.find (ty, cd))
1110
+ return cd.first ;
1112
1111
ptr_vector<sort> forbidden_set;
1113
1112
forbidden_set.push_back (ty);
1114
1113
TRACE (" util_bug" , tout << " invoke get-non-rec: " << sort_ref (ty, m) << " \n " ;);
1115
- r = get_non_rec_constructor_core (ty, forbidden_set);
1114
+ cd = get_non_rec_constructor_core (ty, forbidden_set);
1116
1115
SASSERT (forbidden_set.back () == ty);
1117
- SASSERT (r);
1118
- m_asts.push_back (ty);
1119
- m_asts.push_back (r);
1120
- m_datatype2nonrec_constructor.insert (ty, r);
1121
- return r;
1116
+ SASSERT (cd.first );
1117
+ return cd.first ;
1122
1118
}
1123
1119
1124
1120
/* *
1125
1121
\brief Return a constructor mk(T_1, ..., T_n) where
1126
1122
each T_i is not a datatype or it is a datatype t not in forbidden_set,
1127
1123
and get_non_rec_constructor_core(T_i, forbidden_set union { T_i })
1128
1124
*/
1129
- func_decl * util::get_non_rec_constructor_core (sort * ty, ptr_vector<sort> & forbidden_set) {
1125
+ util::cnstr_depth util::get_non_rec_constructor_core (sort * ty, ptr_vector<sort> & forbidden_set) {
1130
1126
// We must select a constructor c(T_1, ..., T_n):T such that
1131
1127
// 1) T_i's are not recursive
1132
1128
// If there is no such constructor, then we select one that
@@ -1135,32 +1131,22 @@ namespace datatype {
1135
1131
ptr_vector<func_decl> const & constructors = *get_datatype_constructors (ty);
1136
1132
unsigned sz = constructors.size ();
1137
1133
array_util autil (m);
1134
+ cnstr_depth result (nullptr , 0 );
1135
+ if (m_datatype2nonrec_constructor.find (ty, result))
1136
+ return result;
1138
1137
TRACE (" util_bug" , tout << " get-non-rec constructor: " << sort_ref (ty, m) << " \n " ;
1139
1138
tout << " forbidden: " ;
1140
1139
for (sort* s : forbidden_set) tout << sort_ref (s, m) << " " ;
1141
1140
tout << " \n " ;
1142
1141
tout << " constructors: " << sz << " \n " ;
1143
1142
for (func_decl* f : constructors) tout << func_decl_ref (f, m) << " \n " ;
1144
1143
);
1145
- // step 1)
1146
- unsigned start = ++m_start;
1147
- for (unsigned j = 0 ; j < sz; ++j) {
1148
- func_decl * c = constructors[(j + start) % sz];
1149
- TRACE (" util_bug" , tout << " checking " << sort_ref (ty, m) << " : " << func_decl_ref (c, m) << " \n " ;);
1150
- unsigned num_args = c->get_arity ();
1151
- unsigned i = 0 ;
1152
- for (; i < num_args && !is_datatype (autil.get_array_range_rec (c->get_domain (i))); i++);
1153
- if (i == num_args) {
1154
- TRACE (" util_bug" , tout << " found non-rec " << func_decl_ref (c, m) << " \n " ;);
1155
- return c;
1156
- }
1157
- }
1158
- // step 2)
1159
- for (unsigned j = 0 ; j < sz; ++j) {
1160
- func_decl * c = constructors[(j + start) % sz];
1161
- TRACE (" util_bug" , tout << " non_rec_constructor c: " << j << " " << func_decl_ref (c, m) << " \n " ;);
1144
+ unsigned min_depth = INT_MAX;
1145
+ for (func_decl * c : constructors) {
1146
+ TRACE (" util_bug" , tout << " non_rec_constructor c: " << func_decl_ref (c, m) << " \n " ;);
1162
1147
unsigned num_args = c->get_arity ();
1163
1148
unsigned i = 0 ;
1149
+ unsigned max_depth = 0 ;
1164
1150
for (; i < num_args; i++) {
1165
1151
sort * T_i = autil.get_array_range_rec (c->get_domain (i));
1166
1152
TRACE (" util_bug" , tout << " c: " << i << " " << sort_ref (T_i, m) << " \n " ;);
@@ -1173,17 +1159,26 @@ namespace datatype {
1173
1159
break ;
1174
1160
}
1175
1161
forbidden_set.push_back (T_i);
1176
- func_decl * nested_c = get_non_rec_constructor_core (T_i, forbidden_set);
1162
+ cnstr_depth nested_c = get_non_rec_constructor_core (T_i, forbidden_set);
1177
1163
SASSERT (forbidden_set.back () == T_i);
1178
1164
forbidden_set.pop_back ();
1179
- if (nested_c == nullptr )
1165
+ if (nested_c. first == nullptr )
1180
1166
break ;
1181
- TRACE (" util_bug" , tout << " nested_c: " << nested_c->get_name () << " \n " ;);
1167
+ TRACE (" util_bug" , tout << " nested_c: " << nested_c.first ->get_name () << " \n " ;);
1168
+ max_depth = std::max (nested_c.second + 1 , max_depth);
1169
+ }
1170
+ if (i == num_args && max_depth < min_depth) {
1171
+ result.first = c;
1172
+ result.second = max_depth;
1173
+ min_depth = max_depth;
1182
1174
}
1183
- if (i == num_args)
1184
- return c;
1185
1175
}
1186
- return nullptr ;
1176
+ if (result.first ) {
1177
+ m_asts.push_back (result.first );
1178
+ m_asts.push_back (ty);
1179
+ m_datatype2nonrec_constructor.insert (ty, result);
1180
+ }
1181
+ return result;
1187
1182
}
1188
1183
1189
1184
unsigned util::get_constructor_idx (func_decl * f) const {
0 commit comments