?? rsesrules.cpp
字號:
//-------------------------------------------------------------------
// Author........: Aleksander 豩rn
// Date..........:
// Description...: The data logically belonging to the RSESRules
// object may physically "belong" to the parent
// RSESReducts object.
// Revisions.....:
//===================================================================
#include <stdafx.h> // Precompiled headers.
#include <copyright.h>
#include <kernel/rses/structures/rsesrules.h>
#include <kernel/rses/structures/rsesrule.h>
#include <kernel/rses/library/trule.h>
#include <kernel/rses/library/treduct.h>
#include <kernel/rses/library/trr_mem.h>
#include <kernel/rses/library/err.h>
#include <kernel/utilities/creator.h>
#include <kernel/basic/message.h>
//-------------------------------------------------------------------
// Methods for class RSESRules.
//===================================================================
//-------------------------------------------------------------------
// Constructors/destructor.
//===================================================================
//-------------------------------------------------------------------
// Method........: Copy constructor
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Deep or shallow pointer copy?
// Revisions.....:
//===================================================================
RSESRules::RSESRules(const RSESRules &in) : Rules(in) {
rules_ = in.rules_;
is_owner_ = false;
}
//-------------------------------------------------------------------
// Method........: Constructor
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
RSESRules::RSESRules() {
rules_ = NULL;
is_owner_ = false;
}
//-------------------------------------------------------------------
// Method........: Destructor
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Note that a call to Clear() assumes that a set of
// RSES reducts only supports one rule set as a child,
// something that is presently true due to the current
// status of the RSES library.
//
// Embedded TRedRulMem object is typically "owned" by
// the parent reduct set.
// Revisions.....:
//===================================================================
RSESRules::~RSESRules() {
// Remove all rules.
RemoveAllStructures();
if (is_owner_)
delete rules_;
}
//-------------------------------------------------------------------
// Methods inherited from Identifier.
//===================================================================
IMPLEMENTIDMETHODS(RSESRules, RSESRULES, Rules)
//-------------------------------------------------------------------
// Methods inherited from Persistent.
//===================================================================
//-------------------------------------------------------------------
// Method........: Load
// Author........: Aleksander 豩rn
// Date..........:
// Description...: A RSESRules object doesn't necessarily per se contain
// any data, the (embedded) data may "belong" to
// the parent RSESReducts object.
//
// Should find a way to deal with this properly, so that
// one can logically save only a set of rules...
//
// Comments......: BUG: Does not load any children! Should call
// ParentStructure::Load instead!
//
// Revisions.....:
//===================================================================
bool
RSESRules::Load(ifstream &stream) {
// Load stuff higher up.
if (!AnnotatedStructure::Load(stream))
return false;
return true;
}
//-------------------------------------------------------------------
// Method........: Save
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Cf. comments of corresponding Load method.
//
// BUG: Does not save any children! Should call
// ParentStructure::Save instead!
//
// Revisions.....:
//===================================================================
bool
RSESRules::Save(ofstream &stream) const {
// Save stuff higher up.
if (!AnnotatedStructure::Save(stream))
return false;
if (is_owner_)
Message::Warning("Set of RSES rules (" + GetName() + ") not saved.");
if (HasChildren())
Message::Warning("Children of \"" + GetName() + "\" not saved.", false);
return true;
}
//-------------------------------------------------------------------
// Methods inherited from Structure.
//===================================================================
//------------------------------------------------------------------
// Method........: Duplicate
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Duplication of embedded RSES rules is not really
// done, only wrappers are duplicated. This
// method should therefore be used with utmost care.
//
// The only reason this method does not return NULL
// by default, is so that the Creator can create
// "virgin" RSESRules objects. The number of wrappers
// is then 0, so it really doesn't matter in that
// particular case.
// Revisions.....:
//===================================================================
Structure *
RSESRules::Duplicate() const {
// Is duplication possible?
if (GetNoStructures() > 0) {
Message::Error("Non-empty RSES rule sets cannot be duplicated.\n"
"Duplicate the parent RSES reduct set instead.");
return NULL;
}
return new RSESRules(*this);
}
//------------------------------------------------------------------
// Method........: Clear
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Note that this affects the embedded object of the
// (wrapperwise logically independent) parent RSES
// reduct set. Use therefore this method with utmost
// care.
// Revisions.....:
//===================================================================
void
RSESRules::Clear() {
RemoveAllStructures();
}
//-------------------------------------------------------------------
// Methods inherited from Structures.
//===================================================================
//------------------------------------------------------------------
// Method........: InsertStructure
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Overloaded to check for consistency/homogenity.
// Ensures that only RSES rules are inserted. Also,
// checks their reduct origins.
//
// Comments......: AppendStructure is not necessary to overload, since
// Structures::AppendStructure is implemented via the
// InsertStructure method.
//
// Having to check membership in the embedded TRedRulMem
// is very inefficient.
// Revisions.....:
//===================================================================
bool
RSESRules::InsertStructure(Structure *structure, int i) {
// Valid input?
if (structure == NULL) {
Message::Error("Cannot insert a NULL rule.");
return false;
}
// Structure of correct type?
if (!structure->IsA(RSESRULE)) {
Message::Error("Cannot insert a non-RSES rule into a RSES rule set.");
return false;
}
// Cast to verified type.
Handle<RSESRule> rule = dynamic_cast(RSESRule *, structure);
// Get originating RSES reduct.
TReduct *rsesreduct = rule->reduct_;
if (rsesreduct == NULL) {
Message::Error("The RSES reduct embedded in the RSES rule is NULL.");
return false;
}
// Is there a TRedRulMem object to insert into?
if (rules_ == NULL) {
Message::Error("The embedded RSES reduct and rule memory is NULL.");
return false;
}
int position = Undefined::Integer();
// Is the originating RSES reduct a member of the embedded reduct and rule memory?
try {
int i, no_reducts = rules_->NoReducts();
// Locate position index, if present.
for (i = no_reducts - 1; i >= 0; i--) {
if (rules_->GetRed(i) == rsesreduct) {
position = i;
break;
}
}
}
// Catch any RSES exceptions.
catch (Error &error) {
Message::RSESError("Error accessing embedded TRedRulMem object.", error.GetMessage());
return false;
}
bool is_member = (position != Undefined::Integer());
// If the originating RSES reduct was not a member, add it.
if (!is_member) {
Message::Error("Addition of non-member RSESReduct not implemented yet.\n"
"Not yet determined how to handle associated rules, if more than one.");
return false;
}
// We've already verified TRedRulMem membership and consistency.
bool verify = false;
return InsertRule(rule.GetPointer(), i, *rsesreduct, verify, position);
}
//------------------------------------------------------------------
// Method........: RemoveStructure
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
RSESRules::RemoveStructure(int i) {
// Get the rule wrapper to remove.
Handle<RSESRule> rule = dynamic_cast(RSESRule *, GetStructure(i));
if (rule == NULL) {
Message::Error("Unable to acquire rule to remove.");
return false;
}
// Get the originating RSES reduct.
TReduct *reduct = rule->reduct_;
if (reduct == NULL) {
Message::Error("Unable to acquire originating reduct of rule to remove.");
return false;
}
int position = Undefined::Integer();
// Remove the embedded rule from the embedded reduct.
try {
int i, no_rules = reduct->NoRules();
// Find out in which position in the embedded reduct the embedded rule lies.
for (i = 0 ; i < no_rules; i++) {
if (reduct->GetRule(i) == rule->rule_) {
position = i;
break;
}
}
// Was a position index found?
if (position == Undefined::Integer()) {
Message::Error("The embedded rule could not be found as a child of the embedded parent reduct.");
return false;
}
// Do the removal.
reduct->RemoveRule(position);
}
// Catch any RSES exceptions.
catch (Error &error) {
Message::RSESError("Error accessing the embedded RSES library objects.", error.GetMessage());
return false;
}
// Remove the rule wrapper.
if (!Structures::RemoveStructure(i)) {
Message::Error("Error removing rule wrapper from structure set.");
return false;
}
return true;
}
//------------------------------------------------------------------
// Method........: RemoveAllStructures
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
RSESRules::RemoveAllStructures() {
// Remove all wrappers.
if (!Structures::RemoveAllStructures()) {
Message::Error("Failed to remove all wrapper structures.");
return false;
}
// Does the embedded reduct and rule memory exist?
if (rules_ == NULL)
return true;
// Do the clearing.
try {
rules_->ClearRules();
}
catch (Error &error) {
Message::RSESError("Error clearing rules from parent reduct set's embedded RSES reduct and rule memory.", error.GetMessage());
return false;
}
return true;
}
//-------------------------------------------------------------------
// Methods inherited from Rules.
//===================================================================
//-------------------------------------------------------------------
// Method........: Sort
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Sorts the wrappers only.
// Revisions.....:
//===================================================================
bool
RSESRules::Sort(int property, bool ascending, const Handle<DecisionTable> table) {
return Rules::Sort(property, ascending, table);
}
//-------------------------------------------------------------------
// Local methods.
//===================================================================
//------------------------------------------------------------------
// Method........: GetNoRules
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns the number of rules in the rule set that
// are derived from the specified reduct (i.e. have
// the specified reduct as a parent).
//
// Comments......: Inefficient initial implementation, optimize.
// Revisions.....:
//===================================================================
int
RSESRules::GetNoRules(const TReduct &rsesreduct, int index) const {
if (rules_ == NULL)
return 0;
#ifdef _DEBUG
bool is_member = false;
// Is the input reduct really a member of the parent reduct set? If so, all
// embedded rules of the input reduct are assumed to be (embedded) members of
// this rule set.
try {
int i, no_reducts = rules_->NoReducts();
// Check suggested index, if given.
if (index >= 0 && index < no_reducts)
is_member = (rules_->GetRed(index) == &rsesreduct);
// Scan through all reducts if suggested index failed.
if (!is_member) {
for (i = no_reducts - 1; i >= 0; i--) {
if (rules_->GetRed(i) == &rsesreduct) {
is_member = true;
break;
}
}
}
}
// Catch any RSES exceptions.
catch (Error &error) {
Message::RSESError("Error accessing embedded RSES object.", error.GetMessage());
return 0;
}
if (!is_member) {
Message::Error("Argument reduct is not a member of the parent RSES reduct set.");
return 0;
}
#endif
// Return the number of rules associated with the input reduct.
// For some reason, TReduct::NoRules is not a const method...
try {
return const_cast(TReduct &, rsesreduct).NoRules();
}
catch (Error &error) {
Message::RSESError("Error accessing embedded RSES reduct.", error.GetMessage());
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -