📄 ie.cpp
字号:
#include "ie.h"
#include "iegoal.h"
#include "ieexec.h"
#include "ierule.h"
#include <assert.h>
static bool dbg = false;
//===========================================================================
// Name:
// start
//
// Description:
// Start an inference engine goal set.
//
// Parameters:
// name - The name of the goal set.
//
// Return Value:
// None.
//
// Remarks:
//
//===========================================================================
void IE::start ( char * name, IEOwner * owner )
{
m_name = name;
m_owner = owner;
m_curGoal = NULL;
m_curRule = NULL;
m_nextGoal = NULL;
}
//===========================================================================
// Name:
// end
//
// Description:
// End the goal set. Link up the goal pointers in the rules.
//
// Parameters:
// None.
//
// Return Value:
// None.
//
// Remarks:
//
//===========================================================================
void IE::end ()
{
// link the rules to their goals via the goal name
linkRuleGoals();
// set current goal to the first goal
m_curGoal = m_goalList.front();
// push goal on stack
pushGoal ( m_curGoal );
}
//===========================================================================
// Name:
// makeGoal
//
// Description:
// Make a new goal and add it to the end of the goal list.
//
// Parameters:
// name - The name of the goal.
//
// Return Value:
// None.
//
// Remarks:
//
//===========================================================================
void IE::makeGoal ( IEExec * exec )
{
if ( !exec )
return;
// new goal
m_curGoal = new IEGoal ( exec );
// initialize goal
exec->init( m_owner );
// add it to the end of the goal list
m_goalList.push_back ( m_curGoal );
}
//===========================================================================
// Name:
// makeRule
//
// Description:
// Make a new rule and add it to the current goal.
//
// Parameters:
// condition - Pointer to the conditional object for the rule.
// lineInfo - Description of the line the makeRule macro is on. (for debug)
//
// Return Value:
// None.
//
// Remarks:
// This method expects a 'current' goal to have been established by a call
// to makeGoal.
//===========================================================================
void IE::makeRule ( IEExec * condition, char * lineInfo )
{
// make sure there is a current goal established
if ( ! m_curGoal )
{
printf ( "ERROR: No goal specified for rule at %s.\n", lineInfo );
return;
}
// check the type of the conditional object to make
// sure it matches the type of the goal set
#if 0
if ( condition->getType() != m_type )
{
printf ( "ERROR: Condition %s at %s invalid type of %d.\n",
condition->getName(), lineInfo, condition->getType() );
return;
}
#endif
// make a new rule
m_curRule = new IERule( condition );
// initialize rule condition exec
condition->init( m_owner );
// add the rule to the current goal
m_curGoal->addRule ( m_curRule );
}
//===========================================================================
// Name:
// addRuleGoto
//
// Description:
// Make the current rule a goto rule.
//
// Parameters:
// goalName - The name of the goal to goto to.
// lineInfo - Debug info for the macro setting the goto portion. (debug)
//
// Return Value:
// None.
//
// Remarks:
// This method expects a current rule to have been established via makeRule.
//===========================================================================
void IE::addRuleGoto ( char * goalName, char * lineInfo )
{
if ( noRule ( lineInfo ) )
return;
m_curRule->setGoal ( goalName, lineInfo );
m_curRule->setType ( IERule::Goto );
m_curRule->m_name = "If_";
m_curRule->m_name += m_curRule->m_condition->getName();
m_curRule->m_name += "_Goto_";
m_curRule->m_name += goalName;
}
//===========================================================================
// Name:
// addRuleGosub
//
// Description:
// Make the current rule a gosub rule.
//
// Parameters:
// goalName - The name of the goal to gosub.
// lineInfo - Debug info for the macro setting the gosub portion. (debug)
//
// Return Value:
// None.
//
// Remarks:
// This method expects a current rule to have been established via makeRule.
//===========================================================================
void IE::addRuleGosub ( char * goalName, char * lineInfo )
{
if ( noRule ( lineInfo ) )
return;
m_curRule->setGoal ( goalName, lineInfo );
m_curRule->setType ( IERule::Gosub );
m_curRule->m_name = "If_";
m_curRule->m_name += m_curRule->m_condition->getName();
m_curRule->m_name += "_Gosub_";
m_curRule->m_name += goalName;
}
//===========================================================================
// Name:
// addRuleReturn
//
// Description:
// Make the current rule a return rule.
//
// Parameters:
// lineInfo - Debug info for the macro setting the return portion. (debug)
//
// Return Value:
// None.
//
// Remarks:
// This method expects a current rule to have been established via makeRule.
// A goal name is not need because a return rule will return to the goal
// that transfered to the current goal, whether through a goto or gosub.
//===========================================================================
void IE::addRuleReturn ( char * lineInfo )
{
if ( noRule ( lineInfo ) )
return;
m_curRule->setType ( IERule::Return );
m_curRule->setGoal ( m_curGoal );
m_curRule->m_name = "If_";
m_curRule->m_name += m_curRule->m_condition->getName();
m_curRule->m_name += "_Return";
}
//===========================================================================
// Name:
// update
//
// Description:
// Main update for the inference engine. Processes goal start, finish, and
// rule sets. Pushs, Pops, and transfers goal control based on returns from
// rule conditionals.
//
// Parameters:
// None.
//
// Return Value:
// None.
//
// Remarks:
//
//===========================================================================
void IE::update ()
{
assert ( m_curGoal );
// if at the start of the current goal
checkStart();
// if trying to finish the current goal
if ( ! checkFinish() )
return;
// process all rules for all goals on the stack
std::list<IEGoal *>::iterator goalItr;
std::list<IERule *>::iterator ruleItr;
IEGoal * goal;
IERule * rule;
// first, see if goal alread on the stack
goalItr = m_goalStack.begin();
bool ruleFired = false;
while ( goalItr != m_goalStack.end() && ! ruleFired )
{
goal = *goalItr++;
ruleItr = goal->m_rules.begin();
while ( ruleItr != goal->m_rules.end() )
{
rule = *ruleItr++;
// if rule already fired then skip (for rules on stack)
if ( rule->m_fired )
continue;
if ( dbg ) printf ( "Rule %s tested.\n", rule->getName() );
if ( rule->m_condition->update() == true )
{
if ( dbg ) printf ( "\tFired.\n" );
rule->m_fired = true;
// get the goal for this rule
m_nextGoal = rule->getGoal();
assert( m_nextGoal );
if ( dbg ) printf ( "\tNext goal %s.\n", m_nextGoal->getName() );
// set finish for the current goal to allow
// cleanup (call of finish())
m_curGoal->setFinish( true );
// pop current goal off the stack if not gosub rule,
// next goal will be replacing it
if ( rule->m_type != IERule::Gosub )
popGoal( m_curGoal );
ruleFired = true;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -