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