inline order::result lpo::compare_core(expr_offset s, expr_offset t, unsigned depth) { s = find(s); t = find(t); if (max_depth(depth)) return UNKNOWN; if (is_var(s.get_expr())) return s == t ? EQUAL : UNCOMPARABLE; else if (is_var(t.get_expr())) return occurs(t, s) ? GREATER : UNCOMPARABLE; else { func_decl * f = to_app(s.get_expr())->get_decl(); func_decl * g = to_app(t.get_expr())->get_decl(); if (f_greater(f, g)) return dominates_args(s, t, depth) ? GREATER : NOT_GTEQ; else if (f != g) return arg_dominates_expr(s, t, depth) ? GREATER : NOT_GTEQ; else { result r = lex_compare(s, t, depth); if (r == GREATER) { if (dominates_args(s, t, depth)) return GREATER; } else if (r == EQUAL) return EQUAL; return to_app(s.get_expr())->get_num_args() > 1 && arg_dominates_expr(s, t, depth) ? GREATER : NOT_GTEQ; } } }
static void initng_s_launch(s_event * event) { s_event_launch_data *data; assert(event->event_type == &EVENT_LAUNCH); assert(event->data); data = event->data; assert(data->service); assert(data->service->name); assert(data->process); assert(data->exec_name); D_("service: %s, process: %s\n", data->service->name, data->process->pt->name); if (is_var(&EXECS, data->exec_name, data->service)) { if (simple_exec(data->service, data->process)) { event->status = HANDLED; return; } } if (is_var(&EXEC, data->exec_name, data->service)) { if (simple_run(data->service, data->process)) event->status = HANDLED; } }
void variable_intersection::populate_self(const app * a) { SASSERT(is_uninterp(a)); //TODO: optimize quadratic complexity //TODO: optimize number of checks when variable occurs multiple times unsigned arity = a->get_num_args(); for(unsigned i1=0; i1<arity; i1++) { expr * e1=a->get_arg(i1); if(is_var(e1)) { var* v1=to_var(e1); for(unsigned i2=i1+1; i2<arity; i2++) { expr * e2=a->get_arg(i2); if(!is_var(e2)) { continue; } var* v2=to_var(e2); if(v1->get_idx()==v2->get_idx()) { add_pair(i1, i2); } } } else { SASSERT(is_app(e1)); app * c1 = to_app(e1); SASSERT(c1->get_num_args()==0); //c1 must be a constant m_const_indexes.push_back(i1); m_consts.push_back(c1); SASSERT(m_const_indexes.size()==m_consts.size()); } } }
/** \brief Find bounds of the form (<= x k) (<= (+ x (* -1 y)) k) (<= (+ x (* -1 t)) k) (<= (+ t (* -1 x)) k) x and y are a bound variables, t is a ground term and k is a numeral It also detects >=, and the atom can be negated. */ bool elim_bounds::is_bound(expr * n, var * & lower, var * & upper) { upper = 0; lower = 0; bool neg = false; if (m_manager.is_not(n)) { n = to_app(n)->get_arg(0); neg = true; } bool le = false; if (m_util.is_le(n)) { SASSERT(m_util.is_numeral(to_app(n)->get_arg(1))); n = to_app(n)->get_arg(0); le = true; } else if (m_util.is_ge(n)) { SASSERT(m_util.is_numeral(to_app(n)->get_arg(1))); n = to_app(n)->get_arg(0); le = false; } else { return false; } if (neg) le = !le; if (is_var(n)) { upper = to_var(n); } else if (m_util.is_add(n) && to_app(n)->get_num_args() == 2) { expr * arg1 = to_app(n)->get_arg(0); expr * arg2 = to_app(n)->get_arg(1); if (is_var(arg1)) upper = to_var(arg1); else if (!is_ground(arg1)) return false; rational k; bool is_int; if (m_util.is_mul(arg2) && m_util.is_numeral(to_app(arg2)->get_arg(0), k, is_int) && k.is_minus_one()) { arg2 = to_app(arg2)->get_arg(1); if (is_var(arg2)) lower = to_var(arg2); else if (!is_ground(arg2)) return false; // not supported } else { return false; // not supported } } else { return false; } if (!le) std::swap(upper, lower); return true; }
void trace_expand_select(cell_t *c, cell_t *x, type_t t) { while(reduce(&x, t)) { if(!is_var(x)) trace(x, 0, tt_force); trace(c, x, tt_select); if(!is_var(x)) break; x = x->alt; } }
/** \brief Find bounds of the form (<= x k) (<= (+ x (* -1 y)) k) (<= (+ x (* -1 t)) k) (<= (+ t (* -1 x)) k) x and y are a bound variables, t is a ground term and k is a numeral It also detects >=, and the atom can be negated. */ bool elim_bounds_cfg::is_bound(expr * n, var * & lower, var * & upper) { upper = nullptr; lower = nullptr; bool neg = false; if (m.is_not(n)) { n = to_app(n)->get_arg(0); neg = true; } expr* l = nullptr, *r = nullptr; bool le = false; if (m_util.is_le(n, l, r) && m_util.is_numeral(r)) { n = l; le = true; } else if (m_util.is_ge(n, l, r) && m_util.is_numeral(r)) { n = l; le = false; } else { return false; } if (neg) le = !le; if (is_var(n)) { upper = to_var(n); } else if (m_util.is_add(n, l, r)) { expr * arg1 = l; expr * arg2 = r; if (is_var(arg1)) upper = to_var(arg1); else if (!is_ground(arg1)) return false; rational k; bool is_int; if (m_util.is_mul(arg2) && m_util.is_numeral(to_app(arg2)->get_arg(0), k, is_int) && k.is_minus_one()) { arg2 = to_app(arg2)->get_arg(1); if (is_var(arg2)) lower = to_var(arg2); else if (!is_ground(arg2)) return false; // not supported } else { return false; // not supported } } else { return false; } if (!le) std::swap(upper, lower); return true; }
/** * tests helper functions is_var() and is_op() */ static char * test_helpers() { char tmp[VAR_LENGTH+1], str[LINE_LENGTH]; char * trimmed; int ret, i; printf("Testing %s\n", __FUNCTION__); /* test is_var() from A-Z */ for (i='A'; i<='Z'; i++) { tmp[0] = i; tmp[1] = '\0'; ret = is_var(tmp); mu_assert("error, ret != 1", ret == 1); } /* test bogus inputs */ /* small letter */ tmp[0] = 'a'; ret = is_var(tmp); mu_assert("error, ret != 0", ret == 0); /* number */ tmp[0] = '1'; ret = is_var(tmp); mu_assert("error, ret != 0", ret == 0); /* test is_op */ tmp[0] = '+'; ret = is_op(tmp); mu_assert("error, ret != 1", ret == 1); tmp[0] = '-'; ret = is_op(tmp); mu_assert("error, ret != 1", ret == 1); tmp[0] = '*'; ret = is_op(tmp); mu_assert("error, ret != 1", ret == 1); tmp[0] = '/'; ret = is_op(tmp); mu_assert("error, ret != 1", ret == 1); /* test bogus inputs */ tmp[0] = '='; ret = is_op(tmp); mu_assert("error, ret != 0", ret == 0); tmp[0] = '^'; ret = is_op(tmp); mu_assert("error, ret != 0", ret == 0); tmp[0] = '$'; ret = is_op(tmp); mu_assert("error, ret != 0", ret == 0); /* test trim_space() */ strcpy(str, "\t\tFD 30 \t\t "); trimmed = trim_space(str); mu_assert("error, trimmed != \"FD 30\"", strsame(trimmed, "FD 30")); strcpy(str, " \t \tDO A FROM 1 TO 8 { \t\t "); trimmed = trim_space(str); mu_assert("error, trimmed != \"DO A FROM 1 TO 8 {\"", strsame(trimmed, "DO A FROM 1 TO 8 {")); return 0; }
bool matcher::operator()(expr * e1, expr * e2, substitution & s) { reset(); m_subst = &s; m_todo.push_back(expr_pair(e1, e2)); while (!m_todo.empty()) { expr_pair const & p = m_todo.back(); // if (m_cache.contains(p)) { // m_todo.pop_back(); // continue; // } if (is_var(p.first)) { expr_offset r; if (m_subst->find(to_var(p.first), 0, r)) { if (r.get_expr() != p.second) return false; } else { m_subst->insert(to_var(p.first), 0, expr_offset(p.second, 1)); } m_todo.pop_back(); continue; } if (is_var(p.second)) return false; if (!is_app(p.first)) return false; if (!is_app(p.second)) return false; app * n1 = to_app(p.first); app * n2 = to_app(p.second); if (n1->get_decl() != n2->get_decl()) return false; unsigned num_args1 = n1->get_num_args(); if (num_args1 != n2->get_num_args()) return false; m_todo.pop_back(); if (num_args1 == 0) continue; // m_cache.insert(p); unsigned j = num_args1; while (j > 0) { --j; m_todo.push_back(expr_pair(n1->get_arg(j), n2->get_arg(j))); } } return true; }
/** \brief Little HACK for simplifying injectivity axioms \remark It is not covering all possible cases. */ bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result) { expr * n = q->get_expr(); if (q->is_forall() && m.is_or(n) && to_app(n)->get_num_args() == 2) { expr * arg1 = to_app(n)->get_arg(0); expr * arg2 = to_app(n)->get_arg(1); if (m.is_not(arg2)) std::swap(arg1, arg2); if (m.is_not(arg1) && m.is_eq(to_app(arg1)->get_arg(0)) && m.is_eq(arg2)) { expr * app1 = to_app(to_app(arg1)->get_arg(0))->get_arg(0); expr * app2 = to_app(to_app(arg1)->get_arg(0))->get_arg(1); expr * var1 = to_app(arg2)->get_arg(0); expr * var2 = to_app(arg2)->get_arg(1); if (is_app(app1) && is_app(app2) && to_app(app1)->get_decl() == to_app(app2)->get_decl() && to_app(app1)->get_num_args() == to_app(app2)->get_num_args() && to_app(app1)->get_family_id() == null_family_id && to_app(app1)->get_num_args() > 0 && is_var(var1) && is_var(var2) && var1 != var2) { app * f1 = to_app(app1); app * f2 = to_app(app2); bool found_vars = false; unsigned num = f1->get_num_args(); unsigned idx = UINT_MAX; unsigned num_vars = 1; for (unsigned i = 0; i < num; i++) { expr * c1 = f1->get_arg(i); expr * c2 = f2->get_arg(i); if (!is_var(c1) && !is_uninterp_const(c1)) return false; if ((c1 == var1 && c2 == var2) || (c1 == var2 && c2 == var1)) { if (found_vars) return false; found_vars = true; idx = i; } else if (c1 == c2 && c1 != var1 && c1 != var2) { if (is_var(c1)) { ++num_vars; } } else { return false; } } if (found_vars && !has_free_vars(q)) { TRACE("inj_axiom", tout << "Cadidate for simplification:\n" << mk_ll_pp(q, m) << mk_pp(app1, m) << "\n" << mk_pp(app2, m) << "\n" << mk_pp(var1, m) << "\n" << mk_pp(var2, m) << "\nnum_vars: " << num_vars << "\n";);
unsigned get_bound_arg_count(app * lit, const var_idx_set & bound_vars) { unsigned res = 0; unsigned n = lit->get_num_args(); for (unsigned i = 0; i < n; i++) { const expr * arg = lit->get_arg(i); if (!is_var(arg) || bound_vars.contains(to_var(arg)->get_idx())) { SASSERT(is_var(arg) || is_app(arg)); SASSERT(!is_app(arg) || to_app(arg)->get_num_args()==0); res++; } } return res; }
void complex_literal_selection::operator()(clause * cls) { // look for x != y unsigned num = cls->get_num_literals(); for (unsigned i = 0; i < num; i++) { literal & l = cls->get_literal(i); if (l.sign() && m_manager.is_eq(l.atom()) && is_var(to_app(l.atom())->get_arg(0)) && is_var(to_app(l.atom())->get_arg(1))) { cls->select_literal(i); return; } } // look for min ground neg literal bool found = false; unsigned target = UINT_MAX; unsigned best_count = UINT_MAX; for (unsigned i = 0; i < num; i++) { literal & l = cls->get_literal(i); if (l.sign() && is_ground(l.atom())) { unsigned count = get_symbol_count(l.atom()); if (count < best_count) { found = true; target = i; best_count = count; } } } if (found) { cls->select_literal(target); return; } diff_literal_selection::operator()(cls); }
// called by the arithmetic expression statements. // this function determines whether a parameter variable is a value or a variable name // then returns the appropriate value. // used by the arithmetic operation statements int ProgramState::get_var_value(std::string name) { if (is_var(name)) // if it's a variable return getVar(name); else { // if it's not a variable return atoi(name.c_str()); } }
bool is_horn(expr* n) { expr* n1, *n2; while (is_forall(n)) n = to_quantifier(n)->get_expr(); if (m.is_implies(n, n1, n2) && is_predicate(n2)) { if (is_var(n1)) { return true; } if (is_quantifier(n1)) { return false; } app* a1 = to_app(n1); if (m.is_and(a1)) { for (unsigned i = 0; i < a1->get_num_args(); ++i) { if (!is_predicate(a1->get_arg(i)) && contains_predicate(a1->get_arg(i))) { return false; } } } else if (!is_predicate(a1) && contains_predicate(a1)) { return false; } return true; } return false; }
void *FliValueObjHdl::get_sub_hdl(int index) { if (!m_indexable) return NULL; if (m_sub_hdls == NULL) { if (is_var()) { m_sub_hdls = (void **)mti_GetVarSubelements(get_handle<mtiVariableIdT>(), NULL); } else { m_sub_hdls = (void **)mti_GetSignalSubelements(get_handle<mtiSignalIdT>(), NULL); } } int idx; if (m_range_left > m_range_right) { idx = m_range_left - index; } else { idx = index - m_range_left; } if (idx < 0 || idx >= m_num_elems) return NULL; else return m_sub_hdls[idx]; }
void unifier::save_var(expr_offset const & p, expr_offset const & t) { expr * n = p.get_expr(); if (is_var(n)) { unsigned off = p.get_offset(); m_subst->insert(to_var(n)->get_idx(), off, t); } }
void ft_setenv(t_env *env, char **sa) { int k; int l; l = 1; if (ft_strchr(sa[l], '=') == NULL) { ft_putstr(E_MESS09); return ; } k = 0; while (sa[l] != NULL) { while (E_EN[k] != NULL && !(is_var(E_EN[k], sa[l]))) k++; if (k > 100) { ft_putstr(E_MESS07); return ; } else if (ft_strchr(sa[l], '=') == NULL) do_command(env, sa[l]); else E_EN[k] = ft_strdup(sa[l]); l++; } }
bool func_ift(cell_t **cp, type_rep_t t) { cell_t *c = clear_ptr(*cp, 3); alt_set_t alt_set = 0; if(!reduce_arg(c, 0, &alt_set, T_INT)) goto fail; clear_flags(c); if(c->arg[0]->val[0] > 1) goto fail; if(is_var(c->arg[0])) { drop(c->arg[0]); // need to add assertions cell_t *res = id(c->arg[1]); res->alt = id(c->arg[2]); store_lazy(cp, c, res); // *** } else if(c->arg[0]->val[0]) { drop(c->arg[0]); drop(c->arg[2]); store_lazy(cp, c, c->arg[1]); } else { drop(c->arg[0]); drop(c->arg[1]); store_lazy(cp, c, c->arg[2]); } return false; fail: fail(cp); return false; }
void mk_new_rule_tail(ast_manager & m, app * pred, var_idx_set const & non_local_vars, unsigned & next_idx, varidx2var_map & varidx2var, sort_ref_buffer & new_rule_domain, expr_ref_buffer & new_rule_args, app_ref & new_pred) { expr_ref_buffer new_args(m); unsigned n = pred->get_num_args(); for (unsigned i = 0; i < n; i++) { expr * arg = pred->get_arg(i); if (m.is_value(arg)) { new_args.push_back(arg); } else { SASSERT(is_var(arg)); int vidx = to_var(arg)->get_idx(); var * new_var = 0; if (!varidx2var.find(vidx, new_var)) { new_var = m.mk_var(next_idx, to_var(arg)->get_sort()); next_idx++; varidx2var.insert(vidx, new_var); if (non_local_vars.contains(vidx)) { // other predicates used this variable... so it should be in the domain of the filter new_rule_domain.push_back(to_var(arg)->get_sort()); new_rule_args.push_back(new_var); } } SASSERT(new_var != 0); new_args.push_back(new_var); } } new_pred = m.mk_app(pred->get_decl(), new_args.size(), new_args.c_ptr()); }
void expr_context_simplifier::reduce_rec(expr * m, expr_ref & result) { // // reduce expr in context evaluation. // bool polarity; if (m_context.find(m, polarity)) { result = polarity ? m_manager.mk_true() : m_manager.mk_false(); } else if (m_mark.is_marked(m) && !m_manager.is_not(m)) { result = m; } else if (is_quantifier(m)) { reduce_rec(to_quantifier(m), result); m_mark.mark(m, true); } else if (is_app(m)) { reduce_rec(to_app(m), result); m_mark.mark(m, true); } else if (is_var(m)) { result = m; m_mark.mark(m, true); } else { UNREACHABLE(); result = m; } }
void print_opnd_type(Opnd o) { if(is_reg(o)) { if(is_hard_reg(o)) { std::cout << "(is hard reg)"; } else if(is_virtual_reg(o)) { std::cout << "(is virtual reg)[$vr"<<get_reg(o)<<"]"; } else { std::cout << "(is undeterminate reg)"; } } else if(is_immed(o)) { if(is_immed_integer(o)) { std::cout << "(is immed integer)"; } else if(is_immed_string(o)) { std::cout << "(is immed string)"; } else { std::cout << "(is undeterminate immed)"; } } else if(is_addr(o)) { if(is_addr_sym(o)) { FormattedText ft; Sym *symbol = get_sym(o); symbol->print(ft); char* addr_name; addr_name = (char*)(symbol->get_name()).c_str(); std::cout << "(is addr sym)["<<addr_name<<"]"; } else if(is_addr_exp(o)) { std::cout << "(is addr exp)"; } else { std::cout << "(is undeterminate addr)"; } } else if(is_var(o)) { FormattedText ft; VarSym *vsym = get_var(o); vsym->print(ft); char* var_name; var_name = (char*)(vsym->get_name()).c_str(); std::cout << "(is var)["<<var_name<<"]"; } else if(is_null(o)) { std::cout << "(is null)"; } else { std::cout << "(I don't know) !!!)"; } return; }
/* calculate approximate length of a printed term. For space alloc. */ DWORD clenpterm(prolog_term term) { int i, clen; if (is_var(term)) return 11; else if (is_int(term)) return 12; else if (is_float(term)) return 12; else if (is_nil(term)) return 2; else if (is_string(term)) return strlen(p2c_string(term))+5; else if (is_list(term)) { clen = 1; clen += clenpterm(p2p_car(term)) + 1; while (is_list(term)) { clen += clenpterm(p2p_car(term)) + 1; term = p2p_cdr(term); } if (!is_nil(term)) { clen += clenpterm(term) + 1; } return clen+1; } else if (is_functor(term)) { clen = strlen(p2c_functor(term))+5; if (p2c_arity(term) > 0) { clen += clenpterm(p2p_arg(term,1)) + 1; for (i = 2; i <= p2c_arity(term); i++) { clen += clenpterm(p2p_arg(term,i)) + 1; } return clen + 1; } else return clen; } else { fprintf(stderr,"error, unrecognized type"); return 0; } }
/** \brief Check whether the variable in t1 occurs in t2. */ bool lpo::occurs(expr_offset const & t1, expr_offset const & t2) { SASSERT(is_var(t1.get_expr())); if (is_ground(t2.get_expr())) return false; m_todo.reset(); m_todo.push_back(t2); while (!m_todo.empty()) { expr_offset t = m_todo.back(); m_todo.pop_back(); t = find(t); expr * n = t.get_expr(); if (is_ground(n)) continue; unsigned offset = t.get_offset(); unsigned j; switch (n->get_kind()) { case AST_VAR: if (t == t1) return true; break; case AST_APP: j = to_app(n)->get_num_args(); while (j > 0) { --j; expr * arg = to_app(n)->get_arg(j); if (!is_ground(arg)) m_todo.push_back(expr_offset(arg, offset)); } break; default: UNREACHABLE(); } } return false; }
void collect(expr * t, expr_fast_mark1 & visited) { rational k; visit(t, visited); while (!m_todo.empty()) { checkpoint(); expr * t = m_todo.back(); m_todo.pop_back(); if (is_var(t)) continue; if (is_quantifier(t)) { unsigned num_children = to_quantifier(t)->get_num_children(); for (unsigned i = 0; i < num_children; i ++) visit(to_quantifier(t)->get_child(i), visited); } else { SASSERT(is_app(t)); if (m_autil.is_power(t) && m_autil.is_numeral(to_app(t)->get_arg(1), k) && k.is_int() && k.is_pos()) { expr * arg = to_app(t)->get_arg(0); save_degree(arg, k); visit_args(arg, visited); } else { visit_args(t, visited); } } } }
/* Process an assignment expression */ void eval_exp0(int *value) { char temp[ID_LEN]; /* holds name of var receiving the assignment */ register int temp_tok; if(token_type==IDENTIFIER) { if(is_var(token)) { /* if a var, see if assignment */ strcpy(temp, token); temp_tok = token_type; get_token(); if(*token=='=') { /* is an assignment */ get_token(); eval_exp0(value); /* get value to assign */ assign_var(temp, *value); /* assign the value */ return; } else { /* not an assignment */ putback(); /* restore original token */ strcpy(token, temp); token_type = temp_tok; } } } eval_exp1(value); }
bool udoc_relation::is_var_range(expr* e, unsigned& hi, unsigned& lo, unsigned& v) const { udoc_plugin& p = get_plugin(); if (is_var(e)) { v = to_var(e)->get_idx(); hi = p.num_sort_bits(e)-1; lo = 0; return true; } expr* e2; if (p.bv.is_extract(e, lo, hi, e2) && is_var(e2)) { v = to_var(e2)->get_idx(); SASSERT(lo <= hi); return true; } return false; }
void eval_exp0(int &value) { char temp[MAX_ID_LEN + 1]; tok_types temp_tok; if (token_type == IDENTIFIER) { if (is_var(token)) { strcpy(temp, token); temp_tok = token_type; get_token(); if (*token == '=') { get_token(); eval_exp0(value); assign_var(temp, value); return; } else { putback(); strcpy(token, temp); token_type = temp_tok; } } } eval_exp1(value); }
void mk_unbound_compressor::detect_tasks(unsigned rule_index) { rule * r = m_rules.get(rule_index); var_idx_set tail_vars; collect_tail_vars(m_manager, r, tail_vars); app * head = r->get_head(); func_decl * head_pred = head->get_decl(); if (m_context.is_output_predicate(head_pred)) { //we don't compress output predicates return; } unsigned n = head_pred->get_arity(); var_counter head_var_counter; head_var_counter.count_vars(m_manager, head, 1); for (unsigned i=0; i<n; i++) { expr * arg = head->get_arg(i); if (!is_var(arg)) { continue; } unsigned var_idx = to_var(arg)->get_idx(); if (!tail_vars.contains(var_idx)) { //unbound unsigned occurence_cnt = head_var_counter.get(var_idx); SASSERT(occurence_cnt>0); if (occurence_cnt == 1) { TRACE("dl", r->display(m_context, tout << "Compress: ");); add_task(head_pred, i); return; //we compress out the unbound arguments one by one }
bool mk_unbound_compressor::is_unbound_argument(rule * r, unsigned head_index) { app * head = r->get_head(); expr * head_arg = head->get_arg(head_index); unsigned var_idx; return is_var(head_arg, var_idx) && rm.collect_tail_vars(r).contains(var_idx); }
optional<head_index> get_head_index(unsigned num, transition const * ts, expr const & a) { if (is_simple(num, ts)) { expr n = expand_pp_pattern(num, ts, a); if (!is_var(n)) return some(head_index(n)); } return optional<head_index>(); }
void add_var(char* name) { if (is_var(name)) cerror("duplicate variable"); if (nVars == SIZEVART-1) cerror("too many variables"); strcpy(Vars[nVars].name, name); Vars[nVars].value = 0.0; nVars++; }