📄 rsesrules.cpp
字号:
}
//------------------------------------------------------------------
// Method........: GetRule
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns the specified rule in the rule set that
// has the specified reduct as a parent.
//
// The index argument is relative to the specified
// reduct, not the whole rule set. (This in contrast
// to the InsertRule method.)
//
// Cf. description of the GetNoRules(const TReduct &)
// method.
//
// Comments......: Inefficient initial implementation, optimize.
//
// Should eliminate the index argument relativeness
// inconsistency and make all index arguments
// semantically uniform.
// Revisions.....:
//===================================================================
Rule *
RSESRules::GetRule(int i, const TReduct &rsesreduct, int index) const {
#ifdef _DEBUG
// Is index in range?
if ((i < 0) || (i >= GetNoRules(rsesreduct, index))) {
Message::Error("Rule index out of range.");
return NULL;
}
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
TRule *embedded;
// Get the embedded rule. For some reason, TReduct::GetRule is not a const method...
try {
embedded = const_cast(TReduct &, rsesreduct).GetRule(i);
}
catch (Error &error) {
Message::RSESError("Error accessing embedded RSES reduct.", error.GetMessage());
return NULL;
}
int j, no_wrappers = GetNoStructures();
// Find the right wrapper.
for (j = no_wrappers - 1; j >= 0; j--) {
// Get current wrapper.
Handle<RSESRule> wrapper = dynamic_cast(RSESRule *, GetStructure(j));
// Match?
if (wrapper->rule_ == embedded)
return wrapper.GetPointer();
}
return NULL;
}
//------------------------------------------------------------------
// Method........: InsertRule
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Inserts a rule with a specified parent reduct into
// the rule set.
//
// The index argument is relative to the full set of
// rules, not the specified reduct. (This in contrast
// to the GetRule method.)
//
// Comments......: Should eliminate the index argument relativeness
// inconsistency and make all index arguments
// semantically uniform.
// Revisions.....:
//===================================================================
bool
RSESRules::InsertRule(RSESRule *rule, int i, TReduct &rsesreduct, bool verify, int index) {
// Is the insertion really an append operation?
if (i == GetNoStructures())
return AppendRule(rule, rsesreduct, verify, index);
Message::Error("The RSES library does not support general insertion of rules into a rule set, append instead.");
return false;
}
//------------------------------------------------------------------
// Method........: AppendRule
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Appends a rule with a specified parent reduct to
// the rule set. The appendation is done relative to
// the whole rule set, not relative to the specified
// reduct.
//
// Cf. description of the InsertRule method.
//
// Comments......: Inefficient initial implementation, optimize.
// Revisions.....:
//===================================================================
bool
RSESRules::AppendRule(RSESRule *rule, TReduct &rsesreduct, bool verify, int index) {
// Is the input valid?
if (rule == NULL) {
Message::Error("Cannot append a NULL rule to the rule set.");
return false;
}
// Is the reduct a parent of the rule?
if (rule->reduct_ != &rsesreduct) {
Message::Error("Argument reduct is not a parent of argument rule.");
return false;
}
// Is there a RSES reduct and rule memory to append rule to?
if (rules_ == NULL) {
Message::Error("Argument reduct is not a parent of argument rule.");
return false;
}
// If we're not to verify RSES consistency, append the rule to the set
// of wrappers and return.
if (!verify)
return Structures::InsertStructure(rule, GetNoStructures());
bool is_member = false;
// Is the input reduct really a member of the RSES reduct and rule memory? 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 reduct memory.", error.GetMessage());
return false;
}
if (!is_member) {
Message::Error("Argument reduct is not a member of the embedded RSES reduct memory.");
return false;
}
// Is the embedded rule already attached to the embedded reduct?
try {
int i, no_rules = rsesreduct.NoRules();
// Check attached rules.
for (i = 0; i < no_rules; i++) {
if (rsesreduct.GetRule(i) == rule->rule_)
break;
}
// Rule not attached, attach it!
if (i == no_rules) {
rsesreduct.AddRule(rule->rule_);
rule->is_rule_owner_ = false;
}
}
// Catch any RSES exceptions.
catch (Error &error) {
Message::RSESError("Error accessing embedded RSES reduct or rule.", error.GetMessage());
return false;
}
// Append the rule to the set of wrappers.
return Structures::InsertStructure(rule, GetNoStructures());
}
//------------------------------------------------------------------
// Method........: RemoveRule
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Removes a rule with a specified parent reduct from
// the rule set.
//
// Cf. description of the GetRule/InsertRule for a
// discussion about the interpretation of the index
// argument.
//
// Comments......: This method might not be necessary to implement,
// can use the inherited RemoveStructure(int i) instead.
// Consider therefore deleting this method altogether.
// Revisions.....:
//===================================================================
bool
RSESRules::RemoveRule(int /*i*/, TReduct &/*rsesreduct*/, int /*index*/) {
// Give an error message.
Message::Error("RSESRules::RemoveRule(int, TReduct &, int) not implemented.");
return false;
}
//------------------------------------------------------------------
// Method........: RemoveAllRules
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Removes all rules from the rule set that have a
// specified reduct as parent. .
// Comments......: Inefficient initial implementation, optimize.
// Revisions.....:
//===================================================================
bool
RSESRules::RemoveAllRules(TReduct &rsesreduct, int index) {
if (rules_ == NULL)
return true;
#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 false;
}
if (!is_member) {
Message::Error("Argument reduct is not a member of the parent RSES reduct set.");
return false;
}
#endif
// Remove embedded rules.
try {
rsesreduct.ClearRules();
}
catch (Error &error) {
Message::RSESError("Error accessing embedded RSES reduct.", error.GetMessage());
return false;
}
int i;
// Remove rule wrappers.
for (i = GetNoStructures() - 1; i >= 0; i--) {
// Get current wrapper.
Handle<RSESRule> wrapper = dynamic_cast(RSESRule *, GetStructure(i));
// Check that embedded objects match.
if (&rsesreduct != wrapper->reduct_)
continue;
// Do removal.
if (!Structures::RemoveStructure(i)) {
Message::Error("Error removing rule wrappers.");
return false;
}
}
return true;
}
//-------------------------------------------------------------------
// Local methods.
//===================================================================
//-------------------------------------------------------------------
// Method........: BuildWrappers
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Builds a wrapper object for each individual embedded
// rule object from the RSES library.
//
// Assumes that wrapper classes for the parent
// RSESReducts structure are already built.
//
// Wrappers are created so there is a "linear"
// correspondence between the indices of the wrappers
// and the indices into rules in the embedded TRedRulMem
// object.
//
// Comments......: Structures::InsertStructures used to avoid
// adding an embedded rule to the embedded reduct and
// rule memory when it is already a member. (Since
// most/all methods from Structures are overloaded.)
// For similiar reasons, the Structures:: qualifier
// is used elsewhere too, when appropriate.
//
// Revisions.....:
//===================================================================
bool
RSESRules::BuildWrappers() {
int i, j, no_rules = GetNoStructures();
// Remove any wrappers already present (keeping the embedded objects).
if (no_rules > 0) {
for (i = no_rules - 1; i >= 0; i--) {
if (!Structures::RemoveStructure(i)) {
Message::Error("Failed to remove existing wrapper before building new ones.");
return false;
}
}
}
// Does the reduct and rule memory exist?
if (rules_ == NULL)
return false;
// Create wrappers for individual rule objects.
try {
// Determine how many reducts to check.
int no_reducts = rules_->NoReducts();
// Check all reducts.
for (i = 0; i < no_reducts; i++) {
// Get the reduct.
TReduct *reduct = rules_->GetRed(i);
// Determine how many rules are attached to the RSES reduct.
no_rules = reduct->NoRules();
// Build wrappers.
for (j = 0; j < no_rules; j++) {
// Get the rule to embed.
TRule *rule = reduct->GetRule(j);
// Instantiate a wrapper.
Handle<RSESRule> wrapper = Creator::RSESRule();
// Delete the default contents of the wrapper, and substitute it with new ones.
delete wrapper->rule_;
delete wrapper->reduct_;
wrapper->rule_ = rule;
wrapper->reduct_ = reduct;
wrapper->is_rule_owner_ = false;
wrapper->is_reduct_owner_ = false;
// Insert the wrapper into the wrapper list.
if (!Structures::InsertStructure(wrapper.GetPointer(), Structures::GetNoStructures())) {
Message::Error("Error inserting individual rule wrapper.");
return false;
}
}
}
}
// Catch any RSES exceptions.
catch (Error &error) {
Message::RSESError("Error accessing embedded RSES object, wrappers not properly built.", error.GetMessage());
return false;
}
return true;
}
//-------------------------------------------------------------------
// Method........: TakeOwnership
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
void
RSESRules::TakeOwnership(bool ownership) {
// Set ownership flag for the TRedRulMem structure.
is_owner_ = ownership;
int i, no_rules = GetNoStructures();
// None of the wrappers own the embedded TReduct or TRule objects, the TRedRulMem object
// takes ownership once a TReduct object (with associated TRule objects) is added to the pool.
for (i = 0; i < no_rules; i++) {
// Get wrapper around RSES rule.
Handle<RSESRule> wrapper = dynamic_cast(RSESRule *, GetStructure(i));
// Set ownership flag for the embedded RSES structures.
wrapper->is_reduct_owner_ = false;
wrapper->is_rule_owner_ = false;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -