Model.cc revision 10447
110447Snilay@cs.wisc.edu#include "model/Model.h"
210447Snilay@cs.wisc.edu
310447Snilay@cs.wisc.edu#include <vector>
410447Snilay@cs.wisc.edu
510447Snilay@cs.wisc.edu#include "util/Result.h"
610447Snilay@cs.wisc.edu
710447Snilay@cs.wisc.edunamespace DSENT
810447Snilay@cs.wisc.edu{
910447Snilay@cs.wisc.edu    using std::vector;
1010447Snilay@cs.wisc.edu    using LibUtil::deletePtrMap;
1110447Snilay@cs.wisc.edu    using LibUtil::clonePtrMap;
1210447Snilay@cs.wisc.edu
1310447Snilay@cs.wisc.edu    Model::SubModel::SubModel(Model* model_, double num_models_)
1410447Snilay@cs.wisc.edu        : m_model_(model_), m_num_models_(num_models_)
1510447Snilay@cs.wisc.edu    {}
1610447Snilay@cs.wisc.edu
1710447Snilay@cs.wisc.edu    Model::SubModel::~SubModel()
1810447Snilay@cs.wisc.edu    {
1910447Snilay@cs.wisc.edu        delete m_model_;
2010447Snilay@cs.wisc.edu    }
2110447Snilay@cs.wisc.edu
2210447Snilay@cs.wisc.edu    Model* Model::SubModel::getModel()
2310447Snilay@cs.wisc.edu    {
2410447Snilay@cs.wisc.edu        return m_model_;
2510447Snilay@cs.wisc.edu    }
2610447Snilay@cs.wisc.edu
2710447Snilay@cs.wisc.edu    const Model* Model::SubModel::getModel() const
2810447Snilay@cs.wisc.edu    {
2910447Snilay@cs.wisc.edu        return m_model_;
3010447Snilay@cs.wisc.edu    }
3110447Snilay@cs.wisc.edu
3210447Snilay@cs.wisc.edu    double Model::SubModel::getNumModels() const
3310447Snilay@cs.wisc.edu    {
3410447Snilay@cs.wisc.edu        return m_num_models_;
3510447Snilay@cs.wisc.edu    }
3610447Snilay@cs.wisc.edu
3710447Snilay@cs.wisc.edu    Model::SubModel* Model::SubModel::clone() const
3810447Snilay@cs.wisc.edu    {
3910447Snilay@cs.wisc.edu        return new SubModel(*this);
4010447Snilay@cs.wisc.edu    }
4110447Snilay@cs.wisc.edu
4210447Snilay@cs.wisc.edu    Model::SubModel::SubModel(const SubModel& sub_model_)
4310447Snilay@cs.wisc.edu    {
4410447Snilay@cs.wisc.edu        m_model_ = sub_model_.m_model_->clone();
4510447Snilay@cs.wisc.edu        m_num_models_ = sub_model_.m_num_models_;
4610447Snilay@cs.wisc.edu    }
4710447Snilay@cs.wisc.edu
4810447Snilay@cs.wisc.edu    const char Model::TYPE_SEPARATOR[] = ">>";
4910447Snilay@cs.wisc.edu    const char Model::HIERARCHY_SEPARATOR[] = "->";
5010447Snilay@cs.wisc.edu    const char Model::SUBFIELD_SEPARATOR[] = ":";
5110447Snilay@cs.wisc.edu    const char Model::DETAIL_SEPARATOR[] = "@";
5210447Snilay@cs.wisc.edu
5310447Snilay@cs.wisc.edu    Model::Model(const String& instance_name_, const TechModel* tech_model_)
5410447Snilay@cs.wisc.edu        : m_instance_name_(instance_name_), m_tech_model_(tech_model_),
5510447Snilay@cs.wisc.edu            m_constructed_(false), m_updated_(false), m_evaluated_(false)
5610447Snilay@cs.wisc.edu    {
5710447Snilay@cs.wisc.edu        m_property_names_ = new vector<String>;
5810447Snilay@cs.wisc.edu        m_parameter_names_ = new vector<String>;
5910447Snilay@cs.wisc.edu        m_parameters_ = new ParameterMap();
6010447Snilay@cs.wisc.edu        m_properties_ = new PropertyMap();
6110447Snilay@cs.wisc.edu        m_generated_properties_ = new PropertyMap();
6210447Snilay@cs.wisc.edu        m_sub_instances_ = new Map<SubModel*>();
6310447Snilay@cs.wisc.edu        m_event_map_ = new Map<Result*>();
6410447Snilay@cs.wisc.edu        m_area_map_ = new Map<Result*>();
6510447Snilay@cs.wisc.edu        m_ndd_power_map_ = new Map<Result*>();
6610447Snilay@cs.wisc.edu    }
6710447Snilay@cs.wisc.edu
6810447Snilay@cs.wisc.edu    Model::~Model()
6910447Snilay@cs.wisc.edu    {
7010447Snilay@cs.wisc.edu        // Clear parameter names
7110447Snilay@cs.wisc.edu        delete m_parameter_names_;
7210447Snilay@cs.wisc.edu        // Clear property name
7310447Snilay@cs.wisc.edu        delete m_property_names_;
7410447Snilay@cs.wisc.edu
7510447Snilay@cs.wisc.edu        // Clear parameters
7610447Snilay@cs.wisc.edu        delete m_parameters_;
7710447Snilay@cs.wisc.edu        m_parameters_ = NULL;
7810447Snilay@cs.wisc.edu        // Clear input properties
7910447Snilay@cs.wisc.edu        delete m_properties_;
8010447Snilay@cs.wisc.edu        m_properties_ = NULL;
8110447Snilay@cs.wisc.edu
8210447Snilay@cs.wisc.edu        // Clear generated properties
8310447Snilay@cs.wisc.edu        delete m_generated_properties_;
8410447Snilay@cs.wisc.edu        m_generated_properties_ = NULL;
8510447Snilay@cs.wisc.edu
8610447Snilay@cs.wisc.edu        // Clear sub models
8710447Snilay@cs.wisc.edu        deletePtrMap<SubModel>(m_sub_instances_);
8810447Snilay@cs.wisc.edu        m_sub_instances_ = NULL;
8910447Snilay@cs.wisc.edu
9010447Snilay@cs.wisc.edu        // Clear all results
9110447Snilay@cs.wisc.edu        deletePtrMap<Result>(m_event_map_);
9210447Snilay@cs.wisc.edu        m_event_map_ = NULL;
9310447Snilay@cs.wisc.edu        deletePtrMap<Result>(m_area_map_);
9410447Snilay@cs.wisc.edu        m_area_map_ = NULL;
9510447Snilay@cs.wisc.edu        deletePtrMap<Result>(m_ndd_power_map_);
9610447Snilay@cs.wisc.edu        m_ndd_power_map_ = NULL;
9710447Snilay@cs.wisc.edu    }
9810447Snilay@cs.wisc.edu
9910447Snilay@cs.wisc.edu    void Model::setInstanceName(const String& instance_name_)
10010447Snilay@cs.wisc.edu    {
10110447Snilay@cs.wisc.edu        m_instance_name_ = instance_name_;
10210447Snilay@cs.wisc.edu        return;
10310447Snilay@cs.wisc.edu    }
10410447Snilay@cs.wisc.edu
10510447Snilay@cs.wisc.edu    const String& Model::getInstanceName() const
10610447Snilay@cs.wisc.edu    {
10710447Snilay@cs.wisc.edu        return m_instance_name_;
10810447Snilay@cs.wisc.edu    }
10910447Snilay@cs.wisc.edu
11010447Snilay@cs.wisc.edu    void Model::setIsTopModel(bool is_top_model_)
11110447Snilay@cs.wisc.edu    {
11210447Snilay@cs.wisc.edu        m_is_top_model_ = is_top_model_;
11310447Snilay@cs.wisc.edu        return;
11410447Snilay@cs.wisc.edu    }
11510447Snilay@cs.wisc.edu
11610447Snilay@cs.wisc.edu    bool Model::getIsTopModel() const
11710447Snilay@cs.wisc.edu    {
11810447Snilay@cs.wisc.edu        return m_is_top_model_;
11910447Snilay@cs.wisc.edu    }
12010447Snilay@cs.wisc.edu
12110447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
12210447Snilay@cs.wisc.edu    //  Parameters and properties checks
12310447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
12410447Snilay@cs.wisc.edu    void Model::addParameterName(const String& parameter_name_)
12510447Snilay@cs.wisc.edu    {
12610447Snilay@cs.wisc.edu        ASSERT(!m_constructed_, "[Error] " + getInstanceName() +
12710447Snilay@cs.wisc.edu            " -> Cannot add additional parameters names after model is constructed!");
12810447Snilay@cs.wisc.edu        m_parameter_names_->push_back(parameter_name_);
12910447Snilay@cs.wisc.edu
13010447Snilay@cs.wisc.edu        return;
13110447Snilay@cs.wisc.edu    }
13210447Snilay@cs.wisc.edu
13310447Snilay@cs.wisc.edu    void Model::addParameterName(const String& parameter_name_, const String& parameter_default_)
13410447Snilay@cs.wisc.edu    {
13510447Snilay@cs.wisc.edu        ASSERT(!m_constructed_, "[Error] " + getInstanceName() +
13610447Snilay@cs.wisc.edu            " -> Cannot add additional parameters names after model is constructed!");
13710447Snilay@cs.wisc.edu        m_parameter_names_->push_back(parameter_name_);
13810447Snilay@cs.wisc.edu        setParameter(parameter_name_, parameter_default_);
13910447Snilay@cs.wisc.edu        return;
14010447Snilay@cs.wisc.edu    }
14110447Snilay@cs.wisc.edu
14210447Snilay@cs.wisc.edu    const vector<String>* Model::getParameterNames() const
14310447Snilay@cs.wisc.edu    {
14410447Snilay@cs.wisc.edu        return m_parameter_names_;
14510447Snilay@cs.wisc.edu    }
14610447Snilay@cs.wisc.edu
14710447Snilay@cs.wisc.edu    void Model::addPropertyName(const String& property_name_)
14810447Snilay@cs.wisc.edu    {
14910447Snilay@cs.wisc.edu        ASSERT(!m_constructed_, "[Error] " + getInstanceName() +
15010447Snilay@cs.wisc.edu            " -> Cannot add additional property names after model is constructed!");
15110447Snilay@cs.wisc.edu        m_property_names_->push_back(property_name_);
15210447Snilay@cs.wisc.edu        return;
15310447Snilay@cs.wisc.edu    }
15410447Snilay@cs.wisc.edu
15510447Snilay@cs.wisc.edu    void Model::addPropertyName(const String& property_name_, const String& property_default_)
15610447Snilay@cs.wisc.edu    {
15710447Snilay@cs.wisc.edu        ASSERT(!m_constructed_, "[Error] " + getInstanceName() +
15810447Snilay@cs.wisc.edu            " -> Cannot add additional property names after model is constructed!");
15910447Snilay@cs.wisc.edu        m_property_names_->push_back(property_name_);
16010447Snilay@cs.wisc.edu        setProperty(property_name_, property_default_);
16110447Snilay@cs.wisc.edu        return;
16210447Snilay@cs.wisc.edu    }
16310447Snilay@cs.wisc.edu
16410447Snilay@cs.wisc.edu    const vector<String>* Model::getPropertyNames() const
16510447Snilay@cs.wisc.edu    {
16610447Snilay@cs.wisc.edu        return m_property_names_;
16710447Snilay@cs.wisc.edu    }
16810447Snilay@cs.wisc.edu
16910447Snilay@cs.wisc.edu    void Model::checkParameters() const
17010447Snilay@cs.wisc.edu    {
17110447Snilay@cs.wisc.edu        String missing_parameters = "";
17210447Snilay@cs.wisc.edu
17310447Snilay@cs.wisc.edu        for(int i = 0; i < (int)m_parameter_names_->size(); ++i)
17410447Snilay@cs.wisc.edu        {
17510447Snilay@cs.wisc.edu            const String& parameter_name = m_parameter_names_->at(i);
17610447Snilay@cs.wisc.edu            if (!m_parameters_->keyExist(parameter_name))
17710447Snilay@cs.wisc.edu                missing_parameters += "    " + parameter_name + "\n";
17810447Snilay@cs.wisc.edu        }
17910447Snilay@cs.wisc.edu
18010447Snilay@cs.wisc.edu        ASSERT(missing_parameters.size() == 0, "[Error] " + m_instance_name_ +
18110447Snilay@cs.wisc.edu                " -> Missing parameters:\n" + missing_parameters);
18210447Snilay@cs.wisc.edu        return;
18310447Snilay@cs.wisc.edu    }
18410447Snilay@cs.wisc.edu
18510447Snilay@cs.wisc.edu    void Model::checkProperties() const
18610447Snilay@cs.wisc.edu    {
18710447Snilay@cs.wisc.edu        String missing_properties = "";
18810447Snilay@cs.wisc.edu
18910447Snilay@cs.wisc.edu        for(int i = 0; i < (int)m_property_names_->size(); ++i)
19010447Snilay@cs.wisc.edu        {
19110447Snilay@cs.wisc.edu            const String& property_name = m_property_names_->at(i);
19210447Snilay@cs.wisc.edu            if (!m_properties_->keyExist(property_name))
19310447Snilay@cs.wisc.edu                missing_properties += "    " + property_name + "\n";
19410447Snilay@cs.wisc.edu        }
19510447Snilay@cs.wisc.edu
19610447Snilay@cs.wisc.edu        ASSERT(missing_properties.size() == 0, "[Error] " + m_instance_name_ +
19710447Snilay@cs.wisc.edu                " -> Missing properties:\n" + missing_properties);
19810447Snilay@cs.wisc.edu        return;
19910447Snilay@cs.wisc.edu    }
20010447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
20110447Snilay@cs.wisc.edu
20210447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
20310447Snilay@cs.wisc.edu    //  Parameters Manipulation
20410447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
20510447Snilay@cs.wisc.edu    const ParameterMap* Model::getParameters() const
20610447Snilay@cs.wisc.edu    {
20710447Snilay@cs.wisc.edu        return m_parameters_;
20810447Snilay@cs.wisc.edu    }
20910447Snilay@cs.wisc.edu
21010447Snilay@cs.wisc.edu    const String Model::getParameter(const String& parameter_name_) const
21110447Snilay@cs.wisc.edu    {
21210447Snilay@cs.wisc.edu        return m_parameters_->get(parameter_name_);
21310447Snilay@cs.wisc.edu    }
21410447Snilay@cs.wisc.edu
21510447Snilay@cs.wisc.edu    void Model::setParameter(const String& parameter_name_, const String& parameter_value_)
21610447Snilay@cs.wisc.edu    {
21710447Snilay@cs.wisc.edu        ASSERT(!m_constructed_, "[Error] " + getInstanceName() +
21810447Snilay@cs.wisc.edu            " -> Cannot set parameters after model is constructed!");
21910447Snilay@cs.wisc.edu        m_parameters_->set(parameter_name_, parameter_value_);
22010447Snilay@cs.wisc.edu    }
22110447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
22210447Snilay@cs.wisc.edu
22310447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
22410447Snilay@cs.wisc.edu    // Properties Manipulation
22510447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
22610447Snilay@cs.wisc.edu    const PropertyMap* Model::getProperties() const
22710447Snilay@cs.wisc.edu    {
22810447Snilay@cs.wisc.edu        return m_properties_;
22910447Snilay@cs.wisc.edu    }
23010447Snilay@cs.wisc.edu
23110447Snilay@cs.wisc.edu    const String Model::getProperty(const String& property_name_) const
23210447Snilay@cs.wisc.edu    {
23310447Snilay@cs.wisc.edu        return m_properties_->get(property_name_);
23410447Snilay@cs.wisc.edu    }
23510447Snilay@cs.wisc.edu
23610447Snilay@cs.wisc.edu    void Model::setProperty(const String& property_name_, const String& property_value_)
23710447Snilay@cs.wisc.edu    {
23810447Snilay@cs.wisc.edu        // If any properties changed, reset updated and evaluated flags
23910447Snilay@cs.wisc.edu        m_updated_ = false;
24010447Snilay@cs.wisc.edu        m_evaluated_ = false;
24110447Snilay@cs.wisc.edu        m_properties_->set(property_name_, property_value_);
24210447Snilay@cs.wisc.edu    }
24310447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
24410447Snilay@cs.wisc.edu
24510447Snilay@cs.wisc.edu    PropertyMap* Model::getGenProperties()
24610447Snilay@cs.wisc.edu    {
24710447Snilay@cs.wisc.edu        return m_generated_properties_;
24810447Snilay@cs.wisc.edu    }
24910447Snilay@cs.wisc.edu
25010447Snilay@cs.wisc.edu    const PropertyMap* Model::getGenProperties() const
25110447Snilay@cs.wisc.edu    {
25210447Snilay@cs.wisc.edu        return m_generated_properties_;
25310447Snilay@cs.wisc.edu    }
25410447Snilay@cs.wisc.edu
25510447Snilay@cs.wisc.edu    void Model::addSubInstances(Model* sub_instance_, double num_sub_instances_)
25610447Snilay@cs.wisc.edu    {
25710447Snilay@cs.wisc.edu        // Get instance name
25810447Snilay@cs.wisc.edu        const String& sub_instance_name = sub_instance_->getInstanceName();
25910447Snilay@cs.wisc.edu
26010447Snilay@cs.wisc.edu        // Check if the instance exists
26110447Snilay@cs.wisc.edu        if(m_sub_instances_->keyExist(sub_instance_name))
26210447Snilay@cs.wisc.edu        {
26310447Snilay@cs.wisc.edu            const String& error_msg = "[Error] " + m_instance_name_ +
26410447Snilay@cs.wisc.edu            " -> Instance exists (" + sub_instance_name + ")";
26510447Snilay@cs.wisc.edu            throw Exception(error_msg);
26610447Snilay@cs.wisc.edu        }
26710447Snilay@cs.wisc.edu
26810447Snilay@cs.wisc.edu        // Check if the num_sub_instances_ is a positive number
26910447Snilay@cs.wisc.edu        ASSERT((num_sub_instances_ >= 0), "[Error] " + m_instance_name_ +
27010447Snilay@cs.wisc.edu        " -> Invalid number of instance (" + String(num_sub_instances_) + ")");
27110447Snilay@cs.wisc.edu
27210447Snilay@cs.wisc.edu        // Add the instance
27310447Snilay@cs.wisc.edu        m_sub_instances_->set(sub_instance_name, new SubModel(sub_instance_, num_sub_instances_));
27410447Snilay@cs.wisc.edu        return;
27510447Snilay@cs.wisc.edu    }
27610447Snilay@cs.wisc.edu
27710447Snilay@cs.wisc.edu    Model* Model::getSubInstance(const String& sub_instance_name_)
27810447Snilay@cs.wisc.edu    {
27910447Snilay@cs.wisc.edu        // Throw an Exception if the instance already exists
28010447Snilay@cs.wisc.edu        if(!m_sub_instances_->keyExist(sub_instance_name_))
28110447Snilay@cs.wisc.edu        {
28210447Snilay@cs.wisc.edu            const String& error_msg = "[Error] " + m_instance_name_ +
28310447Snilay@cs.wisc.edu            " -> Instance not exists (" + sub_instance_name_ + ")";
28410447Snilay@cs.wisc.edu            throw Exception(error_msg);
28510447Snilay@cs.wisc.edu        }
28610447Snilay@cs.wisc.edu
28710447Snilay@cs.wisc.edu        return m_sub_instances_->get(sub_instance_name_)->getModel();
28810447Snilay@cs.wisc.edu    }
28910447Snilay@cs.wisc.edu
29010447Snilay@cs.wisc.edu    const Model* Model::getSubInstance(const String& sub_instance_name_) const
29110447Snilay@cs.wisc.edu    {
29210447Snilay@cs.wisc.edu        // Throw an Exception if the instance does not exist
29310447Snilay@cs.wisc.edu        if(!m_sub_instances_->keyExist(sub_instance_name_))
29410447Snilay@cs.wisc.edu        {
29510447Snilay@cs.wisc.edu            const String& error_msg = "[Error] " + m_instance_name_ +
29610447Snilay@cs.wisc.edu            " -> Instance not exists (" + sub_instance_name_ + ")";
29710447Snilay@cs.wisc.edu            throw Exception(error_msg);
29810447Snilay@cs.wisc.edu        }
29910447Snilay@cs.wisc.edu
30010447Snilay@cs.wisc.edu        return m_sub_instances_->get(sub_instance_name_)->getModel();
30110447Snilay@cs.wisc.edu    }
30210447Snilay@cs.wisc.edu
30310447Snilay@cs.wisc.edu    bool Model::hasSubInstance(const String& sub_instance_name_) const
30410447Snilay@cs.wisc.edu    {
30510447Snilay@cs.wisc.edu        return m_sub_instances_->keyExist(sub_instance_name_);
30610447Snilay@cs.wisc.edu    }
30710447Snilay@cs.wisc.edu
30810447Snilay@cs.wisc.edu    void Model::addAreaResult(Result* area_)
30910447Snilay@cs.wisc.edu    {
31010447Snilay@cs.wisc.edu        const String& area_name = area_->getName();
31110447Snilay@cs.wisc.edu
31210447Snilay@cs.wisc.edu        // Throw an Exception if the area already exists
31310447Snilay@cs.wisc.edu        if(m_area_map_->keyExist(area_name))
31410447Snilay@cs.wisc.edu        {
31510447Snilay@cs.wisc.edu            const String& error_msg = "Internal error: area (" + area_name +
31610447Snilay@cs.wisc.edu                ") exists";
31710447Snilay@cs.wisc.edu            throw Exception(error_msg);
31810447Snilay@cs.wisc.edu        }
31910447Snilay@cs.wisc.edu
32010447Snilay@cs.wisc.edu        // Add the area
32110447Snilay@cs.wisc.edu        m_area_map_->set(area_name, area_);
32210447Snilay@cs.wisc.edu        return;
32310447Snilay@cs.wisc.edu    }
32410447Snilay@cs.wisc.edu
32510447Snilay@cs.wisc.edu    Result* Model::getAreaResult(const String& area_name_)
32610447Snilay@cs.wisc.edu    {
32710447Snilay@cs.wisc.edu        return m_area_map_->get(area_name_);
32810447Snilay@cs.wisc.edu    }
32910447Snilay@cs.wisc.edu
33010447Snilay@cs.wisc.edu    const Result* Model::getAreaResult(const String& area_name_) const
33110447Snilay@cs.wisc.edu    {
33210447Snilay@cs.wisc.edu        return m_area_map_->get(area_name_);
33310447Snilay@cs.wisc.edu    }
33410447Snilay@cs.wisc.edu
33510447Snilay@cs.wisc.edu    bool Model::hasAreaResult(const String& area_name_) const
33610447Snilay@cs.wisc.edu    {
33710447Snilay@cs.wisc.edu        return m_area_map_->keyExist(area_name_);
33810447Snilay@cs.wisc.edu    }
33910447Snilay@cs.wisc.edu
34010447Snilay@cs.wisc.edu    void Model::addNddPowerResult(Result* ndd_power_)
34110447Snilay@cs.wisc.edu    {
34210447Snilay@cs.wisc.edu        const String& ndd_power_name = ndd_power_->getName();
34310447Snilay@cs.wisc.edu
34410447Snilay@cs.wisc.edu        // Throw an Exception if the ndd_power already exists
34510447Snilay@cs.wisc.edu        if(m_ndd_power_map_->keyExist(ndd_power_name))
34610447Snilay@cs.wisc.edu        {
34710447Snilay@cs.wisc.edu            const String& error_msg = "Internal error: ndd_power (" + ndd_power_name +
34810447Snilay@cs.wisc.edu                ") exists";
34910447Snilay@cs.wisc.edu            throw Exception(error_msg);
35010447Snilay@cs.wisc.edu        }
35110447Snilay@cs.wisc.edu
35210447Snilay@cs.wisc.edu        // Add the ndd_power
35310447Snilay@cs.wisc.edu        m_ndd_power_map_->set(ndd_power_name, ndd_power_);
35410447Snilay@cs.wisc.edu        return;
35510447Snilay@cs.wisc.edu    }
35610447Snilay@cs.wisc.edu
35710447Snilay@cs.wisc.edu    Result* Model::getNddPowerResult(const String& ndd_power_name_)
35810447Snilay@cs.wisc.edu    {
35910447Snilay@cs.wisc.edu        return m_ndd_power_map_->get(ndd_power_name_);
36010447Snilay@cs.wisc.edu    }
36110447Snilay@cs.wisc.edu
36210447Snilay@cs.wisc.edu    const Result* Model::getNddPowerResult(const String& ndd_power_name_) const
36310447Snilay@cs.wisc.edu    {
36410447Snilay@cs.wisc.edu        return m_ndd_power_map_->get(ndd_power_name_);
36510447Snilay@cs.wisc.edu    }
36610447Snilay@cs.wisc.edu
36710447Snilay@cs.wisc.edu    bool Model::hasNddPowerResult(const String& ndd_power_name_) const
36810447Snilay@cs.wisc.edu    {
36910447Snilay@cs.wisc.edu        return m_ndd_power_map_->keyExist(ndd_power_name_);
37010447Snilay@cs.wisc.edu    }
37110447Snilay@cs.wisc.edu
37210447Snilay@cs.wisc.edu    void Model::addEventResult(Result* event_)
37310447Snilay@cs.wisc.edu    {
37410447Snilay@cs.wisc.edu        const String& event_name = event_->getName();
37510447Snilay@cs.wisc.edu
37610447Snilay@cs.wisc.edu        // Throw an Exception if the event already exists
37710447Snilay@cs.wisc.edu        if(m_event_map_->keyExist(event_name))
37810447Snilay@cs.wisc.edu        {
37910447Snilay@cs.wisc.edu            const String& error_msg = "Internal error: event (" + event_name +
38010447Snilay@cs.wisc.edu                ") exists";
38110447Snilay@cs.wisc.edu            throw Exception(error_msg);
38210447Snilay@cs.wisc.edu        }
38310447Snilay@cs.wisc.edu
38410447Snilay@cs.wisc.edu        // Add the event
38510447Snilay@cs.wisc.edu        m_event_map_->set(event_name, event_);
38610447Snilay@cs.wisc.edu        return;
38710447Snilay@cs.wisc.edu    }
38810447Snilay@cs.wisc.edu
38910447Snilay@cs.wisc.edu    Result* Model::getEventResult(const String& event_name_)
39010447Snilay@cs.wisc.edu    {
39110447Snilay@cs.wisc.edu        return m_event_map_->get(event_name_);
39210447Snilay@cs.wisc.edu    }
39310447Snilay@cs.wisc.edu
39410447Snilay@cs.wisc.edu    const Result* Model::getEventResult(const String& event_name_) const
39510447Snilay@cs.wisc.edu    {
39610447Snilay@cs.wisc.edu        return m_event_map_->get(event_name_);
39710447Snilay@cs.wisc.edu    }
39810447Snilay@cs.wisc.edu
39910447Snilay@cs.wisc.edu    bool Model::hasEventResult(const String& event_name_) const
40010447Snilay@cs.wisc.edu    {
40110447Snilay@cs.wisc.edu        return m_event_map_->keyExist(event_name_);
40210447Snilay@cs.wisc.edu    }
40310447Snilay@cs.wisc.edu
40410447Snilay@cs.wisc.edu    const TechModel* Model::getTechModel() const
40510447Snilay@cs.wisc.edu    {
40610447Snilay@cs.wisc.edu        return m_tech_model_;
40710447Snilay@cs.wisc.edu    }
40810447Snilay@cs.wisc.edu
40910447Snilay@cs.wisc.edu    const void* Model::parseQuery(const String& query_type_, const String& query_hier_, const String& query_sub_field_)
41010447Snilay@cs.wisc.edu    {
41110447Snilay@cs.wisc.edu        // Break query by hierarchy separator
41210447Snilay@cs.wisc.edu        vector<String> hier_split = query_hier_.splitByString(HIERARCHY_SEPARATOR);
41310447Snilay@cs.wisc.edu
41410447Snilay@cs.wisc.edu        // Check if the query_hier matches the instance name
41510447Snilay@cs.wisc.edu        ASSERT((hier_split[0] == m_instance_name_), "[Error] " +
41610447Snilay@cs.wisc.edu                m_instance_name_ + " -> Mismatch in instance name (" +
41710447Snilay@cs.wisc.edu                hier_split[0] + ")");
41810447Snilay@cs.wisc.edu
41910447Snilay@cs.wisc.edu        // If there is no more hierarchy separator, this process the query
42010447Snilay@cs.wisc.edu        if(hier_split.size() == 1)
42110447Snilay@cs.wisc.edu        {
42210447Snilay@cs.wisc.edu            // Query the model
42310447Snilay@cs.wisc.edu            return processQuery(query_type_, query_sub_field_);
42410447Snilay@cs.wisc.edu        }
42510447Snilay@cs.wisc.edu        else
42610447Snilay@cs.wisc.edu        {
42710447Snilay@cs.wisc.edu            // Reconstruct the query
42810447Snilay@cs.wisc.edu            String temp_query_hier = hier_split[1];
42910447Snilay@cs.wisc.edu            for(int i = 2; i < (int)hier_split.size(); ++i)
43010447Snilay@cs.wisc.edu            {
43110447Snilay@cs.wisc.edu                temp_query_hier += HIERARCHY_SEPARATOR + hier_split[i];
43210447Snilay@cs.wisc.edu            }
43310447Snilay@cs.wisc.edu
43410447Snilay@cs.wisc.edu            // Get sub instance's name
43510447Snilay@cs.wisc.edu            const String& temp_sub_instance_name = hier_split[1];
43610447Snilay@cs.wisc.edu            ASSERT(m_sub_instances_->keyExist(temp_sub_instance_name), "[Error] " +
43710447Snilay@cs.wisc.edu                    m_instance_name_ + " -> No sub-instances queried (" +
43810447Snilay@cs.wisc.edu                    temp_sub_instance_name + ")");
43910447Snilay@cs.wisc.edu
44010447Snilay@cs.wisc.edu            return m_sub_instances_->get(temp_sub_instance_name)->getModel()->parseQuery(query_type_, temp_query_hier, query_sub_field_);
44110447Snilay@cs.wisc.edu        }
44210447Snilay@cs.wisc.edu    }
44310447Snilay@cs.wisc.edu
44410447Snilay@cs.wisc.edu    const void* Model::processQuery(const String& query_type_, const String& query_sub_field_)
44510447Snilay@cs.wisc.edu    {
44610447Snilay@cs.wisc.edu        if(query_type_ == "Property")
44710447Snilay@cs.wisc.edu        {
44810447Snilay@cs.wisc.edu            return getProperties();
44910447Snilay@cs.wisc.edu        }
45010447Snilay@cs.wisc.edu        else if(query_type_ == "Parameter")
45110447Snilay@cs.wisc.edu        {
45210447Snilay@cs.wisc.edu            return getParameters();
45310447Snilay@cs.wisc.edu        }
45410447Snilay@cs.wisc.edu        else if(query_type_.contain("Hier"))
45510447Snilay@cs.wisc.edu        {
45610447Snilay@cs.wisc.edu            return this;
45710447Snilay@cs.wisc.edu        }
45810447Snilay@cs.wisc.edu        else if(query_type_ == "Area")
45910447Snilay@cs.wisc.edu        {
46010447Snilay@cs.wisc.edu            return queryArea(query_sub_field_);
46110447Snilay@cs.wisc.edu        }
46210447Snilay@cs.wisc.edu        else if(query_type_ == "NddPower")
46310447Snilay@cs.wisc.edu        {
46410447Snilay@cs.wisc.edu            return queryNddPower(query_sub_field_);
46510447Snilay@cs.wisc.edu        }
46610447Snilay@cs.wisc.edu        else if(query_type_ == "Energy")
46710447Snilay@cs.wisc.edu        {
46810447Snilay@cs.wisc.edu            return queryEventEnergyCost(query_sub_field_);
46910447Snilay@cs.wisc.edu        }
47010447Snilay@cs.wisc.edu        else
47110447Snilay@cs.wisc.edu        {
47210447Snilay@cs.wisc.edu            const String& error_msg = "[Error] " + m_instance_name_ + " -> Unknown query type (" + query_type_ + ")";
47310447Snilay@cs.wisc.edu            throw Exception(error_msg);
47410447Snilay@cs.wisc.edu            return NULL;
47510447Snilay@cs.wisc.edu        }
47610447Snilay@cs.wisc.edu    }
47710447Snilay@cs.wisc.edu
47810447Snilay@cs.wisc.edu    const Result* Model::queryArea(const String& area_name_) const
47910447Snilay@cs.wisc.edu    {
48010447Snilay@cs.wisc.edu        ASSERT(m_area_map_->keyExist(area_name_), "[Error] " + m_instance_name_ +
48110447Snilay@cs.wisc.edu                " -> Unknown queried area name (" + area_name_ + ")");
48210447Snilay@cs.wisc.edu        return m_area_map_->get(area_name_);
48310447Snilay@cs.wisc.edu    }
48410447Snilay@cs.wisc.edu
48510447Snilay@cs.wisc.edu    const Result* Model::queryNddPower(const String& ndd_power_name_)
48610447Snilay@cs.wisc.edu    {
48710447Snilay@cs.wisc.edu        ASSERT(m_ndd_power_map_->keyExist(ndd_power_name_), "[Error] " + m_instance_name_ +
48810447Snilay@cs.wisc.edu                " -> Unknown queried ndd power name (" + ndd_power_name_ + ")");
48910447Snilay@cs.wisc.edu
49010447Snilay@cs.wisc.edu        use("Idle");
49110447Snilay@cs.wisc.edu        return m_ndd_power_map_->get(ndd_power_name_);
49210447Snilay@cs.wisc.edu    }
49310447Snilay@cs.wisc.edu
49410447Snilay@cs.wisc.edu    const Result* Model::queryEventEnergyCost(const String& event_name_)
49510447Snilay@cs.wisc.edu    {
49610447Snilay@cs.wisc.edu        ASSERT(m_event_map_->keyExist(event_name_), "[Error] " + m_instance_name_ +
49710447Snilay@cs.wisc.edu                " -> Unknown queried event name (" + event_name_ + ")");
49810447Snilay@cs.wisc.edu
49910447Snilay@cs.wisc.edu        use(event_name_);
50010447Snilay@cs.wisc.edu        return m_event_map_->get(event_name_);
50110447Snilay@cs.wisc.edu    }
50210447Snilay@cs.wisc.edu
50310447Snilay@cs.wisc.edu    // Update checks whether the model needs updating, whether all properties have been specified,
50410447Snilay@cs.wisc.edu    // and calls updateModel if update is necessary
50510447Snilay@cs.wisc.edu    void Model::construct()
50610447Snilay@cs.wisc.edu    {
50710447Snilay@cs.wisc.edu        // Model should not be constructed yet
50810447Snilay@cs.wisc.edu        ASSERT(!m_constructed_, "[Error] " + getInstanceName() + " -> Cannot construct an already contructed model!");
50910447Snilay@cs.wisc.edu        // Check if whether all needed parameters are defined
51010447Snilay@cs.wisc.edu        checkParameters();
51110447Snilay@cs.wisc.edu        constructModel();
51210447Snilay@cs.wisc.edu        m_constructed_ = true;
51310447Snilay@cs.wisc.edu        m_updated_ = false;
51410447Snilay@cs.wisc.edu        m_evaluated_ = false;
51510447Snilay@cs.wisc.edu        return;
51610447Snilay@cs.wisc.edu    }
51710447Snilay@cs.wisc.edu
51810447Snilay@cs.wisc.edu    // Update checks whether the model needs updating, whether all properties have been specified,
51910447Snilay@cs.wisc.edu    // and calls updateModel if update is necessary
52010447Snilay@cs.wisc.edu    void Model::update()
52110447Snilay@cs.wisc.edu    {
52210447Snilay@cs.wisc.edu        // Model should be constructed
52310447Snilay@cs.wisc.edu        ASSERT(m_constructed_, "[Error] " + getInstanceName() + " -> Cannot update an unconstructed model!");
52410447Snilay@cs.wisc.edu        // If the model needs updating (due to property change)
52510447Snilay@cs.wisc.edu        // an update is necessary
52610447Snilay@cs.wisc.edu        if (!m_updated_)
52710447Snilay@cs.wisc.edu        {
52810447Snilay@cs.wisc.edu            // Check if all properties needed exist
52910447Snilay@cs.wisc.edu            checkProperties();
53010447Snilay@cs.wisc.edu            updateModel();
53110447Snilay@cs.wisc.edu            m_updated_ = true;
53210447Snilay@cs.wisc.edu            m_evaluated_ = false;
53310447Snilay@cs.wisc.edu        }
53410447Snilay@cs.wisc.edu        return;
53510447Snilay@cs.wisc.edu    }
53610447Snilay@cs.wisc.edu
53710447Snilay@cs.wisc.edu    // Evaluate checks whether the model needs to be evaluated.
53810447Snilay@cs.wisc.edu    void Model::evaluate()
53910447Snilay@cs.wisc.edu    {
54010447Snilay@cs.wisc.edu        // Model should be constructed
54110447Snilay@cs.wisc.edu        ASSERT(m_constructed_, "[Error] " + getInstanceName() + " -> Cannot evaluate an unconstructed model!");
54210447Snilay@cs.wisc.edu        // Model should be updated
54310447Snilay@cs.wisc.edu        ASSERT(m_updated_, "[Error] " + getInstanceName() + " -> Cannot evaluate without first updating!");
54410447Snilay@cs.wisc.edu        // If the model needs evaluating
54510447Snilay@cs.wisc.edu        if (!m_evaluated_)
54610447Snilay@cs.wisc.edu        {
54710447Snilay@cs.wisc.edu            evaluateModel();
54810447Snilay@cs.wisc.edu            m_evaluated_ = true;
54910447Snilay@cs.wisc.edu        }
55010447Snilay@cs.wisc.edu
55110447Snilay@cs.wisc.edu        return;
55210447Snilay@cs.wisc.edu    }
55310447Snilay@cs.wisc.edu
55410447Snilay@cs.wisc.edu    void Model::use(const String& event_name_)
55510447Snilay@cs.wisc.edu    {
55610447Snilay@cs.wisc.edu        useModel(event_name_);
55710447Snilay@cs.wisc.edu        return;
55810447Snilay@cs.wisc.edu    }
55910447Snilay@cs.wisc.edu
56010447Snilay@cs.wisc.edu    void Model::use()
56110447Snilay@cs.wisc.edu    {
56210447Snilay@cs.wisc.edu        useModel();
56310447Snilay@cs.wisc.edu        return;
56410447Snilay@cs.wisc.edu    }
56510447Snilay@cs.wisc.edu
56610447Snilay@cs.wisc.edu    // By default, update model will iterate through all sub-instances and do updateModel on them
56710447Snilay@cs.wisc.edu    void Model::updateModel()
56810447Snilay@cs.wisc.edu    {
56910447Snilay@cs.wisc.edu        Map<SubModel*>::Iterator iter = m_sub_instances_->begin();
57010447Snilay@cs.wisc.edu        Map<SubModel*>::Iterator end = m_sub_instances_->end();
57110447Snilay@cs.wisc.edu        while (iter != end)
57210447Snilay@cs.wisc.edu        {
57310447Snilay@cs.wisc.edu            iter->second->getModel()->update();
57410447Snilay@cs.wisc.edu            iter++;
57510447Snilay@cs.wisc.edu        }
57610447Snilay@cs.wisc.edu        return;
57710447Snilay@cs.wisc.edu    }
57810447Snilay@cs.wisc.edu
57910447Snilay@cs.wisc.edu    // By default, update model will iterate through all sub-instances and do updateModel on them
58010447Snilay@cs.wisc.edu    void Model::evaluateModel()
58110447Snilay@cs.wisc.edu    {
58210447Snilay@cs.wisc.edu        Map<SubModel*>::Iterator iter = m_sub_instances_->begin();
58310447Snilay@cs.wisc.edu        Map<SubModel*>::Iterator end = m_sub_instances_->end();
58410447Snilay@cs.wisc.edu        while (iter != end)
58510447Snilay@cs.wisc.edu        {
58610447Snilay@cs.wisc.edu            iter->second->getModel()->evaluate();
58710447Snilay@cs.wisc.edu            iter++;
58810447Snilay@cs.wisc.edu        }
58910447Snilay@cs.wisc.edu        return;
59010447Snilay@cs.wisc.edu    }
59110447Snilay@cs.wisc.edu
59210447Snilay@cs.wisc.edu    void Model::useModel(const String& /* event_name_ */)
59310447Snilay@cs.wisc.edu    {}
59410447Snilay@cs.wisc.edu
59510447Snilay@cs.wisc.edu    void Model::useModel()
59610447Snilay@cs.wisc.edu    {}
59710447Snilay@cs.wisc.edu
59810447Snilay@cs.wisc.edu    void Model::printHierarchy(const String& query_type_, const String& query_sub_field_, const String& prepend_str_, int detail_level_, ostream& ost_) const
59910447Snilay@cs.wisc.edu    {
60010447Snilay@cs.wisc.edu        if(query_type_ == "InstHier")
60110447Snilay@cs.wisc.edu        {
60210447Snilay@cs.wisc.edu            ost_ << prepend_str_ << getInstanceName() << endl;
60310447Snilay@cs.wisc.edu            printInstHierarchy(prepend_str_, detail_level_, ost_);
60410447Snilay@cs.wisc.edu            //if(detail_level_ > 0)
60510447Snilay@cs.wisc.edu            //{
60610447Snilay@cs.wisc.edu                //for(Map<SubModel*>::ConstIterator it = m_sub_instances_->begin(); it != m_sub_instances_->end(); ++it)
60710447Snilay@cs.wisc.edu                //{
60810447Snilay@cs.wisc.edu                    //const Model* sub_model = (it->second)->getModel();
60910447Snilay@cs.wisc.edu                    //String temp_prepend_str = prepend_str_ + "    ";
61010447Snilay@cs.wisc.edu                    //sub_model->printHierarchy(query_type_, query_sub_field_, temp_prepend_str, detail_level_ - 1, ost_);
61110447Snilay@cs.wisc.edu                //}
61210447Snilay@cs.wisc.edu            //}
61310447Snilay@cs.wisc.edu        }
61410447Snilay@cs.wisc.edu        else
61510447Snilay@cs.wisc.edu        {
61610447Snilay@cs.wisc.edu            const Map<Result*>* result_map;
61710447Snilay@cs.wisc.edu
61810447Snilay@cs.wisc.edu            if(query_type_ == "AreaHier")
61910447Snilay@cs.wisc.edu            {
62010447Snilay@cs.wisc.edu                result_map = m_area_map_;
62110447Snilay@cs.wisc.edu            }
62210447Snilay@cs.wisc.edu            else if(query_type_ == "NddPowerHier")
62310447Snilay@cs.wisc.edu            {
62410447Snilay@cs.wisc.edu                result_map = m_ndd_power_map_;
62510447Snilay@cs.wisc.edu            }
62610447Snilay@cs.wisc.edu            else if(query_type_ == "EventHier")
62710447Snilay@cs.wisc.edu            {
62810447Snilay@cs.wisc.edu                result_map = m_event_map_;
62910447Snilay@cs.wisc.edu            }
63010447Snilay@cs.wisc.edu            else
63110447Snilay@cs.wisc.edu            {
63210447Snilay@cs.wisc.edu                const String& error_msg = "[Error] " + m_instance_name_ + " -> Unknown query type (" + query_type_ + ")";
63310447Snilay@cs.wisc.edu                throw Exception(error_msg);
63410447Snilay@cs.wisc.edu                return;
63510447Snilay@cs.wisc.edu            }
63610447Snilay@cs.wisc.edu
63710447Snilay@cs.wisc.edu            if(query_sub_field_ == "")
63810447Snilay@cs.wisc.edu            {
63910447Snilay@cs.wisc.edu                for(Map<Result*>::ConstIterator it = result_map->begin(); it != result_map->end(); ++it)
64010447Snilay@cs.wisc.edu                {
64110447Snilay@cs.wisc.edu                    const Result* result = it->second;
64210447Snilay@cs.wisc.edu                    ost_ << prepend_str_ << getInstanceName() << "->" << result->getName() << endl;
64310447Snilay@cs.wisc.edu                    result->printHierarchy(prepend_str_, detail_level_, ost_);
64410447Snilay@cs.wisc.edu                }
64510447Snilay@cs.wisc.edu            }
64610447Snilay@cs.wisc.edu            else
64710447Snilay@cs.wisc.edu            {
64810447Snilay@cs.wisc.edu                const Result* result = result_map->get(query_sub_field_);
64910447Snilay@cs.wisc.edu                ost_ << prepend_str_ << getInstanceName() << "->" << result->getName() << endl;
65010447Snilay@cs.wisc.edu                result->printHierarchy(prepend_str_, detail_level_, ost_);
65110447Snilay@cs.wisc.edu            }
65210447Snilay@cs.wisc.edu        }
65310447Snilay@cs.wisc.edu        return;
65410447Snilay@cs.wisc.edu    }
65510447Snilay@cs.wisc.edu
65610447Snilay@cs.wisc.edu    void Model::printInstHierarchy(const String& prepend_str_, int detail_level_, ostream& ost_) const
65710447Snilay@cs.wisc.edu    {
65810447Snilay@cs.wisc.edu        if(detail_level_ > 0)
65910447Snilay@cs.wisc.edu        {
66010447Snilay@cs.wisc.edu            for(Map<SubModel*>::ConstIterator it = m_sub_instances_->begin(); it != m_sub_instances_->end(); ++it)
66110447Snilay@cs.wisc.edu            {
66210447Snilay@cs.wisc.edu                const Model* sub_model = it->second->getModel();
66310447Snilay@cs.wisc.edu                String temp_prepend_str = prepend_str_ + "    ";
66410447Snilay@cs.wisc.edu
66510447Snilay@cs.wisc.edu                ost_ << prepend_str_ << " |--" << sub_model->getInstanceName() << endl;
66610447Snilay@cs.wisc.edu                sub_model->printInstHierarchy(temp_prepend_str, detail_level_ - 1, ost_);
66710447Snilay@cs.wisc.edu            }
66810447Snilay@cs.wisc.edu        }
66910447Snilay@cs.wisc.edu        return;
67010447Snilay@cs.wisc.edu    }
67110447Snilay@cs.wisc.edu
67210447Snilay@cs.wisc.edu    Model* Model::clone() const
67310447Snilay@cs.wisc.edu    {
67410447Snilay@cs.wisc.edu        throw Exception(getInstanceName() + " -> Cannot be cloned!");
67510447Snilay@cs.wisc.edu    }
67610447Snilay@cs.wisc.edu
67710447Snilay@cs.wisc.edu    Model::Model(const Model& model_)
67810447Snilay@cs.wisc.edu    {
67910447Snilay@cs.wisc.edu        // Copy instance's name
68010447Snilay@cs.wisc.edu        m_instance_name_ = model_.m_instance_name_;
68110447Snilay@cs.wisc.edu
68210447Snilay@cs.wisc.edu        // Clone properties
68310447Snilay@cs.wisc.edu        m_properties_ = model_.m_properties_->clone();
68410447Snilay@cs.wisc.edu
68510447Snilay@cs.wisc.edu        // Clone instances
68610447Snilay@cs.wisc.edu        m_sub_instances_ = clonePtrMap(model_.m_sub_instances_);
68710447Snilay@cs.wisc.edu
68810447Snilay@cs.wisc.edu        // Clone events, area, ndd_power
68910447Snilay@cs.wisc.edu        m_event_map_ = clonePtrMap(model_.m_event_map_);
69010447Snilay@cs.wisc.edu        m_area_map_ = clonePtrMap(model_.m_area_map_);
69110447Snilay@cs.wisc.edu        m_ndd_power_map_ = clonePtrMap(model_.m_ndd_power_map_);
69210447Snilay@cs.wisc.edu
69310447Snilay@cs.wisc.edu        // Copy tech model pointer
69410447Snilay@cs.wisc.edu        m_tech_model_ = model_.m_tech_model_;
69510447Snilay@cs.wisc.edu    }
69610447Snilay@cs.wisc.edu
69710447Snilay@cs.wisc.edu} // namespace DSENT
69810447Snilay@cs.wisc.edu
699