ct_common  1.0.1
Common library for combinatorial testing
src/ct_common/common/exp_a_param.cpp
Go to the documentation of this file.
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> > &param_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> > &param_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> > &param_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> > &param_specs) const {
00163   os << param_specs[this->pid_]->get_param_name();
00164 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines