ct_common
1.0.1
Common library for combinatorial testing
|
00001 //===----- ct_common/common/exp_a_param.cpp ---------------------*- C++ -*-===// 00002 // 00003 // The ct_common Library 00004 // 00005 // This file is distributed under the MIT license. See LICENSE for details. 00006 // 00007 //===----------------------------------------------------------------------===// 00008 // 00009 // This file contains the function definitions of class Exp_A_Param 00010 // 00011 //===----------------------------------------------------------------------===// 00012 00013 #include <exception> 00014 #include <ct_common/common/utils.h> 00015 #include <ct_common/common/exp_a_param.h> 00016 #include <ct_common/common/paramspec_double.h> 00017 #include <ct_common/common/paramspec_int.h> 00018 #include <ct_common/common/constraint.h> 00019 00020 using namespace ct::common; 00021 00022 Exp_A_Param::Exp_A_Param(void) 00023 : Exp_A_Atom(), pid_(PID_BOUND) { 00024 } 00025 00026 Exp_A_Param::Exp_A_Param(const Exp_A_Param &from) 00027 : Exp_A_Atom(from), pid_(from.pid_) { 00028 } 00029 00030 Exp_A_Param &Exp_A_Param::operator = (const Exp_A_Param &right) { 00031 Exp_A_Atom::operator=(right); 00032 this->pid_ = right.pid_; 00033 return *this; 00034 } 00035 00036 Exp_A_Param::~Exp_A_Param(void) { 00037 } 00038 00039 EvalType_Double Exp_A_Param::EvaluateDouble_Impl(const std::vector<boost::shared_ptr<ParamSpec> > ¶m_specs, 00040 const Assignment &assignment) const { 00041 EvalType_Double tmp_return; 00042 // FIXME: need to reconsider the logic 00043 if (param_specs[this->pid_]->is_auto()) { 00044 if (!TYPE_CHECK(param_specs[this->pid_].get(), ParamSpec_Int*) && 00045 !TYPE_CHECK(param_specs[this->pid_].get(), ParamSpec_Double*)) { 00046 CT_EXCEPTION("Evaluating numeric values from non-numeric auto value parameter"); 00047 return tmp_return; 00048 } 00049 for (std::size_t i = 0; i < param_specs[this->pid_]->get_auto_value_specs().size(); ++i) { 00050 boost::shared_ptr<Constraint> cond = boost::dynamic_pointer_cast<Constraint>(param_specs[this->pid_]->auto_value_specs()[i].first); 00051 if (cond) { 00052 EvalType_Bool cond_value; 00053 cond_value = cond->Evaluate(param_specs, assignment); 00054 if (cond_value.is_valid_ && cond_value.value_) { 00055 // condition met, taking the value 00056 boost::shared_ptr<Exp_A> val_exp = boost::dynamic_pointer_cast<Exp_A>(param_specs[this->pid_]->auto_value_specs()[i].second); 00057 if (val_exp) { 00058 return val_exp->EvaluateDouble(param_specs, assignment); 00059 } else { 00060 CT_EXCEPTION("Error: encountering invalid auto value expression"); 00061 return tmp_return; 00062 } 00063 } 00064 } else { 00065 CT_EXCEPTION("Error: encountering invalid auto value condition"); 00066 return tmp_return; 00067 } 00068 } 00069 // FIXME: suppressing error 00070 //CT_EXCEPTION(std::string("Error: encountering unhandled auto value condition for parameter ")+param_specs[this->pid_]->get_param_name()); 00071 return tmp_return; 00072 } 00073 std::size_t vid = assignment.GetValue(this->pid_); 00074 tmp_return.is_valid_ = !param_specs[this->pid_]->is_vid_invalid(vid); 00075 if (tmp_return.is_valid_) { 00076 if (TYPE_CHECK(param_specs[this->pid_].get(), ParamSpec_Int*)) { 00077 tmp_return.value_ = dynamic_cast<ParamSpec_Int *>(param_specs[this->pid_].get()) 00078 ->get_int_values()[vid]; 00079 } else if (TYPE_CHECK(param_specs[this->pid_].get(), ParamSpec_Double*)) { 00080 tmp_return.value_ = dynamic_cast<ParamSpec_Double *>(param_specs[this->pid_].get()) 00081 ->get_double_values()[vid]; 00082 } else { 00083 CT_EXCEPTION("cannot evaluate numerical value of a non-numerical parameter"); 00084 tmp_return.is_valid_ = false; 00085 } 00086 } 00087 return tmp_return; 00088 } 00089 00090 EvalType_Int Exp_A_Param::EvaluateInt_Impl(const std::vector<boost::shared_ptr<ParamSpec> > ¶m_specs, 00091 const Assignment &assignment) const { 00092 EvalType_Int tmp_return; 00093 // FIXME: need to reconsider the logic 00094 if (param_specs[this->pid_]->is_auto()) { 00095 if (!TYPE_CHECK(param_specs[this->pid_].get(), ParamSpec_Int*) && 00096 !TYPE_CHECK(param_specs[this->pid_].get(), ParamSpec_Double*)) { 00097 CT_EXCEPTION("Evaluating numeric values from non-numeric auto value parameter"); 00098 return tmp_return; 00099 } 00100 for (std::size_t i = 0; i < param_specs[this->pid_]->get_auto_value_specs().size(); ++i) { 00101 boost::shared_ptr<Constraint> cond = boost::dynamic_pointer_cast<Constraint>(param_specs[this->pid_]->auto_value_specs()[i].first); 00102 if (cond) { 00103 EvalType_Bool cond_value; 00104 cond_value = cond->Evaluate(param_specs, assignment); 00105 if (cond_value.is_valid_ && cond_value.value_) { 00106 // condition met, taking the value 00107 boost::shared_ptr<Exp_A> val_exp = boost::dynamic_pointer_cast<Exp_A>(param_specs[this->pid_]->auto_value_specs()[i].second); 00108 if (val_exp) { 00109 return val_exp->EvaluateInt(param_specs, assignment); 00110 } else { 00111 CT_EXCEPTION("Error: encountering invalid auto value expression"); 00112 return tmp_return; 00113 } 00114 } 00115 } else { 00116 CT_EXCEPTION("Error: encountering invalid auto value condition"); 00117 return tmp_return; 00118 } 00119 } 00120 // FIXME: suppressing error 00121 //CT_EXCEPTION(std::string("Error: encountering unhandled auto value condition for parameter ")+param_specs[this->pid_]->get_param_name()); 00122 return tmp_return; 00123 } 00124 std::size_t vid = assignment.GetValue(this->pid_); 00125 tmp_return.is_valid_ = !param_specs[this->pid_]->is_vid_invalid(vid); 00126 if (tmp_return.is_valid_) { 00127 if (TYPE_CHECK(param_specs[this->pid_].get(), ParamSpec_Int*)) { 00128 tmp_return.value_ = dynamic_cast<ParamSpec_Int *>(param_specs[this->pid_].get()) 00129 ->get_int_values()[vid]; 00130 } else if (TYPE_CHECK(param_specs[this->pid_].get(), ParamSpec_Double*)) { 00131 tmp_return.value_ = (int)dynamic_cast<ParamSpec_Double *>(param_specs[this->pid_].get()) 00132 ->get_double_values()[vid]; 00133 } else { 00134 CT_EXCEPTION("cannot evaluate numerical value of a non-numerical parameter"); 00135 tmp_return.is_valid_ = false; 00136 } 00137 } 00138 return tmp_return; 00139 } 00140 00141 std::string Exp_A_Param::get_class_name(void) const { 00142 return Exp_A_Param::class_name(); 00143 } 00144 00145 std::string Exp_A_Param::class_name(void) { 00146 return "Exp_A_Param"; 00147 } 00148 00149 void Exp_A_Param::inner_touch_leaf_pids(const std::vector<boost::shared_ptr<ParamSpec> > ¶m_specs, 00150 std::set<std::size_t> &pids_to_touch) const { 00151 if (!param_specs[this->pid_]) { 00152 CT_EXCEPTION("encountered invalid parameter spec"); 00153 return; 00154 } 00155 if (param_specs[this->pid_]->is_auto()) { 00156 param_specs[this->pid_]->touch_pids(param_specs, pids_to_touch); 00157 } else { 00158 pids_to_touch.insert(this->pid_); 00159 } 00160 } 00161 00162 void Exp_A_Param::dump(std::ostream &os, const std::vector<boost::shared_ptr<ParamSpec> > ¶m_specs) const { 00163 os << param_specs[this->pid_]->get_param_name(); 00164 }