globle void InitializeAgenda( void *theEnv) { AllocateEnvironmentData(theEnv,AGENDA_DATA,sizeof(struct agendaData),NULL); AgendaData(theEnv)->SalienceEvaluation = WHEN_DEFINED; AgendaData(theEnv)->Strategy = DEFAULT_STRATEGY; EnvAddClearFunction(theEnv,(char*)"agenda",AgendaClearFunction,0); #if DEBUGGING_FUNCTIONS AddWatchItem(theEnv,(char*)"activations",1,&AgendaData(theEnv)->WatchActivations,40,DefruleWatchAccess,DefruleWatchPrint); #endif #if ! RUN_TIME EnvDefineFunction2(theEnv,(char*)"refresh", 'v', PTIEF RefreshCommand, (char*)"RefreshCommand", (char*)"11w"); EnvDefineFunction2(theEnv,(char*)"refresh-agenda",'v', PTIEF RefreshAgendaCommand, (char*)"RefreshAgendaCommand", (char*)"01w"); EnvDefineFunction2(theEnv,(char*)"get-salience-evaluation",'w', PTIEF GetSalienceEvaluationCommand, (char*)"GetSalienceEvaluationCommand", (char*)"00"); EnvDefineFunction2(theEnv,(char*)"set-salience-evaluation",'w', PTIEF SetSalienceEvaluationCommand, (char*)"SetSalienceEvaluationCommand", (char*)"11w"); #if DEBUGGING_FUNCTIONS EnvDefineFunction2(theEnv,(char*)"agenda", 'v', PTIEF AgendaCommand, (char*)"AgendaCommand", (char*)"01w"); #endif #endif }
globle intBool EnvSetSalienceEvaluation( void *theEnv, int value) { int ov; ov = AgendaData(theEnv)->SalienceEvaluation; AgendaData(theEnv)->SalienceEvaluation = value; return(ov); }
globle int EnvSetStrategy( void *theEnv, int value) { int oldStrategy; oldStrategy = AgendaData(theEnv)->Strategy; AgendaData(theEnv)->Strategy = value; if (oldStrategy != AgendaData(theEnv)->Strategy) EnvReorderAgenda(theEnv,NULL); return(oldStrategy); }
static void UpdateDefrule( void *theEnv, void *buf, long obji) { struct bsaveDefrule *br; br = (struct bsaveDefrule *) buf; UpdateConstructHeader(theEnv,&br->header,&DefruleBinaryData(theEnv)->DefruleArray[obji].header, (int) sizeof(struct defruleModule),(void *) DefruleBinaryData(theEnv)->ModuleArray, (int) sizeof(struct defrule),(void *) DefruleBinaryData(theEnv)->DefruleArray); DefruleBinaryData(theEnv)->DefruleArray[obji].dynamicSalience = ExpressionPointer(br->dynamicSalience); DefruleBinaryData(theEnv)->DefruleArray[obji].actions = ExpressionPointer(br->actions); DefruleBinaryData(theEnv)->DefruleArray[obji].logicalJoin = BloadJoinPointer(br->logicalJoin); DefruleBinaryData(theEnv)->DefruleArray[obji].lastJoin = BloadJoinPointer(br->lastJoin); DefruleBinaryData(theEnv)->DefruleArray[obji].disjunct = BloadDefrulePointer(DefruleBinaryData(theEnv)->DefruleArray,br->disjunct); DefruleBinaryData(theEnv)->DefruleArray[obji].salience = br->salience; DefruleBinaryData(theEnv)->DefruleArray[obji].localVarCnt = br->localVarCnt; DefruleBinaryData(theEnv)->DefruleArray[obji].complexity = br->complexity; DefruleBinaryData(theEnv)->DefruleArray[obji].autoFocus = br->autoFocus; DefruleBinaryData(theEnv)->DefruleArray[obji].executing = 0; DefruleBinaryData(theEnv)->DefruleArray[obji].afterBreakpoint = 0; #if DEBUGGING_FUNCTIONS DefruleBinaryData(theEnv)->DefruleArray[obji].watchActivation = AgendaData(theEnv)->WatchActivations; DefruleBinaryData(theEnv)->DefruleArray[obji].watchFiring = DefruleData(theEnv)->WatchRules; #endif }
globle intBool DetachActivation( void *theEnv, void *vTheActivation) { struct defruleModule *theModuleItem; struct activation *theActivation = (struct activation *) vTheActivation; /*============================*/ /* A NULL pointer is invalid. */ /*============================*/ if (theActivation == NULL) SystemError(theEnv,"AGENDA",1); /*====================================*/ /* Determine the module of the agenda */ /* in which the activation is stored. */ /*====================================*/ theModuleItem = (struct defruleModule *) theActivation->theRule->header.whichModule; RemoveActivationFromGroup(theEnv,theActivation,theModuleItem); /*========================================================*/ /* If the activation is the top activation on the agenda, */ /* then update the module pointer to agenda. */ /*========================================================*/ if (theActivation == theModuleItem->agenda) { theModuleItem->agenda = theActivation->next; } /*==================================================*/ /* Update the pointers in the preceding activation. */ /*==================================================*/ if (theActivation->prev != NULL) { theActivation->prev->next = theActivation->next; } /*==================================================*/ /* Update the pointers in the following activation. */ /*==================================================*/ if (theActivation->next != NULL) { theActivation->next->prev = theActivation->prev; } /*=================================================*/ /* Update the pointers in the detached activation. */ /*=================================================*/ theActivation->prev = NULL; theActivation->next = NULL; /*=============================*/ /* Mark the agenda as changed. */ /*=============================*/ AgendaData(theEnv)->AgendaChanged = TRUE; return(TRUE); }
globle void *SetStrategyCommand( void *theEnv) { DATA_OBJECT argPtr; char *argument; int oldStrategy; oldStrategy = AgendaData(theEnv)->Strategy; /*=====================================================*/ /* Check for the correct number and type of arguments. */ /*=====================================================*/ if (EnvArgCountCheck(theEnv,"set-strategy",EXACTLY,1) == -1) { return((SYMBOL_HN *) EnvAddSymbol(theEnv,GetStrategyName(EnvGetStrategy(theEnv)))); } if (EnvArgTypeCheck(theEnv,"set-strategy",1,SYMBOL,&argPtr) == FALSE) { return((SYMBOL_HN *) EnvAddSymbol(theEnv,GetStrategyName(EnvGetStrategy(theEnv)))); } argument = DOToString(argPtr); /*=============================================*/ /* Set the strategy to the specified strategy. */ /*=============================================*/ if (strcmp(argument,"depth") == 0) { EnvSetStrategy(theEnv,DEPTH_STRATEGY); } else if (strcmp(argument,"breadth") == 0) { EnvSetStrategy(theEnv,BREADTH_STRATEGY); } else if (strcmp(argument,"lex") == 0) { EnvSetStrategy(theEnv,LEX_STRATEGY); } else if (strcmp(argument,"mea") == 0) { EnvSetStrategy(theEnv,MEA_STRATEGY); } else if (strcmp(argument,"complexity") == 0) { EnvSetStrategy(theEnv,COMPLEXITY_STRATEGY); } else if (strcmp(argument,"simplicity") == 0) { EnvSetStrategy(theEnv,SIMPLICITY_STRATEGY); } else if (strcmp(argument,"random") == 0) { EnvSetStrategy(theEnv,RANDOM_STRATEGY); } else { ExpectedTypeError1(theEnv,"set-strategy",1, "symbol with value depth, breadth, lex, mea, complexity, simplicity, or random"); return((SYMBOL_HN *) EnvAddSymbol(theEnv,GetStrategyName(EnvGetStrategy(theEnv)))); } /*=======================================*/ /* Return the old value of the strategy. */ /*=======================================*/ return((SYMBOL_HN *) EnvAddSymbol(theEnv,GetStrategyName(oldStrategy))); }
globle intBool MoveActivationToTop( void *theEnv, void *vtheActivation) { struct activation *prevPtr; struct activation *theActivation = (struct activation *) vtheActivation; struct defruleModule *theModuleItem; /*====================================*/ /* Determine the module of the agenda */ /* in which the activation is stored. */ /*====================================*/ theModuleItem = (struct defruleModule *) theActivation->theRule->header.whichModule; /*============================================*/ /* If the activation is already at the top of */ /* the agenda, then nothing needs to be done. */ /*============================================*/ if (theActivation == theModuleItem->agenda) return(FALSE); /*=================================================*/ /* Update the pointers of the activation preceding */ /* and following the activation being moved. */ /*=================================================*/ prevPtr = theActivation->prev; prevPtr->next = theActivation->next; if (theActivation->next != NULL) theActivation->next->prev = prevPtr; /*=======================================================*/ /* Move the activation and then update its pointers, the */ /* pointers of the activation following it, and the */ /* module pointer to the top activation on the agenda. */ /*=======================================================*/ theActivation->next = theModuleItem->agenda; theModuleItem->agenda->prev = theActivation; theActivation->prev = NULL; theModuleItem->agenda = theActivation; /*=============================*/ /* Mark the agenda as changed. */ /*=============================*/ AgendaData(theEnv)->AgendaChanged = TRUE; return(TRUE); }
globle unsigned long GetNumberOfActivations( void *theEnv) { return(AgendaData(theEnv)->NumberOfActivations); }
globle void EnvSetAgendaChanged( void *theEnv, int value) { AgendaData(theEnv)->AgendaChanged = value; }
globle int EnvGetAgendaChanged( void *theEnv) { return(AgendaData(theEnv)->AgendaChanged); }
static void AgendaClearFunction( void *theEnv) { AgendaData(theEnv)->CurrentTimetag = 0; }
globle void RemoveActivation( void *theEnv, void *vTheActivation, int updateAgenda, int updateLinks) { struct defruleModule *theModuleItem; struct activation *theActivation = (struct activation *) vTheActivation; /*====================================*/ /* Determine the module of the agenda */ /* in which the activation is stored. */ /*====================================*/ theModuleItem = (struct defruleModule *) theActivation->theRule->header.whichModule; /*=================================*/ /* Update the agenda if necessary. */ /*=================================*/ if (updateAgenda == TRUE) { RemoveActivationFromGroup(theEnv,theActivation,theModuleItem); /*===============================================*/ /* Update the pointer links between activations. */ /*===============================================*/ if (theActivation->prev == NULL) { theModuleItem->agenda = theModuleItem->agenda->next; if (theModuleItem->agenda != NULL) theModuleItem->agenda->prev = NULL; } else { theActivation->prev->next = theActivation->next; if (theActivation->next != NULL) { theActivation->next->prev = theActivation->prev; } } /*===================================*/ /* Indicate removal of activation if */ /* activations are being watched. */ /*===================================*/ #if DEBUGGING_FUNCTIONS if (theActivation->theRule->watchActivation) { EnvPrintRouter(theEnv,WTRACE,(char*)"<== Activation "); PrintActivation(theEnv,WTRACE,(void *) theActivation); EnvPrintRouter(theEnv,WTRACE,(char*)"\n"); } #endif /*=============================*/ /* Mark the agenda as changed. */ /*=============================*/ AgendaData(theEnv)->AgendaChanged = TRUE; } /*============================================*/ /* Update join and agenda links if necessary. */ /*============================================*/ if ((updateLinks == TRUE) && (theActivation->basis != NULL)) { theActivation->basis->marker = NULL; } /*================================================*/ /* Return the activation to the free memory pool. */ /*================================================*/ AgendaData(theEnv)->NumberOfActivations--; rtn_struct(theEnv,activation,theActivation); }
globle void AddActivation( void *theEnv, void *vTheRule, void *vBinds) { struct activation *newActivation; struct defrule *theRule = (struct defrule *) vTheRule; struct partialMatch *binds = (struct partialMatch *) vBinds; struct defruleModule *theModuleItem; struct salienceGroup *theGroup; /*=======================================*/ /* Focus on the module if the activation */ /* is from an auto-focus rule. */ /*=======================================*/ if (theRule->autoFocus) { EnvFocus(theEnv,(void *) theRule->header.whichModule->theModule); } /*=======================================================*/ /* Create the activation. The activation stores pointers */ /* to its associated partial match and defrule. The */ /* activation is given a time tag, its salience is */ /* evaluated, and it is assigned a random number for use */ /* with the random conflict resolution strategy. */ /*=======================================================*/ newActivation = get_struct(theEnv,activation); newActivation->theRule = theRule; newActivation->basis = binds; newActivation->timetag = AgendaData(theEnv)->CurrentTimetag++; newActivation->salience = EvaluateSalience(theEnv,theRule); newActivation->randomID = genrand(); newActivation->prev = NULL; newActivation->next = NULL; AgendaData(theEnv)->NumberOfActivations++; /*=======================================================*/ /* Point the partial match to the activation to complete */ /* the link between the join network and the agenda. */ /*=======================================================*/ binds->marker = (void *) newActivation; /*====================================================*/ /* If activations are being watch, display a message. */ /*====================================================*/ #if DEBUGGING_FUNCTIONS if (newActivation->theRule->watchActivation) { EnvPrintRouter(theEnv,WTRACE,(char*)"==> Activation "); PrintActivation(theEnv,WTRACE,(void *) newActivation); EnvPrintRouter(theEnv,WTRACE,(char*)"\n"); } #endif /*=====================================*/ /* Place the activation on the agenda. */ /*=====================================*/ theModuleItem = (struct defruleModule *) theRule->header.whichModule; theGroup = ReuseOrCreateSalienceGroup(theEnv,theModuleItem,newActivation->salience); PlaceActivation(theEnv,&(theModuleItem->agenda),newActivation,theGroup); }
globle intBool EnvGetSalienceEvaluation( void *theEnv) { return(AgendaData(theEnv)->SalienceEvaluation); }
globle int EnvGetStrategy( void *theEnv) { return(AgendaData(theEnv)->Strategy); }
globle void PlaceActivation( void *theEnv, ACTIVATION **whichAgenda, ACTIVATION *newActivation) { ACTIVATION *placeAfter = NULL; /*================================================*/ /* Set the flag which indicates that a change has */ /* been made to the agenda. */ /*================================================*/ EnvSetAgendaChanged(theEnv,TRUE); /*=============================================*/ /* Determine the location where the activation */ /* should be placed in the agenda based on the */ /* current conflict resolution strategy. */ /*==============================================*/ #if ! CONFLICT_RESOLUTION_STRATEGIES if (*whichAgenda != NULL) placeAfter = PlaceDepthActivation(*whichAgenda,newActivation); #else if (*whichAgenda != NULL) switch (AgendaData(theEnv)->Strategy) { case DEPTH_STRATEGY: placeAfter = PlaceDepthActivation(*whichAgenda,newActivation); break; case BREADTH_STRATEGY: placeAfter = PlaceBreadthActivation(*whichAgenda,newActivation); break; case LEX_STRATEGY: placeAfter = PlaceLEXActivation(theEnv,*whichAgenda,newActivation); break; case MEA_STRATEGY: placeAfter = PlaceMEAActivation(theEnv,*whichAgenda,newActivation); break; case COMPLEXITY_STRATEGY: placeAfter = PlaceComplexityActivation(*whichAgenda,newActivation); break; case SIMPLICITY_STRATEGY: placeAfter = PlaceSimplicityActivation(*whichAgenda,newActivation); break; case RANDOM_STRATEGY: placeAfter = PlaceRandomActivation(*whichAgenda,newActivation); break; } #endif /*==============================================================*/ /* Place the activation at the appropriate place in the agenda. */ /*==============================================================*/ if (placeAfter == NULL) /* then place it at the beginning of then agenda. */ { newActivation->next = *whichAgenda; *whichAgenda = newActivation; if (newActivation->next != NULL) newActivation->next->prev = newActivation; } else /* insert it in the agenda. */ { newActivation->next = placeAfter->next; newActivation->prev = placeAfter; placeAfter->next = newActivation; if (newActivation->next != NULL) { newActivation->next->prev = newActivation; } } }