/*****************************************************************************/ /*! * \file expr_value.cpp * * Author: Sergey Berezin * * Created: Fri Feb 7 22:29:04 2003 * *
* * License to use, copy, modify, sell and/or distribute this software * and its documentation for any purpose is hereby granted without * royalty, subject to the terms and conditions defined in the \ref * LICENSE file provided with this distribution. * *
* */ /*****************************************************************************/ #include "expr_value.h" #include "notifylist.h" using namespace std; namespace CVC3 { //////////////////////////////////////////////////////////////////////// // Class ExprValue static members //////////////////////////////////////////////////////////////////////// std::hash ExprValue::s_charHash; std::hash ExprValue::s_intHash; //////////////////////////////////////////////////////////////////////// // Class ExprValue methods //////////////////////////////////////////////////////////////////////// // Destructor ExprValue::~ExprValue() { // Be careful deleting the attributes: first set them to NULL, then // delete, to avoid circular destructor calls if (d_find) { CDO* find = d_find; d_find = NULL; delete find; free(find); } if(d_notifyList != NULL) { NotifyList* nl = d_notifyList; d_notifyList = NULL; delete nl; } // Set all smart pointers to Null d_type = Type(); d_simpCache=Theorem(); // d_simpFrom=Expr(); } // Equality between any two ExprValue objects (including subclasses) bool ExprValue::operator==(const ExprValue& ev2) const { DebugAssert(getMMIndex() == EXPR_VALUE, "ExprValue::operator==() called from a subclass"); if(getMMIndex() != ev2.getMMIndex()) return false; return (d_kind == ev2.d_kind); } ExprValue* ExprValue::copy(ExprManager* em, ExprIndex idx) const { DebugAssert(getMMIndex() == EXPR_VALUE, "ExprValue::copy() called from a subclass"); return new(em->getMM(EXPR_VALUE)) ExprValue(em, d_kind, idx); } bool ExprNodeTmp::operator==(const ExprValue& ev2) const { return getMMIndex() == ev2.getMMIndex() && d_kind == ev2.getKind() && getKids() == ev2.getKids(); } ExprValue* ExprNodeTmp::copy(ExprManager* em, ExprIndex idx) const { if (d_em != em) { vector children; vector::const_iterator i = d_children.begin(), iend = d_children.end(); for (; i != iend; ++i) children.push_back(rebuild(*i, em)); return new(em->getMM(getMMIndex())) ExprNode(em, d_kind, children, idx); } return new(em->getMM(getMMIndex())) ExprNode(em, d_kind, d_children, idx); } ExprNode::~ExprNode() { // Be careful deleting the attributes: first set them to NULL, then // delete, to avoid circular destructor calls if (d_sig) { CDO* sig = d_sig; d_sig = NULL; delete sig; free(sig); } if (d_rep) { CDO* rep = d_rep; d_rep = NULL; delete rep; free(rep); } } bool ExprNode::operator==(const ExprValue& ev2) const { if(getMMIndex() != ev2.getMMIndex()) return false; return (d_kind == ev2.getKind()) && (getKids() == ev2.getKids()); } ExprValue* ExprNode::copy(ExprManager* em, ExprIndex idx) const { if (d_em != em) { vector children; vector::const_iterator i = d_children.begin(), iend = d_children.end(); for (; i != iend; ++i) children.push_back(rebuild(*i, em)); return new(em->getMM(getMMIndex())) ExprNode(em, d_kind, children, idx); } return new(em->getMM(getMMIndex())) ExprNode(em, d_kind, d_children, idx); } bool ExprString::operator==(const ExprValue& ev2) const { if(getMMIndex() != ev2.getMMIndex()) return false; return (getString() == ev2.getString()); } ExprValue* ExprString::copy(ExprManager* em, ExprIndex idx) const { return new(em->getMM(getMMIndex())) ExprString(em, d_str, idx); } bool ExprSkolem::operator==(const ExprValue& ev2) const { if(getMMIndex() != ev2.getMMIndex()) return false; return (getBoundIndex() == ev2.getBoundIndex() && getExistential() == ev2.getExistential()); } ExprValue* ExprSkolem::copy(ExprManager* em, ExprIndex idx) const { if (d_em != em) { return new(em->getMM(getMMIndex())) ExprSkolem(em, getBoundIndex(), rebuild(getExistential(), em), idx); } return new(em->getMM(getMMIndex())) ExprSkolem(em, getBoundIndex(), getExistential(), idx); } bool ExprRational::operator==(const ExprValue& ev2) const { if(getMMIndex() != ev2.getMMIndex()) return false; return (getRational() == ev2.getRational()); } ExprValue* ExprRational::copy(ExprManager* em, ExprIndex idx) const { return new(em->getMM(getMMIndex())) ExprRational(em, d_r, idx); } bool ExprVar::operator==(const ExprValue& ev2) const { if(getMMIndex() != ev2.getMMIndex()) return false; return (getKind() == ev2.getKind() && getName() == ev2.getName()); } ExprValue* ExprVar::copy(ExprManager* em, ExprIndex idx) const { return new(em->getMM(getMMIndex())) ExprVar(em, d_name, idx); } bool ExprSymbol::operator==(const ExprValue& ev2) const { if(getMMIndex() != ev2.getMMIndex()) return false; return (getKind() == ev2.getKind() && getName() == ev2.getName()); } ExprValue* ExprSymbol::copy(ExprManager* em, ExprIndex idx) const { return new(em->getMM(getMMIndex())) ExprSymbol(em, d_kind, d_name, idx); } bool ExprBoundVar::operator==(const ExprValue& ev2) const { if(getMMIndex() != ev2.getMMIndex()) return false; return (getKind() == ev2.getKind() && getName() == ev2.getName() && getUid() == ev2.getUid()); } ExprValue* ExprBoundVar::copy(ExprManager* em, ExprIndex idx) const { return new(em->getMM(getMMIndex())) ExprBoundVar(em, d_name, d_uid, idx); } bool ExprApply::operator==(const ExprValue& ev2) const { if(getMMIndex() != ev2.getMMIndex()) return false; return (getOp() == ev2.getOp()) && (getKids() == ev2.getKids()); } ExprValue* ExprApply::copy(ExprManager* em, ExprIndex idx) const { if (d_em != em) { vector children; vector::const_iterator i = d_children.begin(), iend = d_children.end(); for (; i != iend; ++i) children.push_back(rebuild(*i, em)); return new(em->getMM(getMMIndex())) ExprApply(em, Op(rebuild(d_opExpr, em)), children, idx); } return new(em->getMM(getMMIndex())) ExprApply(em, Op(d_opExpr), d_children, idx); } bool ExprApplyTmp::operator==(const ExprValue& ev2) const { if(getMMIndex() != ev2.getMMIndex()) return false; return (getOp() == ev2.getOp()) && (getKids() == ev2.getKids()); } ExprValue* ExprApplyTmp::copy(ExprManager* em, ExprIndex idx) const { if (d_em != em) { vector children; vector::const_iterator i = d_children.begin(), iend = d_children.end(); for (; i != iend; ++i) children.push_back(rebuild(*i, em)); return new(em->getMM(getMMIndex())) ExprApply(em, Op(rebuild(d_opExpr, em)), children, idx); } return new(em->getMM(getMMIndex())) ExprApply(em, Op(d_opExpr), d_children, idx); } bool ExprClosure::operator==(const ExprValue& ev2) const { if(getMMIndex() != ev2.getMMIndex()) return false; return (getKind() == ev2.getKind()) && (getBody() == ev2.getBody()) && (getVars() == ev2.getVars()); } ExprValue* ExprClosure::copy(ExprManager* em, ExprIndex idx) const { if (d_em != em) { vector vars; vector::const_iterator i = d_vars.begin(), iend = d_vars.end(); for (; i != iend; ++i) vars.push_back(rebuild(*i, em)); return new(em->getMM(getMMIndex())) ExprClosure(em, d_kind, vars, rebuild(d_body, em), idx); } return new(em->getMM(getMMIndex())) ExprClosure(em, d_kind, d_vars, d_body, idx); } bool ExprTheorem::operator==(const ExprValue& ev2) const { if(getMMIndex() != ev2.getMMIndex()) return false; return (getTheorem() == ev2.getTheorem()); } ExprValue* ExprTheorem::copy(ExprManager* em, ExprIndex idx) const { return new(em->getMM(getMMIndex())) ExprTheorem(em, d_thm, idx); } //////////////////////////////////////////////////////////////////////// // Methods of subclasses of ExprValue //////////////////////////////////////////////////////////////////////// // Hash function for subclasses with kids. size_t ExprValue::hash(const int kind, const std::vector& kids) { size_t res(s_intHash((long int)kind)); for(std::vector::const_iterator i=kids.begin(), iend=kids.end(); i!=iend; ++i) { void* ptr = i->d_expr; res = res*PRIME + pointerHash(ptr); } return res; } size_t ExprClosure::computeHash() const { return d_body.hash()*PRIME + ExprValue::hash(d_kind, d_vars); } } // end of namespace CVC3