@@ -51,11 +51,10 @@ bv2fpa_converter::bv2fpa_converter(ast_manager & m, fpa2bv_converter & conv) :
51
51
for (auto const & kv : conv.m_uf2bvuf ) {
52
52
m_uf2bvuf.insert (kv.m_key , kv.m_value );
53
53
m.inc_ref (kv.m_key );
54
- m.inc_ref (kv.m_value .first );
55
- m.inc_ref (kv.m_value .second );
54
+ m.inc_ref (kv.m_value );
56
55
}
57
56
for (auto const & kv : conv.m_min_max_ufs ) {
58
- m_specials .insert (kv.m_key , kv.m_value );
57
+ m_min_max_specials .insert (kv.m_key , kv.m_value );
59
58
m.inc_ref (kv.m_key );
60
59
m.inc_ref (kv.m_value .first );
61
60
m.inc_ref (kv.m_value .second );
@@ -67,16 +66,15 @@ bv2fpa_converter::~bv2fpa_converter() {
67
66
dec_ref_map_key_values (m, m_rm_const2bv);
68
67
for (auto const & kv : m_uf2bvuf) {
69
68
m.dec_ref (kv.m_key );
70
- m.dec_ref (kv.m_value .first );
71
- m.dec_ref (kv.m_value .second );
69
+ m.dec_ref (kv.m_value );
72
70
}
73
- for (auto const & kv : m_specials ) {
71
+ for (auto const & kv : m_min_max_specials ) {
74
72
m.dec_ref (kv.m_key );
75
73
m.dec_ref (kv.m_value .first );
76
74
m.dec_ref (kv.m_value .second );
77
75
}
78
76
m_uf2bvuf.reset ();
79
- m_specials .reset ();
77
+ m_min_max_specials .reset ();
80
78
}
81
79
82
80
expr_ref bv2fpa_converter::convert_bv2fp (sort * s, expr * sgn, expr * exp, expr * sig) {
@@ -191,7 +189,7 @@ expr_ref bv2fpa_converter::convert_bv2rm(model_core * mc, expr * val) {
191
189
192
190
expr_ref bv2fpa_converter::rebuild_floats (model_core * mc, sort * s, expr * e) {
193
191
expr_ref result (m);
194
- TRACE (" bv2fpa " , tout << " rebuild floats in " << mk_ismt2_pp (s, m) << " for " ;
192
+ TRACE (" bv2fpa_rebuild " , tout << " rebuild floats in " << mk_ismt2_pp (s, m) << " for " ;
195
193
if (e) tout << mk_ismt2_pp (e, m);
196
194
else tout << " nil" ;
197
195
tout << std::endl; );
@@ -288,13 +286,23 @@ func_interp * bv2fpa_converter::convert_func_interp(model_core * mc, func_decl *
288
286
expr_ref ft_fres = rebuild_floats (mc, rng, to_app (bv_fres));
289
287
m_th_rw (ft_fres);
290
288
TRACE (" bv2fpa" ,
289
+ tout << " func_interp entry #" << i << " :" << std::endl;
290
+ tout << " (" << bv_f->get_name ();
291
+ for (unsigned i = 0 ; i < bv_f->get_arity (); i++)
292
+ tout << " " << mk_ismt2_pp (bv_args[i], m);
293
+ tout << " ) = " << mk_ismt2_pp (bv_fres, m) << std::endl;
294
+ tout << " --> " << std::endl;
295
+ tout << " (" << f->get_name ();
291
296
for (unsigned i = 0 ; i < new_args.size (); i++)
292
- tout << mk_ismt2_pp (bv_args[i], m) << " == " <<
293
- mk_ismt2_pp (new_args[i], m) << std::endl;
294
- tout << mk_ismt2_pp (bv_fres, m) << " == " << mk_ismt2_pp (ft_fres, m) << std::endl;);
297
+ tout << " " << mk_ismt2_pp (new_args[i], m);
298
+ tout << " ) = " << mk_ismt2_pp (ft_fres, m) << std::endl;);
295
299
func_entry * fe = result->get_entry (new_args.c_ptr ());
296
- if (fe == nullptr )
297
- result->insert_new_entry (new_args.c_ptr (), ft_fres);
300
+ if (fe == nullptr ) {
301
+ // Avoid over-specification of a partially interpreted theory function
302
+ if (f->get_family_id () != m_fpa_util.get_family_id () ||
303
+ m_fpa_util.is_considered_uninterpreted (f, new_args.size (), new_args.c_ptr ()))
304
+ result->insert_new_entry (new_args.c_ptr (), ft_fres);
305
+ }
298
306
else {
299
307
// The BV model may have multiple equivalent entries using different
300
308
// representations of NaN. We can only keep one and we check that
@@ -309,6 +317,7 @@ func_interp * bv2fpa_converter::convert_func_interp(model_core * mc, func_decl *
309
317
if (bv_els) {
310
318
expr_ref ft_els = rebuild_floats (mc, rng, bv_els);
311
319
m_th_rw (ft_els);
320
+ TRACE (" bv2fpa" , tout << " else=" << mk_ismt2_pp (ft_els, m) << std::endl;);
312
321
result->set_else (ft_els);
313
322
}
314
323
}
@@ -398,7 +407,7 @@ void bv2fpa_converter::convert_rm_consts(model_core * mc, model_core * target_mo
398
407
}
399
408
400
409
void bv2fpa_converter::convert_min_max_specials (model_core * mc, model_core * target_model, obj_hashtable<func_decl> & seen) {
401
- for (auto const & kv : m_specials ) {
410
+ for (auto const & kv : m_min_max_specials ) {
402
411
func_decl * f = kv.m_key ;
403
412
app * pn_cnst = kv.m_value .first ;
404
413
app * np_cnst = kv.m_value .second ;
@@ -432,8 +441,7 @@ void bv2fpa_converter::convert_min_max_specials(model_core * mc, model_core * ta
432
441
void bv2fpa_converter::convert_uf2bvuf (model_core * mc, model_core * target_model, obj_hashtable<func_decl> & seen) {
433
442
for (auto const & kv : m_uf2bvuf) {
434
443
func_decl * f = kv.m_key ;
435
- func_decl* f_uf = kv.m_value .first ;
436
- expr* f_def = kv.m_value .second ;
444
+ func_decl * f_uf = kv.m_value ;
437
445
seen.insert (f_uf);
438
446
439
447
if (f->get_arity () == 0 )
@@ -454,29 +462,22 @@ void bv2fpa_converter::convert_uf2bvuf(model_core * mc, model_core * target_mode
454
462
}
455
463
}
456
464
else if (f->get_family_id () == m_fpa_util.get_fid ()) {
457
- if (f_def) {
458
- func_interp* fi = alloc (func_interp, m, f->get_arity ());
459
- expr_ref def = rebuild_floats (mc, f->get_range (), to_app (f_def));
460
- fi->set_else (def);
461
- SASSERT (m.get_sort (def) == f->get_range ());
462
- target_model->register_decl (f, fi);
463
- func_interp* fj = mc->get_func_interp (f_uf);
464
- if (fj) {
465
- target_model->register_decl (f_uf, fj->copy ());
466
- }
467
- continue ;
468
- }
469
-
465
+ // kv.m_value contains the model for the unspecified cases of kv.m_key in terms of bit-vectors.
466
+ // convert_func_interp rebuilds a func_interp on floats.
470
467
471
468
// f is a floating point function: f(x,y) : Float
472
469
// f_uf is a bit-vector function: f_uf(xB,yB) : BitVec
473
470
// then there is f_def: f_Bv(xB, yB) := if(range(xB),.., f_uf(xB,yB))
474
471
// f(x,y) := to_float(if(range(to_bv(x)), ... f_uf(to_bv(xB), to_bv(yB)))) - not practical
475
- // := if(range_fp(x), ...., to_float(f_uf(...)) - approach
476
-
477
- target_model->register_decl (f, convert_func_interp (mc, f, f_uf));
472
+ // := if(range_fp(x), ...., to_float(f_uf(...)) - approach (via fpa_util::is_considered_uninterpreted)
473
+
474
+ func_interp *fi = convert_func_interp (mc, f, f_uf);
475
+ if (fi->num_entries () > 0 || fi->get_else () != nullptr )
476
+ target_model->register_decl (f, fi);
478
477
}
479
478
}
479
+
480
+ TRACE (" bv2fpa" , tout << " Target model: " << *target_model; );
480
481
}
481
482
482
483
void bv2fpa_converter::display (std::ostream & out) {
@@ -496,9 +497,9 @@ void bv2fpa_converter::display(std::ostream & out) {
496
497
const symbol & n = kv.m_key ->get_name ();
497
498
out << " \n (" << n << " " ;
498
499
unsigned indent = n.size () + 4 ;
499
- out << mk_ismt2_pp (kv.m_value . first , m, indent) << " )" ;
500
+ out << mk_ismt2_pp (kv.m_value , m, indent) << " )" ;
500
501
}
501
- for (auto const & kv : m_specials ) {
502
+ for (auto const & kv : m_min_max_specials ) {
502
503
const symbol & n = kv.m_key ->get_name ();
503
504
out << " \n (" << n << " " ;
504
505
unsigned indent = n.size () + 4 ;
@@ -525,22 +526,19 @@ bv2fpa_converter * bv2fpa_converter::translate(ast_translation & translator) {
525
526
}
526
527
for (auto const & kv : m_uf2bvuf) {
527
528
func_decl * k = translator (kv.m_key );
528
- func_decl * v = translator (kv.m_value .first );
529
- expr* d = translator (kv.m_value .second );
530
- res->m_uf2bvuf .insert (k, std::make_pair (v, d));
529
+ func_decl * v = translator (kv.m_value );
530
+ res->m_uf2bvuf .insert (k, v);
531
531
translator.to ().inc_ref (k);
532
532
translator.to ().inc_ref (v);
533
- translator.to ().inc_ref (d);
534
533
}
535
- for (auto const & kv : m_specials ) {
534
+ for (auto const & kv : m_min_max_specials ) {
536
535
func_decl * k = translator (kv.m_key );
537
536
app * v1 = translator (kv.m_value .first );
538
537
app * v2 = translator (kv.m_value .second );
539
- res->m_specials .insert (k, std::pair<app*, app*>(v1, v2));
538
+ res->m_min_max_specials .insert (k, std::pair<app*, app*>(v1, v2));
540
539
translator.to ().inc_ref (k);
541
540
translator.to ().inc_ref (v1);
542
541
translator.to ().inc_ref (v2);
543
542
}
544
543
return res;
545
544
}
546
-
0 commit comments