| 396 | } |
| 397 | |
| 398 | static expr preprocess(const Transform &t, const set<expr> &qvars0, |
| 399 | const set<expr> &undef_qvars, expr &&e) { |
| 400 | if (hit_half_memory_limit()) |
| 401 | return expr::mkForAll(qvars0, std::move(e)); |
| 402 | |
| 403 | // eliminate all quantified boolean vars; Z3 gets too slow with those |
| 404 | auto qvars = qvars0; |
| 405 | unsigned num_qvars_subst = 0; |
| 406 | for (auto I = qvars.begin(); I != qvars.end(); ) { |
| 407 | auto &var = *I; |
| 408 | if (!var.isBool()) { |
| 409 | ++I; |
| 410 | continue; |
| 411 | } |
| 412 | if (hit_half_memory_limit()) |
| 413 | break; |
| 414 | |
| 415 | expr t = e.subst(var, true); |
| 416 | if (!t.eq(e)) { |
| 417 | e = (t && e.subst(var, false)).simplify(); |
| 418 | ++num_qvars_subst; |
| 419 | } |
| 420 | I = qvars.erase(I); |
| 421 | |
| 422 | // Z3's subst is *super* slow; avoid exponential run-time |
| 423 | if (++num_qvars_subst > 9) |
| 424 | break; |
| 425 | } |
| 426 | |
| 427 | if (config::disable_undef_input || undef_qvars.empty() || |
| 428 | hit_half_memory_limit()) |
| 429 | return expr::mkForAll(qvars, std::move(e)); |
| 430 | |
| 431 | // manually instantiate undef masks |
| 432 | map<expr, expr> instances({ { std::move(e), true } }); |
| 433 | |
| 434 | for (auto &i : t.src.getInputs()) { |
| 435 | if (auto in = dynamic_cast<const Input*>(&i)) |
| 436 | instantiate_undef(in, instances, i.getType(), 0); |
| 437 | } |
| 438 | |
| 439 | expr insts(false); |
| 440 | for (auto &[e, v] : instances) { |
| 441 | insts |= expr::mkForAll(qvars, std::move(const_cast<expr&>(e))) && v; |
| 442 | } |
| 443 | return insts; |
| 444 | } |
| 445 | |
| 446 | |
| 447 | static expr |
no test coverage detected