?? factqury.c
字號(hào):
DATA_OBJECT *result)
{
QUERY_TEMPLATE *qtemplates;
unsigned rcnt;
register unsigned i,j;
result->type = MULTIFIELD;
result->begin = 0;
result->end = -1;
qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg,
"find-all-facts",&rcnt);
if (qtemplates == NULL)
{
result->value = (void *) EnvCreateMultifield(theEnv,0L);
return;
}
PushQueryCore(theEnv);
FactQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
FactQueryData(theEnv)->QueryCore->solns = (struct fact **) gm2(theEnv,(sizeof(struct fact *) * rcnt));
FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
FactQueryData(theEnv)->QueryCore->action = NULL;
FactQueryData(theEnv)->QueryCore->soln_set = NULL;
FactQueryData(theEnv)->QueryCore->soln_size = rcnt;
FactQueryData(theEnv)->QueryCore->soln_cnt = 0;
TestEntireChain(theEnv,qtemplates,0);
FactQueryData(theEnv)->AbortQuery = FALSE;
result->value = (void *) EnvCreateMultifield(theEnv,FactQueryData(theEnv)->QueryCore->soln_cnt * rcnt);
while (FactQueryData(theEnv)->QueryCore->soln_set != NULL)
{
for (i = 0 , j = (unsigned) (result->end + 2) ; i < rcnt ; i++ , j++)
{
SetMFType(result->value,j,FACT_ADDRESS);
SetMFValue(result->value,j,FactQueryData(theEnv)->QueryCore->soln_set->soln[i]);
}
result->end = (long) j-2;
PopQuerySoln(theEnv);
}
rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->solns,(sizeof(struct fact *) * rcnt));
rtn_struct(theEnv,query_core,FactQueryData(theEnv)->QueryCore);
PopQueryCore(theEnv);
DeleteQueryTemplates(theEnv,qtemplates);
}
/******************************************************************************
NAME : QueryDoForFact
DESCRIPTION : Finds the first set of facts which satisfy the query and
executes a user-action with that set
INPUTS : None
RETURNS : Caller's result buffer
SIDE EFFECTS : The query template-expressions are evaluated once,
and the query boolean-expression is evaluated
zero or more times (depending on fact restrictions
and how early the expression evaulates to TRUE - if at all).
Also the action expression is executed zero or once.
Caller's result buffer holds result of user-action
NOTES : H/L Syntax : See ParseQueryAction()
******************************************************************************/
globle void QueryDoForFact(
void *theEnv,
DATA_OBJECT *result)
{
QUERY_TEMPLATE *qtemplates;
unsigned rcnt;
result->type = SYMBOL;
result->value = EnvFalseSymbol(theEnv);
qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg->nextArg,
"do-for-fact",&rcnt);
if (qtemplates == NULL)
return;
PushQueryCore(theEnv);
FactQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
FactQueryData(theEnv)->QueryCore->solns = (struct fact **) gm2(theEnv,(sizeof(struct fact *) * rcnt));
FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
FactQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
if (TestForFirstInChain(theEnv,qtemplates,0) == TRUE)
EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->action,result);
FactQueryData(theEnv)->AbortQuery = FALSE;
ProcedureFunctionData(theEnv)->BreakFlag = FALSE;
rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->solns,(sizeof(struct fact *) * rcnt));
rtn_struct(theEnv,query_core,FactQueryData(theEnv)->QueryCore);
PopQueryCore(theEnv);
DeleteQueryTemplates(theEnv,qtemplates);
}
/******************************************************************************
NAME : QueryDoForAllFacts
DESCRIPTION : Finds all sets of facts which satisfy the query and
executes a user-function for each set as it is found
INPUTS : Caller's result buffer
RETURNS : Nothing useful
SIDE EFFECTS : The query template-expressions are evaluated once,
and the query boolean-expression is evaluated
once for every fact set. Also, the action is
executed for every fact set.
Caller's result buffer holds result of last action executed.
NOTES : H/L Syntax : See FactParseQueryAction()
******************************************************************************/
globle void QueryDoForAllFacts(
void *theEnv,
DATA_OBJECT *result)
{
QUERY_TEMPLATE *qtemplates;
unsigned rcnt;
result->type = SYMBOL;
result->value = EnvFalseSymbol(theEnv);
qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg->nextArg,
"do-for-all-facts",&rcnt);
if (qtemplates == NULL)
return;
PushQueryCore(theEnv);
FactQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
FactQueryData(theEnv)->QueryCore->solns = (struct fact **) gm2(theEnv,(sizeof(struct fact *) * rcnt));
FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
FactQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
FactQueryData(theEnv)->QueryCore->result = result;
ValueInstall(theEnv,FactQueryData(theEnv)->QueryCore->result);
TestEntireChain(theEnv,qtemplates,0);
ValueDeinstall(theEnv,FactQueryData(theEnv)->QueryCore->result);
PropagateReturnValue(theEnv,FactQueryData(theEnv)->QueryCore->result);
FactQueryData(theEnv)->AbortQuery = FALSE;
ProcedureFunctionData(theEnv)->BreakFlag = FALSE;
rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->solns,(sizeof(struct fact *) * rcnt));
rtn_struct(theEnv,query_core,FactQueryData(theEnv)->QueryCore);
PopQueryCore(theEnv);
DeleteQueryTemplates(theEnv,qtemplates);
}
/******************************************************************************
NAME : DelayedQueryDoForAllFacts
DESCRIPTION : Finds all sets of facts which satisfy the query and
and exceutes a user-action for each set
This function differs from QueryDoForAllFacts() in
that it forms the complete list of query satisfactions
BEFORE executing any actions.
INPUTS : Caller's result buffer
RETURNS : Nothing useful
SIDE EFFECTS : The query template-expressions are evaluated once,
and the query boolean-expression is evaluated
once for every fact set. The action is executed
for evry query satisfaction.
Caller's result buffer holds result of last action executed.
NOTES : H/L Syntax : See FactParseQueryNoAction()
******************************************************************************/
globle void DelayedQueryDoForAllFacts(
void *theEnv,
DATA_OBJECT *result)
{
QUERY_TEMPLATE *qtemplates;
unsigned rcnt;
register unsigned i;
result->type = SYMBOL;
result->value = EnvFalseSymbol(theEnv);
qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg->nextArg,
"delayed-do-for-all-facts",&rcnt);
if (qtemplates == NULL)
return;
PushQueryCore(theEnv);
FactQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
FactQueryData(theEnv)->QueryCore->solns = (struct fact **) gm2(theEnv,(sizeof(struct fact *) * rcnt));
FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
FactQueryData(theEnv)->QueryCore->action = NULL;
FactQueryData(theEnv)->QueryCore->soln_set = NULL;
FactQueryData(theEnv)->QueryCore->soln_size = rcnt;
FactQueryData(theEnv)->QueryCore->soln_cnt = 0;
TestEntireChain(theEnv,qtemplates,0);
FactQueryData(theEnv)->AbortQuery = FALSE;
FactQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
while (FactQueryData(theEnv)->QueryCore->soln_set != NULL)
{
for (i = 0 ; i < rcnt ; i++)
FactQueryData(theEnv)->QueryCore->solns[i] = FactQueryData(theEnv)->QueryCore->soln_set->soln[i];
PopQuerySoln(theEnv);
EvaluationData(theEnv)->CurrentEvaluationDepth++;
EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->action,result);
EvaluationData(theEnv)->CurrentEvaluationDepth--;
if (ProcedureFunctionData(theEnv)->ReturnFlag == TRUE)
{ PropagateReturnValue(theEnv,result); }
PeriodicCleanup(theEnv,FALSE,TRUE);
if (EvaluationData(theEnv)->HaltExecution || ProcedureFunctionData(theEnv)->BreakFlag || ProcedureFunctionData(theEnv)->ReturnFlag)
{
while (FactQueryData(theEnv)->QueryCore->soln_set != NULL)
PopQuerySoln(theEnv);
break;
}
}
ProcedureFunctionData(theEnv)->BreakFlag = FALSE;
rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->solns,(sizeof(struct fact *) * rcnt));
rtn_struct(theEnv,query_core,FactQueryData(theEnv)->QueryCore);
PopQueryCore(theEnv);
DeleteQueryTemplates(theEnv,qtemplates);
}
/* =========================================
*****************************************
INTERNALLY VISIBLE FUNCTIONS
=========================================
***************************************** */
/*******************************************************
NAME : PushQueryCore
DESCRIPTION : Pushes the current QueryCore onto stack
INPUTS : None
RETURNS : Nothing useful
SIDE EFFECTS : Allocates new stack node and changes
QueryCoreStack
NOTES : None
*******************************************************/
static void PushQueryCore(
void *theEnv)
{
QUERY_STACK *qptr;
qptr = get_struct(theEnv,query_stack);
qptr->core = FactQueryData(theEnv)->QueryCore;
qptr->nxt = FactQueryData(theEnv)->QueryCoreStack;
FactQueryData(theEnv)->QueryCoreStack = qptr;
}
/******************************************************
NAME : PopQueryCore
DESCRIPTION : Pops top of QueryCore stack and
restores QueryCore to this core
INPUTS : None
RETURNS : Nothing useful
SIDE EFFECTS : Stack node deallocated, QueryCoreStack
changed and QueryCore reset
NOTES : Assumes stack is not empty
******************************************************/
static void PopQueryCore(
void *theEnv)
{
QUERY_STACK *qptr;
FactQueryData(theEnv)->QueryCore = FactQueryData(theEnv)->QueryCoreStack->core;
qptr = FactQueryData(theEnv)->QueryCoreStack;
FactQueryData(theEnv)->QueryCoreStack = FactQueryData(theEnv)->QueryCoreStack->nxt;
rtn_struct(theEnv,query_stack,qptr);
}
/***************************************************
NAME : FindQueryCore
DESCRIPTION : Looks up a QueryCore Stack Frame
Depth 0 is current frame
1 is next deepest, etc.
INPUTS : Depth
RETURNS : Address of query core stack frame
SIDE EFFECTS : None
NOTES : None
***************************************************/
static QUERY_CORE *FindQueryCore(
void *theEnv,
int depth)
{
QUERY_STACK *qptr;
if (depth == 0)
return(FactQueryData(theEnv)->QueryCore);
qptr = FactQueryData(theEnv)->QueryCoreStack;
while (depth > 1)
{
qptr = qptr->nxt;
depth--;
}
return(qptr->core);
}
/**********************************************************
NAME : DetermineQueryTemplates
DESCRIPTION : Builds a list of templates to be used in
fact queries - uses parse form.
INPUTS : 1) The parse template expression chain
2) The name of the function being executed
3) Caller's buffer for restriction count
(# of separate lists)
RETURNS : The query list, or NULL on errors
SIDE EFFECTS : Memory allocated for list
Busy count incremented for all templates
NOTES : Each restriction is linked by nxt pointer,
multiple templates in a restriction are
linked by the chain pointer.
total number of chains
Assumes classExp is not NULL and that each
restriction chain is terminated with
the QUERY_DELIMITER_SYMBOL "(QDS)"
**********************************************************/
static QUERY_TEMPLATE *DetermineQueryTemplates(
void *theEnv,
EXPRESSION *templateExp,
char *func,
unsigned *rcnt)
{
QUERY_TEMPLATE *clist = NULL,*cnxt = NULL,*cchain = NULL,*tmp;
int new_list = FALSE;
DATA_OBJECT temp;
*rcnt = 0;
while (templateExp != NULL)
{
if (EvaluateExpression(theEnv,templateExp,&temp))
{
DeleteQueryTemplates(theEnv,clist);
return(NULL);
}
if ((temp.type == SYMBOL) && (temp.value == (void *) FactQueryData(theEnv)->QUERY_DELIMETER_SYMBOL))
{
new_list = TRUE;
(*rcnt)++;
}
else if ((tmp = FormChain(theEnv,func,&temp)) != NULL)
{
if (clist == NULL)
clist = cnxt = cchain = tmp;
else if (new_list == TRUE)
{
new_list = FALSE;
cnxt->nxt = tmp;
cnxt = cchain = tmp;
}
else
cchain->chain = tmp;
while (cchain->chain != NULL)
cchain = cchain->chain;
}
else
{
SyntaxErrorMessage(theEnv,"fact-set query class restrictions");
DeleteQueryTemplates(theEnv,clist);
SetEvaluationError(theEnv,TRUE);
return(NULL);
}
templateExp = templateExp->nextArg;
return(clist);
}
/*************************************************************
NAME : FormChain
DESCRIPTION : Builds a list of classes to be used in
fact queries - uses parse form.
INPUTS : 1) Name of calling function for error msgs
2) Data object - must be a symbol or a
multifield value containing all symbols
The symbols must be names of existing templates
RETURNS : The query chain, or NULL on errors
SIDE EFFECTS : Memory allocated for chain
Busy count incremented for all templates
NOTES : None
*************************************************************/
static QUERY_TEMPLATE *FormChain(
void *theEnv,
char *func,
DATA_OBJECT *val)
{
struct deftemplate *templatePtr;
QUERY_TEMPLATE *head,*bot,*tmp;
register long i,end; /* 6.04 Bug Fix */
char *templateName;
int count;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -