Term* Term::evalute_term(map<Term*, SatValue>& assignments) { switch(this->get_term_type()) { case CONSTANT_TERM: return this; case VARIABLE_TERM: { if(assignments.count(this) > 0){ return ConstantTerm::make(assignments[this].value.to_int()); } return this; } case FUNCTION_TERM: { if(assignments.count(this) > 0){ return ConstantTerm::make(assignments[this].value.to_int()); } vector<Term*> new_args; FunctionTerm* ft = (FunctionTerm*) this; for(unsigned int i = 0; i < ft->get_args().size(); i++) { Term* arg = ft->get_args()[i]; arg = arg->evalute_term(assignments); new_args.push_back(arg); } Term* new_t = FunctionTerm::make(ft->get_id(), new_args, ft->is_invertible()); if(assignments.count(new_t) > 0) return ConstantTerm::make(assignments[new_t].value.to_int()); return new_t; } case ARITHMETIC_TERM: { ArithmeticTerm* at = (ArithmeticTerm*) this; Term* res = ConstantTerm::make(at->get_constant()); const map<Term*, long int>& elems = at->get_elems(); map<Term*, long int>::const_iterator it = elems.begin(); for(; it!=elems.end(); it++) { Term* t = it->first; Term* val = t->evalute_term(assignments); res = res->add(val->multiply(it->second)); } if(assignments.count(res) > 0) return ConstantTerm::make(assignments[res].value.to_int()); return res; } default: assert(false); } }