/************************************************************ NAME : TestForFirstInChain DESCRIPTION : Processes all classes in a restriction chain until success or done INPUTS : 1) The current chain 2) The index of the chain restriction (e.g. the 4th query-variable) RETURNS : TRUE if query succeeds, FALSE otherwise SIDE EFFECTS : Sets current restriction class Instance variable values set NOTES : None ************************************************************/ static int TestForFirstInChain( void *theEnv, EXEC_STATUS, QUERY_CLASS *qchain, int indx) { QUERY_CLASS *qptr; int id; InstanceQueryData(theEnv,execStatus)->AbortQuery = TRUE; for (qptr = qchain ; qptr != NULL ; qptr = qptr->chain) { InstanceQueryData(theEnv,execStatus)->AbortQuery = FALSE; if ((id = GetTraversalID(theEnv,execStatus)) == -1) return(FALSE); if (TestForFirstInstanceInClass(theEnv,execStatus,qptr->theModule,id,qptr->cls,qchain,indx)) { ReleaseTraversalID(theEnv,execStatus); return(TRUE); } ReleaseTraversalID(theEnv,execStatus); if ((execStatus->HaltExecution == TRUE) || (InstanceQueryData(theEnv,execStatus)->AbortQuery == TRUE)) return(FALSE); } return(FALSE); }
/************************************************************ NAME : TestForFirstInChain DESCRIPTION : Processes all classes in a restriction chain until success or done INPUTS : 1) The current chain 2) The index of the chain restriction (e.g. the 4th query-variable) RETURNS : TRUE if query succeeds, FALSE otherwise SIDE EFFECTS : Sets current restriction class Instance variable values set NOTES : None ************************************************************/ static int TestForFirstInChain( QUERY_CLASS *qchain, int indx) { QUERY_CLASS *qptr; int id; AbortQuery = TRUE; for (qptr = qchain ; qptr != NULL ; qptr = qptr->chain) { AbortQuery = FALSE; if ((id = GetTraversalID()) == -1) return(FALSE); if (TestForFirstInstanceInClass(qptr->theModule,id,qptr->cls,qchain,indx)) { ReleaseTraversalID(); return(TRUE); } ReleaseTraversalID(); if ((HaltExecution == TRUE) || (AbortQuery == TRUE)) return(FALSE); } return(FALSE); }
/***************************************************************** NAME : TestForFirstInstanceInClass DESCRIPTION : Processes all instances in a class and then all subclasses of a class until success or done INPUTS : 1) The module for which classes tested must be in scope 2) Visitation traversal id 3) The class 4) The current class restriction chain 5) The index of the current restriction RETURNS : TRUE if query succeeds, FALSE otherwise SIDE EFFECTS : Instance variable values set NOTES : None *****************************************************************/ static int TestForFirstInstanceInClass( void *theEnv, EXEC_STATUS, struct defmodule *theModule, int id, DEFCLASS *cls, QUERY_CLASS *qchain, int indx) { long i; INSTANCE_TYPE *ins; DATA_OBJECT temp; if (TestTraversalID(cls->traversalRecord,id)) return(FALSE); SetTraversalID(cls->traversalRecord,id); if (DefclassInScope(theEnv,execStatus,cls,theModule) == FALSE) return(FALSE); ins = cls->instanceList; while (ins != NULL) { InstanceQueryData(theEnv,execStatus)->QueryCore->solns[indx] = ins; if (qchain->nxt != NULL) { ins->busy++; if (TestForFirstInChain(theEnv,execStatus,qchain->nxt,indx+1) == TRUE) { ins->busy--; break; } ins->busy--; if ((execStatus->HaltExecution == TRUE) || (InstanceQueryData(theEnv,execStatus)->AbortQuery == TRUE)) break; } else { ins->busy++; execStatus->CurrentEvaluationDepth++; EvaluateExpression(theEnv,execStatus,InstanceQueryData(theEnv,execStatus)->QueryCore->query,&temp); execStatus->CurrentEvaluationDepth--; PeriodicCleanup(theEnv,execStatus,FALSE,TRUE); ins->busy--; if (execStatus->HaltExecution == TRUE) break; if ((temp.type != SYMBOL) ? TRUE : (temp.value != EnvFalseSymbol(theEnv,execStatus))) break; } ins = ins->nxtClass; while ((ins != NULL) ? (ins->garbage == 1) : FALSE) ins = ins->nxtClass; } if (ins != NULL) return(((execStatus->HaltExecution == TRUE) || (InstanceQueryData(theEnv,execStatus)->AbortQuery == TRUE)) ? FALSE : TRUE); for (i = 0 ; i < cls->directSubclasses.classCount ; i++) { if (TestForFirstInstanceInClass(theEnv,execStatus,theModule,id,cls->directSubclasses.classArray[i], qchain,indx)) return(TRUE); if ((execStatus->HaltExecution == TRUE) || (InstanceQueryData(theEnv,execStatus)->AbortQuery == TRUE)) return(FALSE); } return(FALSE); }
/***************************************************************** NAME : TestForFirstInstanceInClass DESCRIPTION : Processes all instances in a class and then all subclasses of a class until success or done INPUTS : 1) The module for which classes tested must be in scope 2) Visitation traversal id 3) The class 4) The current class restriction chain 5) The index of the current restriction RETURNS : TRUE if query succeeds, FALSE otherwise SIDE EFFECTS : Instance variable values set NOTES : None *****************************************************************/ static int TestForFirstInstanceInClass( void *theEnv, struct defmodule *theModule, int id, DEFCLASS *cls, QUERY_CLASS *qchain, int indx) { long i; INSTANCE_TYPE *ins; DATA_OBJECT temp; struct garbageFrame newGarbageFrame; struct garbageFrame *oldGarbageFrame; if (TestTraversalID(cls->traversalRecord,id)) return(FALSE); SetTraversalID(cls->traversalRecord,id); if (DefclassInScope(theEnv,cls,theModule) == FALSE) return(FALSE); oldGarbageFrame = UtilityData(theEnv)->CurrentGarbageFrame; memset(&newGarbageFrame,0,sizeof(struct garbageFrame)); newGarbageFrame.priorFrame = oldGarbageFrame; UtilityData(theEnv)->CurrentGarbageFrame = &newGarbageFrame; ins = cls->instanceList; while (ins != NULL) { InstanceQueryData(theEnv)->QueryCore->solns[indx] = ins; if (qchain->nxt != NULL) { ins->busy++; if (TestForFirstInChain(theEnv,qchain->nxt,indx+1) == TRUE) { ins->busy--; break; } ins->busy--; if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (InstanceQueryData(theEnv)->AbortQuery == TRUE)) break; } else { ins->busy++; EvaluateExpression(theEnv,InstanceQueryData(theEnv)->QueryCore->query,&temp); ins->busy--; if (EvaluationData(theEnv)->HaltExecution == TRUE) break; if ((temp.type != SYMBOL) ? TRUE : (temp.value != EnvFalseSymbol(theEnv))) break; } CleanCurrentGarbageFrame(theEnv,NULL); CallPeriodicTasks(theEnv); ins = ins->nxtClass; while ((ins != NULL) ? (ins->garbage == 1) : FALSE) ins = ins->nxtClass; } RestorePriorGarbageFrame(theEnv,&newGarbageFrame, oldGarbageFrame,NULL); CallPeriodicTasks(theEnv); if (ins != NULL) return(((EvaluationData(theEnv)->HaltExecution == TRUE) || (InstanceQueryData(theEnv)->AbortQuery == TRUE)) ? FALSE : TRUE); for (i = 0 ; i < cls->directSubclasses.classCount ; i++) { if (TestForFirstInstanceInClass(theEnv,theModule,id,cls->directSubclasses.classArray[i], qchain,indx)) return(TRUE); if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (InstanceQueryData(theEnv)->AbortQuery == TRUE)) return(FALSE); } return(FALSE); }