case kind::ABS:
case kind::IS_INTEGER:
case kind::TO_INTEGER:
- case kind::TO_REAL: out << smtKindString(k) << " "; break;
+ case kind::TO_REAL:
+ case kind::POW: out << smtKindString(k) << " "; break;
case kind::DIVISIBLE:
out << "(_ divisible " << n.getOperator().getConst<Divisible>().k << ")";
case kind::IS_INTEGER: return "is_int";
case kind::TO_INTEGER: return "to_int";
case kind::TO_REAL: return "to_real";
+ case kind::POW: return "^";
// arrays theory
case kind::SELECT: return "select";
return RewriteResponse(REWRITE_DONE, t);
case kind::TO_REAL:
return RewriteResponse(REWRITE_DONE, t[0]);
+ case kind::POW:
+ return RewriteResponse(REWRITE_DONE, t);
default:
Unhandled(k);
}
}
}
+
RewriteResponse ArithRewriter::postRewriteTerm(TNode t){
if(t.isConst()){
return rewriteConstant(t);
//Unimplemented("IS_INTEGER, nonconstant");
//return rewriteIsInteger(t);
return RewriteResponse(REWRITE_DONE, t);
+ case kind::POW:
+ {
+ if(t[1].getKind() == kind::CONST_RATIONAL){
+ const Rational& exp = t[1].getConst<Rational>();
+ TNode base = t[0];
+ if(exp.sgn() == 0){
+ return RewriteResponse(REWRITE_DONE, mkRationalNode(Rational(1)));
+ }else if(exp.sgn() > 0 && exp.isIntegral()){
+ Integer num = exp.getNumerator();
+ NodeBuilder<> nb(kind::MULT);
+ Integer one(1);
+ for(Integer i(0); i < num; i = i + one){
+ nb << base;
+ }
+ Assert(nb.getNumChildren() > 0);
+ Node mult = nb;
+ return RewriteResponse(REWRITE_AGAIN, mult);
+ }
+ }
+
+ // Todo improve the exception thrown
+ std::stringstream ss;
+ ss << "The POW(^) operator can only be used with a natural number ";
+ ss << "in the exponent. Exception occured in:" << std::endl;
+ ss << " " << t;
+ throw Exception(ss.str());
+ }
default:
Unreachable();
}