bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def, bool & inv) const { // TODO: obsolete... we should move to collect_arith_macro_candidates arith_simplifier_plugin * as = get_arith_simp(); if (!m_manager.is_eq(n) && !as->is_le(n) && !as->is_ge(n)) return false; expr * lhs = to_app(n)->get_arg(0); expr * rhs = to_app(n)->get_arg(1); if (!as->is_numeral(rhs)) return false; inv = false; ptr_buffer<expr> args; expr * h = 0; unsigned lhs_num_args; expr * const * lhs_args; if (is_add(lhs)) { lhs_num_args = to_app(lhs)->get_num_args(); lhs_args = to_app(lhs)->get_args(); } else { lhs_num_args = 1; lhs_args = &lhs; } for (unsigned i = 0; i < lhs_num_args; i++) { expr * arg = lhs_args[i]; expr * neg_arg; if (h == 0 && is_macro_head(arg, num_decls) && !is_forbidden(to_app(arg)->get_decl()) && !poly_contains_head(lhs, to_app(arg)->get_decl(), arg)) { h = arg; } else if (h == 0 && as->is_times_minus_one(arg, neg_arg) && is_macro_head(neg_arg, num_decls) && !is_forbidden(to_app(neg_arg)->get_decl()) && !poly_contains_head(lhs, to_app(neg_arg)->get_decl(), arg)) { h = neg_arg; inv = true; } else { args.push_back(arg); } } if (h == 0) return false; head = to_app(h); expr_ref tmp(m_manager); as->mk_add(args.size(), args.c_ptr(), tmp); if (inv) as->mk_sub(tmp, rhs, def); else as->mk_sub(rhs, tmp, def); return true; }
/* ADD conversion for external command */ ref_t shadow_aconvert(shadow_mgr mgr, ref_t r) { if (do_ref(mgr)) /* Only applies when in pure CUDD mode */ return r; DdNode *n = get_ddnode(mgr, r); if (is_add(mgr, r)) { return r; } if (is_zdd(mgr, r)) { err(false, "Can't convert ADD to ZDD"); return REF_INVALID; } DdNode *an = aconvert(mgr, n); ref_t ar = dd2ref(an, IS_ADD); add_ref(mgr, ar, an); return ar; }
/* ZDD conversion for external command */ ref_t shadow_zconvert(shadow_mgr mgr, ref_t r) { if (do_ref(mgr)) /* Only applies when in pure CUDD mode */ return r; DdNode *n = get_ddnode(mgr, r); if (is_zdd(mgr, r)) { return r; } if (is_add(mgr, r)) { err(false, "Can't convert ADD to ZDD"); return REF_INVALID; } DdNode *zn = zconvert(mgr, n); ref_t zr = dd2ref(zn, IS_ZDD); add_ref(mgr, zr, zn); return zr; }
/** \brief Return true if n contains f. The method ignores the sub-expression \c exception. \remark n is a "polynomial". */ bool macro_util::poly_contains_head(expr * n, func_decl * f, expr * exception) const { unsigned num_args; expr * const * args; if (is_add(n)) { num_args = to_app(n)->get_num_args(); args = to_app(n)->get_args(); } else { num_args = 1; args = &n; } for (unsigned i = 0; i < num_args; i++) { expr * arg = args[i]; if (arg != exception && occurs(f, arg)) return true; } return false; }
int is_redir(t_lex *lex, t_token_ht *token_ht, int i) { if (lex->line[i] == '>' && lex->line[i + 1] == '>') i = is_add(lex, token_ht, i); else if (lex->line[i] == '<' && lex->line[i + 1] == '<') i = is_heredoc(lex, token_ht, i); else if (lex->line[i] == '<' && lex->line[i - 1] != '<') i = is_in(lex, token_ht, i); else if (lex->line[i] == '>' && lex->line[i - 1] != '>') i = is_replace(lex, token_ht, i); else return (0); if (lex->fd[0] != -1 || lex->fd[1] != -1) { lex->fd[0] = -1; lex->fd[0] = -1; } return (i); }
/** \brief Return true if m is a wellformed monomial. */ bool poly_simplifier_plugin::wf_monomial(expr * m) const { SASSERT(!is_add(m)); if (is_mul(m)) { app * curr = to_app(m); expr * pp = 0; if (is_numeral(curr->get_arg(0))) pp = curr->get_arg(1); else pp = curr; if (is_mul(pp)) { for (unsigned i = 0; i < to_app(pp)->get_num_args(); i++) { expr * arg = to_app(pp)->get_arg(i); CTRACE("wf_monomial_bug", is_mul(arg), tout << "m: " << mk_ismt2_pp(m, m_manager) << "\n"; tout << "pp: " << mk_ismt2_pp(pp, m_manager) << "\n"; tout << "arg: " << mk_ismt2_pp(arg, m_manager) << "\n"; tout << "i: " << i << "\n"; ); SASSERT(!is_mul(arg)); SASSERT(!is_numeral(arg)); } } }
/* Compute negation. Creates CUDD reference. For ZDDs, records as reference */ ref_t shadow_negate(shadow_mgr mgr, ref_t a) { ref_t r = REF_INVALID; if (REF_IS_INVALID(a)) return a; if (do_ref(mgr)) r = REF_NEGATE(a); else { DdNode *an = get_ddnode(mgr, a); if (is_zdd(mgr, a)) { DdNode *zone = Cudd_ReadZddOne(mgr->bdd_manager, 0); reference_dd(mgr, zone); DdNode *ann = Cudd_zddDiff(mgr->bdd_manager, zone, an); reference_dd(mgr, ann); unreference_dd(mgr, zone, IS_ZDD); r = dd2ref(ann, IS_ZDD); // For ZDDs, don't already have negated values recorded add_ref(mgr, r, ann); } else if (is_add(mgr, a)) { DdNode *ann = Cudd_addCmpl(mgr->bdd_manager, an); reference_dd(mgr, ann); r = dd2ref(ann, IS_ADD); // For ADDs, don't already have negated values recorded add_ref(mgr, r, ann); } else { DdNode *ann = Cudd_Not(an); reference_dd(mgr, ann); r = dd2ref(ann, IS_BDD); } } #if RPT >= 5 char buf[24], nbuf[24]; shadow_show(mgr, a, buf); shadow_show(mgr, r, nbuf); report(5, "Negated %s to get %s", buf, nbuf); #endif return r; }
ref_t shadow_xor(shadow_mgr mgr, ref_t aref, ref_t bref) { ref_t r = REF_ZERO; dd_type_t dtype = IS_BDD; bool za = is_zdd(mgr, aref); bool zb = is_zdd(mgr, bref); bool aa = is_add(mgr, aref); bool ab = is_add(mgr, bref); if (mgr->do_cudd && mgr->nzvars > 0) { /* Check whether arguments are ZDDs */ DdNode *an = get_ddnode(mgr, aref); DdNode *bn = get_ddnode(mgr, bref); DdNode *rn; if (za || zb) { if (aa || ab) { err(false, "Can't mix ADDs and ZDDs"); } dtype = IS_ZDD; /* Make sure they're both ZDDs */ if (!za) { an = zconvert(mgr, an); } if (!zb) { bn = zconvert(mgr, bn); } rn = Cudd_zddSymmetricDiff(mgr->bdd_manager, an, bn); reference_dd(mgr, rn); r = dd2ref(rn, IS_ZDD); add_ref(mgr, r, rn); if (!za) unreference_dd(mgr, an, IS_ZDD); if (!zb) unreference_dd(mgr, bn, IS_ZDD); } } if (mgr->do_cudd) { /* Check whether arguments are ADDs */ DdNode *an = get_ddnode(mgr, aref); DdNode *bn = get_ddnode(mgr, bref); DdNode *rn; if (aa || ab) { dtype = IS_ADD; /* Make sure they're both ADDs */ if (!aa) { an = aconvert(mgr, an); } if (!ab) { bn = aconvert(mgr, bn); } rn = Cudd_addApply(mgr->bdd_manager, Cudd_addXor, an, bn); reference_dd(mgr, rn); r = dd2ref(rn, IS_ADD); add_ref(mgr, r, rn); if (!aa) unreference_dd(mgr, an, IS_ADD); if (!ab) unreference_dd(mgr, bn, IS_ADD); } } if (dtype == IS_BDD) r = shadow_ite(mgr, aref, shadow_negate(mgr, bref), bref); #if RPT >= 4 char buf1[24], buf2[24], buf3[24]; shadow_show(mgr, aref, buf1); shadow_show(mgr, bref, buf2); shadow_show(mgr, r, buf3); report(4, "%s %sXOR %s --> %s", buf1, dtype == IS_ZDD ? "Z" : dtype == IS_ADD ? "A" : "" , buf2, buf3); #endif return r; }
ref_t shadow_ite(shadow_mgr mgr, ref_t iref, ref_t tref, ref_t eref) { DdNode *in = get_ddnode(mgr, iref); DdNode *tn = get_ddnode(mgr, tref); DdNode *en = get_ddnode(mgr, eref); DdNode *n = NULL; ref_t r = REF_INVALID; dd_type_t dtype = IS_BDD; if (mgr->do_local) { r = ref_ite(mgr->ref_mgr, iref, tref, eref); } if (mgr->do_dist) { ref_t rdist = dist_ite(mgr->ref_mgr, iref, tref, eref); if (mgr->do_local) { if (!check_refs(mgr, r, rdist)) { return REF_INVALID; } } else { r = rdist; } } if (mgr->do_cudd) { if (mgr->nzvars > 0) { bool zi = is_zdd(mgr, iref); bool zt = is_zdd(mgr, tref); bool ze = is_zdd(mgr, eref); if (zi || zt || ze) { dtype = IS_ZDD; if (is_add(mgr, iref) || is_add(mgr, tref) || is_add(mgr, eref)) { err(false, "Can't mix ADDs with ZDDs"); } if (!zi) { in = zconvert(mgr, in); } if (!zt) { tn = zconvert(mgr, tn); } if (!ze) { en = zconvert(mgr, en); } n = Cudd_zddIte(mgr->bdd_manager, in, tn, en); reference_dd(mgr, n); if (!zi) unreference_dd(mgr, in, IS_ZDD); if (!zt) unreference_dd(mgr, tn, IS_ZDD); if (!ze) unreference_dd(mgr, en, IS_ZDD); } } { bool ai = is_add(mgr, iref); bool at = is_add(mgr, tref); bool ae = is_add(mgr, eref); if (ai || at || ae) { dtype = IS_ADD; if (!ai) { in = aconvert(mgr, in); } if (!at) { tn = aconvert(mgr, tn); } if (!ae) { en = aconvert(mgr, en); } n = Cudd_addIte(mgr->bdd_manager, in, tn, en); reference_dd(mgr, n); if (!ai) unreference_dd(mgr, in, IS_ADD); if (!at) unreference_dd(mgr, tn, IS_ADD); if (!ae) unreference_dd(mgr, en, IS_ADD); } } if (dtype == IS_BDD) { n = Cudd_bddIte(mgr->bdd_manager, in, tn, en); reference_dd(mgr, n); } } else { n = ref2dd(mgr, r); } if (!do_ref(mgr)) r = dd2ref(n, dtype); add_ref(mgr, r, n); return r; }