1    /*******************************************************/
2    /*      "C" Language Integrated Production System      */
3    /*                                                     */
4    /*             CLIPS Version 6.30  01/25/15            */
5    /*                                                     */
6    /*                 DEFTEMPLATE MODULE                  */
7    /*******************************************************/
8 
9 /*************************************************************/
10 /* Purpose: Defines basic deftemplate primitive functions    */
11 /*   such as allocating and deallocating, traversing, and    */
12 /*   finding deftemplate data structures.                    */
13 /*                                                           */
14 /* Principal Programmer(s):                                  */
15 /*      Gary D. Riley                                        */
16 /*                                                           */
17 /* Contributing Programmer(s):                               */
18 /*      Brian L. Dantes                                      */
19 /*                                                           */
20 /* Revision History:                                         */
21 /*                                                           */
22 /*      6.23: Added support for templates maintaining their  */
23 /*            own list of facts.                             */
24 /*                                                           */
25 /*      6.24: Renamed BOOLEAN macro type to intBool.         */
26 /*                                                           */
27 /*            Corrected code to remove run-time program      */
28 /*            compiler warnings.                             */
29 /*                                                           */
30 /*      6.30: Added code for deftemplate run time            */
31 /*            initialization of hashed comparisons to        */
32 /*            constants.                                     */
33 /*                                                           */
34 /*            Removed conditional code for unsupported       */
35 /*            compilers/operating systems (IBM_MCW,          */
36 /*            MAC_MCW, and IBM_TBC).                         */
37 /*                                                           */
38 /*            Support for deftemplate slot facets.           */
39 /*                                                           */
40 /*            Added const qualifiers to remove C++           */
41 /*            deprecation warnings.                          */
42 /*                                                           */
43 /*            Converted API macros to function calls.        */
44 /*                                                           */
45 /*            Changed find construct functionality so that   */
46 /*            imported modules are search when locating a    */
47 /*            named construct.                               */
48 /*                                                           */
49 /*************************************************************/
50 
51 #define _TMPLTDEF_SOURCE_
52 
53 #include "setup.h"
54 
55 #if DEFTEMPLATE_CONSTRUCT
56 
57 #include <stdio.h>
58 #define _STDIO_INCLUDED_
59 
60 #include "memalloc.h"
61 #include "exprnops.h"
62 #include "cstrccom.h"
63 #include "network.h"
64 #include "tmpltpsr.h"
65 #include "tmpltbsc.h"
66 #include "tmpltutl.h"
67 #include "tmpltfun.h"
68 #include "router.h"
69 #include "modulpsr.h"
70 #include "modulutl.h"
71 #include "cstrnchk.h"
72 #include "envrnmnt.h"
73 
74 #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE
75 #include "bload.h"
76 #include "tmpltbin.h"
77 #endif
78 
79 #if CONSTRUCT_COMPILER && (! RUN_TIME)
80 #include "tmpltcmp.h"
81 #endif
82 
83 #include "tmpltdef.h"
84 
85 /***************************************/
86 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
87 /***************************************/
88 
89    static void                   *AllocateModule(void *);
90    static void                    ReturnModule(void *,void *);
91    static void                    ReturnDeftemplate(void *,void *);
92    static void                    InitializeDeftemplateModules(void *);
93    static void                    DeallocateDeftemplateData(void *);
94    static void                    DestroyDeftemplateAction(void *,struct constructHeader *,void *);
95    static void                    DestroyDeftemplate(void *,void *);
96 #if RUN_TIME
97    static void                    RuntimeDeftemplateAction(void *,struct constructHeader *,void *);
98    static void                    SearchForHashedPatternNodes(void *,struct factPatternNode *);
99 #endif
100 
101 /******************************************************************/
102 /* InitializeDeftemplates: Initializes the deftemplate construct. */
103 /******************************************************************/
InitializeDeftemplates(void * theEnv)104 globle void InitializeDeftemplates(
105   void *theEnv)
106   {
107    globle struct entityRecord deftemplatePtrRecord = { "DEFTEMPLATE_PTR",
108                                                            DEFTEMPLATE_PTR,1,0,0,
109                                                            NULL,
110                                                            NULL,NULL,
111                                                            NULL,
112                                                            NULL,
113                                                            DecrementDeftemplateBusyCount,
114                                                            IncrementDeftemplateBusyCount,
115                                                            NULL,NULL,NULL,NULL,NULL };
116    AllocateEnvironmentData(theEnv,DEFTEMPLATE_DATA,sizeof(struct deftemplateData),DeallocateDeftemplateData);
117 
118    memcpy(&DeftemplateData(theEnv)->DeftemplatePtrRecord,&deftemplatePtrRecord,sizeof(struct entityRecord));
119 
120    InitializeFacts(theEnv);
121 
122    InitializeDeftemplateModules(theEnv);
123 
124    DeftemplateBasicCommands(theEnv);
125 
126    DeftemplateFunctions(theEnv);
127 
128    DeftemplateData(theEnv)->DeftemplateConstruct =
129       AddConstruct(theEnv,"deftemplate","deftemplates",ParseDeftemplate,EnvFindDeftemplate,
130                    GetConstructNamePointer,GetConstructPPForm,
131                    GetConstructModuleItem,EnvGetNextDeftemplate,SetNextConstruct,
132                    EnvIsDeftemplateDeletable,EnvUndeftemplate,ReturnDeftemplate);
133 
134    InstallPrimitive(theEnv,(ENTITY_RECORD_PTR) &DeftemplateData(theEnv)->DeftemplatePtrRecord,DEFTEMPLATE_PTR);
135   }
136 
137 /******************************************************/
138 /* DeallocateDeftemplateData: Deallocates environment */
139 /*    data for the deftemplate construct.             */
140 /******************************************************/
DeallocateDeftemplateData(void * theEnv)141 static void DeallocateDeftemplateData(
142   void *theEnv)
143   {
144 #if ! RUN_TIME
145    struct deftemplateModule *theModuleItem;
146    void *theModule;
147 #endif
148 #if BLOAD || BLOAD_AND_BSAVE
149    if (Bloaded(theEnv)) return;
150 #endif
151 
152    DoForAllConstructs(theEnv,DestroyDeftemplateAction,DeftemplateData(theEnv)->DeftemplateModuleIndex,FALSE,NULL);
153 
154 #if ! RUN_TIME
155    for (theModule = EnvGetNextDefmodule(theEnv,NULL);
156         theModule != NULL;
157         theModule = EnvGetNextDefmodule(theEnv,theModule))
158      {
159       theModuleItem = (struct deftemplateModule *)
160                       GetModuleItem(theEnv,(struct defmodule *) theModule,
161                                     DeftemplateData(theEnv)->DeftemplateModuleIndex);
162       rtn_struct(theEnv,deftemplateModule,theModuleItem);
163      }
164 #endif
165   }
166 
167 /*****************************************************/
168 /* DestroyDeftemplateAction: Action used to remove   */
169 /*   deftemplates as a result of DestroyEnvironment. */
170 /*****************************************************/
DestroyDeftemplateAction(void * theEnv,struct constructHeader * theConstruct,void * buffer)171 static void DestroyDeftemplateAction(
172   void *theEnv,
173   struct constructHeader *theConstruct,
174   void *buffer)
175   {
176 #if MAC_XCD
177 #pragma unused(buffer)
178 #endif
179    struct deftemplate *theDeftemplate = (struct deftemplate *) theConstruct;
180 
181    if (theDeftemplate == NULL) return;
182 
183    DestroyDeftemplate(theEnv,theDeftemplate);
184   }
185 
186 
187 /*************************************************************/
188 /* InitializeDeftemplateModules: Initializes the deftemplate */
189 /*   construct for use with the defmodule construct.         */
190 /*************************************************************/
InitializeDeftemplateModules(void * theEnv)191 static void InitializeDeftemplateModules(
192   void *theEnv)
193   {
194    DeftemplateData(theEnv)->DeftemplateModuleIndex = RegisterModuleItem(theEnv,"deftemplate",
195                                     AllocateModule,
196                                     ReturnModule,
197 #if BLOAD_AND_BSAVE || BLOAD || BLOAD_ONLY
198                                     BloadDeftemplateModuleReference,
199 #else
200                                     NULL,
201 #endif
202 #if CONSTRUCT_COMPILER && (! RUN_TIME)
203                                     DeftemplateCModuleReference,
204 #else
205                                     NULL,
206 #endif
207                                     EnvFindDeftemplateInModule);
208 
209 #if (! BLOAD_ONLY) && (! RUN_TIME) && DEFMODULE_CONSTRUCT
210    AddPortConstructItem(theEnv,"deftemplate",SYMBOL);
211 #endif
212   }
213 
214 /***************************************************/
215 /* AllocateModule: Allocates a deftemplate module. */
216 /***************************************************/
AllocateModule(void * theEnv)217 static void *AllocateModule(
218   void *theEnv)
219   {
220    return((void *) get_struct(theEnv,deftemplateModule));
221   }
222 
223 /*************************************************/
224 /* ReturnModule: Deallocates a deftemplate module. */
225 /*************************************************/
ReturnModule(void * theEnv,void * theItem)226 static void ReturnModule(
227   void *theEnv,
228   void *theItem)
229   {
230    FreeConstructHeaderModule(theEnv,(struct defmoduleItemHeader *) theItem,DeftemplateData(theEnv)->DeftemplateConstruct);
231    rtn_struct(theEnv,deftemplateModule,theItem);
232   }
233 
234 /****************************************************************/
235 /* GetDeftemplateModuleItem: Returns a pointer to the defmodule */
236 /*  item for the specified deftemplate or defmodule.            */
237 /****************************************************************/
GetDeftemplateModuleItem(void * theEnv,struct defmodule * theModule)238 globle struct deftemplateModule *GetDeftemplateModuleItem(
239   void *theEnv,
240   struct defmodule *theModule)
241   {
242    return((struct deftemplateModule *) GetConstructModuleItemByIndex(theEnv,theModule,DeftemplateData(theEnv)->DeftemplateModuleIndex));
243   }
244 
245 /*****************************************************/
246 /* EnvFindDeftemplate: Searches for a deftemplate in */
247 /*   the list of deftemplates. Returns a pointer to  */
248 /*   the deftemplate if  found, otherwise NULL.      */
249 /*****************************************************/
EnvFindDeftemplate(void * theEnv,const char * deftemplateName)250 globle void *EnvFindDeftemplate(
251   void *theEnv,
252   const char *deftemplateName)
253   {
254    return(FindNamedConstructInModuleOrImports(theEnv,deftemplateName,DeftemplateData(theEnv)->DeftemplateConstruct));
255   }
256 
257 /*****************************************************/
258 /* EnvFindDeftemplateInModule: Searches for a deftemplate in */
259 /*   the list of deftemplates. Returns a pointer to  */
260 /*   the deftemplate if  found, otherwise NULL.      */
261 /*****************************************************/
EnvFindDeftemplateInModule(void * theEnv,const char * deftemplateName)262 globle void *EnvFindDeftemplateInModule(
263   void *theEnv,
264   const char *deftemplateName)
265   {
266    return(FindNamedConstructInModule(theEnv,deftemplateName,DeftemplateData(theEnv)->DeftemplateConstruct));
267   }
268 
269 /***********************************************************************/
270 /* EnvGetNextDeftemplate: If passed a NULL pointer, returns the first  */
271 /*   deftemplate in the ListOfDeftemplates. Otherwise returns the next */
272 /*   deftemplate following the deftemplate passed as an argument.      */
273 /***********************************************************************/
EnvGetNextDeftemplate(void * theEnv,void * deftemplatePtr)274 globle void *EnvGetNextDeftemplate(
275   void *theEnv,
276   void *deftemplatePtr)
277   {
278    return((void *) GetNextConstructItem(theEnv,(struct constructHeader *) deftemplatePtr,DeftemplateData(theEnv)->DeftemplateModuleIndex));
279   }
280 
281 /***********************************************************/
282 /* EnvIsDeftemplateDeletable: Returns TRUE if a particular */
283 /*   deftemplate can be deleted, otherwise returns FALSE.  */
284 /***********************************************************/
EnvIsDeftemplateDeletable(void * theEnv,void * vTheDeftemplate)285 globle intBool EnvIsDeftemplateDeletable(
286   void *theEnv,
287   void *vTheDeftemplate)
288   {
289    struct deftemplate *theDeftemplate = (struct deftemplate *) vTheDeftemplate;
290 
291    if (! ConstructsDeletable(theEnv))
292      { return FALSE; }
293 
294    if (theDeftemplate->busyCount > 0) return(FALSE);
295    if (theDeftemplate->patternNetwork != NULL) return(FALSE);
296 
297    return(TRUE);
298   }
299 
300 /**************************************************************/
301 /* ReturnDeftemplate: Returns the data structures associated  */
302 /*   with a deftemplate construct to the pool of free memory. */
303 /**************************************************************/
ReturnDeftemplate(void * theEnv,void * vTheConstruct)304 static void ReturnDeftemplate(
305   void *theEnv,
306   void *vTheConstruct)
307   {
308 #if (! BLOAD_ONLY) && (! RUN_TIME)
309    struct deftemplate *theConstruct = (struct deftemplate *) vTheConstruct;
310    struct templateSlot *slotPtr;
311 
312    if (theConstruct == NULL) return;
313 
314    /*====================================================================*/
315    /* If a template is redefined, then we want to save its debug status. */
316    /*====================================================================*/
317 
318 #if DEBUGGING_FUNCTIONS
319    DeftemplateData(theEnv)->DeletedTemplateDebugFlags = 0;
320    if (theConstruct->watch) BitwiseSet(DeftemplateData(theEnv)->DeletedTemplateDebugFlags,0);
321 #endif
322 
323    /*===========================================*/
324    /* Free storage used by the templates slots. */
325    /*===========================================*/
326 
327    slotPtr = theConstruct->slotList;
328    while (slotPtr != NULL)
329      {
330       DecrementSymbolCount(theEnv,slotPtr->slotName);
331       RemoveHashedExpression(theEnv,slotPtr->defaultList);
332       slotPtr->defaultList = NULL;
333       RemoveHashedExpression(theEnv,slotPtr->facetList);
334       slotPtr->facetList = NULL;
335       RemoveConstraint(theEnv,slotPtr->constraints);
336       slotPtr->constraints = NULL;
337       slotPtr = slotPtr->next;
338      }
339 
340    ReturnSlots(theEnv,theConstruct->slotList);
341 
342    /*==================================*/
343    /* Free storage used by the header. */
344    /*==================================*/
345 
346    DeinstallConstructHeader(theEnv,&theConstruct->header);
347 
348    rtn_struct(theEnv,deftemplate,theConstruct);
349 #endif
350   }
351 
352 /**************************************************************/
353 /* DestroyDeftemplate: Returns the data structures associated */
354 /*   with a deftemplate construct to the pool of free memory. */
355 /**************************************************************/
DestroyDeftemplate(void * theEnv,void * vTheConstruct)356 static void DestroyDeftemplate(
357   void *theEnv,
358   void *vTheConstruct)
359   {
360    struct deftemplate *theConstruct = (struct deftemplate *) vTheConstruct;
361 #if (! BLOAD_ONLY) && (! RUN_TIME)
362    struct templateSlot *slotPtr, *nextSlot;
363 #endif
364    if (theConstruct == NULL) return;
365 
366 #if (! BLOAD_ONLY) && (! RUN_TIME)
367    slotPtr = theConstruct->slotList;
368 
369    while (slotPtr != NULL)
370      {
371       nextSlot = slotPtr->next;
372       rtn_struct(theEnv,templateSlot,slotPtr);
373       slotPtr = nextSlot;
374      }
375 #endif
376 
377    DestroyFactPatternNetwork(theEnv,theConstruct->patternNetwork);
378 
379    /*==================================*/
380    /* Free storage used by the header. */
381    /*==================================*/
382 
383 #if (! BLOAD_ONLY) && (! RUN_TIME)
384    DeinstallConstructHeader(theEnv,&theConstruct->header);
385 
386    rtn_struct(theEnv,deftemplate,theConstruct);
387 #endif
388   }
389 
390 /***********************************************/
391 /* ReturnSlots: Returns the slot structures of */
392 /*   a deftemplate to free memory.             */
393 /***********************************************/
ReturnSlots(void * theEnv,struct templateSlot * slotPtr)394 globle void ReturnSlots(
395   void *theEnv,
396   struct templateSlot *slotPtr)
397   {
398 #if (! BLOAD_ONLY) && (! RUN_TIME)
399    struct templateSlot *nextSlot;
400 
401    while (slotPtr != NULL)
402      {
403       nextSlot = slotPtr->next;
404       ReturnExpression(theEnv,slotPtr->defaultList);
405       ReturnExpression(theEnv,slotPtr->facetList);
406       RemoveConstraint(theEnv,slotPtr->constraints);
407       rtn_struct(theEnv,templateSlot,slotPtr);
408       slotPtr = nextSlot;
409      }
410 #endif
411   }
412 
413 /*************************************************/
414 /* DecrementDeftemplateBusyCount: Decrements the */
415 /*   busy count of a deftemplate data structure. */
416 /*************************************************/
DecrementDeftemplateBusyCount(void * theEnv,void * vTheTemplate)417 globle void DecrementDeftemplateBusyCount(
418   void *theEnv,
419   void *vTheTemplate)
420   {
421    struct deftemplate *theTemplate = (struct deftemplate *) vTheTemplate;
422 
423    if (! ConstructData(theEnv)->ClearInProgress) theTemplate->busyCount--;
424   }
425 
426 /*************************************************/
427 /* IncrementDeftemplateBusyCount: Increments the */
428 /*   busy count of a deftemplate data structure. */
429 /*************************************************/
IncrementDeftemplateBusyCount(void * theEnv,void * vTheTemplate)430 globle void IncrementDeftemplateBusyCount(
431   void *theEnv,
432   void *vTheTemplate)
433   {
434    struct deftemplate *theTemplate = (struct deftemplate *) vTheTemplate;
435 #if MAC_XCD
436 #pragma unused(theEnv)
437 #endif
438 
439    theTemplate->busyCount++;
440   }
441 
442 /*******************************************************************/
443 /* EnvGetNextFactInTemplate: If passed a NULL pointer, returns the */
444 /*   first fact in the template's fact-list. Otherwise returns the */
445 /*   next template fact following the fact passed as an argument.  */
446 /*******************************************************************/
EnvGetNextFactInTemplate(void * theEnv,void * theTemplate,void * factPtr)447 globle void *EnvGetNextFactInTemplate(
448   void *theEnv,
449   void *theTemplate,
450   void *factPtr)
451   {
452 #if MAC_XCD
453 #pragma unused(theEnv)
454 #endif
455    if (factPtr == NULL)
456      { return((void *) ((struct deftemplate *) theTemplate)->factList); }
457 
458    if (((struct fact *) factPtr)->garbage) return(NULL);
459 
460    return((void *) ((struct fact *) factPtr)->nextTemplateFact);
461   }
462 
463 #if ! RUN_TIME
464 
465 /******************************/
466 /* CreateDeftemplateScopeMap: */
467 /******************************/
CreateDeftemplateScopeMap(void * theEnv,struct deftemplate * theDeftemplate)468 globle void *CreateDeftemplateScopeMap(
469   void *theEnv,
470   struct deftemplate *theDeftemplate)
471   {
472    unsigned scopeMapSize;
473    char *scopeMap;
474    const char *templateName;
475    struct defmodule *matchModule, *theModule;
476    int moduleID,count;
477    void *theBitMap;
478 
479    templateName = ValueToString(theDeftemplate->header.name);
480    matchModule = theDeftemplate->header.whichModule->theModule;
481 
482    scopeMapSize = (sizeof(char) * ((GetNumberOfDefmodules(theEnv) / BITS_PER_BYTE) + 1));
483    scopeMap = (char *) gm2(theEnv,scopeMapSize);
484 
485    ClearBitString((void *) scopeMap,scopeMapSize);
486    SaveCurrentModule(theEnv);
487    for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL) ;
488         theModule != NULL ;
489         theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,(void *) theModule))
490      {
491       EnvSetCurrentModule(theEnv,(void *) theModule);
492       moduleID = (int) theModule->bsaveID;
493       if (FindImportedConstruct(theEnv,"deftemplate",matchModule,
494                                 templateName,&count,TRUE,NULL) != NULL)
495         SetBitMap(scopeMap,moduleID);
496      }
497    RestoreCurrentModule(theEnv);
498    theBitMap = EnvAddBitMap(theEnv,scopeMap,scopeMapSize);
499    IncrementBitMapCount(theBitMap);
500    rm(theEnv,(void *) scopeMap,scopeMapSize);
501    return(theBitMap);
502   }
503 
504 #endif
505 
506 #if RUN_TIME
507 
508 /**************************************************/
509 /* RuntimeDeftemplateAction: Action to be applied */
510 /*   to each deftemplate construct when a runtime */
511 /*   initialization occurs.                       */
512 /**************************************************/
RuntimeDeftemplateAction(void * theEnv,struct constructHeader * theConstruct,void * buffer)513 static void RuntimeDeftemplateAction(
514   void *theEnv,
515   struct constructHeader *theConstruct,
516   void *buffer)
517   {
518 #if MAC_XCD
519 #pragma unused(buffer)
520 #endif
521    struct deftemplate *theDeftemplate = (struct deftemplate *) theConstruct;
522 
523    SearchForHashedPatternNodes(theEnv,theDeftemplate->patternNetwork);
524   }
525 
526 /*******************************************************************/
527 /* SearchForHashedPatternNodes:    */
528 /*******************************************************************/
SearchForHashedPatternNodes(void * theEnv,struct factPatternNode * theNode)529 static void SearchForHashedPatternNodes(
530    void *theEnv,
531    struct factPatternNode *theNode)
532    {
533     while (theNode != NULL)
534       {
535        if ((theNode->lastLevel != NULL) && (theNode->lastLevel->header.selector))
536         { AddHashedPatternNode(theEnv,theNode->lastLevel,theNode,theNode->networkTest->type,theNode->networkTest->value); }
537 
538        SearchForHashedPatternNodes(theEnv,theNode->nextLevel);
539 
540        theNode = theNode->rightNode;
541       }
542    }
543 
544 /*******************************************************************/
545 /* DeftemplateRunTimeInitialize:    */
546 /*******************************************************************/
DeftemplateRunTimeInitialize(void * theEnv)547 globle void DeftemplateRunTimeInitialize(
548   void *theEnv)
549   {
550    DoForAllConstructs(theEnv,RuntimeDeftemplateAction,DeftemplateData(theEnv)->DeftemplateModuleIndex,TRUE,NULL);
551   }
552 
553 #endif /* RUN_TIME */
554 
555 /*##################################*/
556 /* Additional Environment Functions */
557 /*##################################*/
558 
EnvDeftemplateModule(void * theEnv,void * theDeftemplate)559 globle const char *EnvDeftemplateModule(
560   void *theEnv,
561   void *theDeftemplate)
562   {
563    return GetConstructModuleName((struct constructHeader *) theDeftemplate);
564   }
565 
EnvGetDeftemplateName(void * theEnv,void * theDeftemplate)566 globle const char *EnvGetDeftemplateName(
567   void *theEnv,
568   void *theDeftemplate)
569   {
570    return GetConstructNameString((struct constructHeader *) theDeftemplate);
571   }
572 
EnvGetDeftemplatePPForm(void * theEnv,void * theDeftemplate)573 globle const char *EnvGetDeftemplatePPForm(
574   void *theEnv,
575   void *theDeftemplate)
576   {
577    return GetConstructPPForm(theEnv,(struct constructHeader *) theDeftemplate);
578   }
579 
580 /*#####################################*/
581 /* ALLOW_ENVIRONMENT_GLOBALS Functions */
582 /*#####################################*/
583 
584 #if ALLOW_ENVIRONMENT_GLOBALS
585 
DeftemplateModule(void * theDeftemplate)586 globle const char *DeftemplateModule(
587   void *theDeftemplate)
588   {
589    return EnvDeftemplateModule(GetCurrentEnvironment(),theDeftemplate);
590   }
591 
FindDeftemplate(const char * deftemplateName)592 globle void *FindDeftemplate(
593   const char *deftemplateName)
594   {
595    return EnvFindDeftemplate(GetCurrentEnvironment(),deftemplateName);
596   }
597 
GetDeftemplateName(void * theDeftemplate)598 globle const char *GetDeftemplateName(
599   void *theDeftemplate)
600   {
601    return EnvGetDeftemplateName(GetCurrentEnvironment(),theDeftemplate);
602   }
603 
GetDeftemplatePPForm(void * theDeftemplate)604 globle const char *GetDeftemplatePPForm(
605   void *theDeftemplate)
606   {
607    return EnvGetDeftemplatePPForm(GetCurrentEnvironment(),theDeftemplate);
608   }
609 
GetNextDeftemplate(void * deftemplatePtr)610 globle void *GetNextDeftemplate(
611   void *deftemplatePtr)
612   {
613    return EnvGetNextDeftemplate(GetCurrentEnvironment(),deftemplatePtr);
614   }
615 
IsDeftemplateDeletable(void * vTheDeftemplate)616 globle intBool IsDeftemplateDeletable(
617   void *vTheDeftemplate)
618   {
619    return EnvIsDeftemplateDeletable(GetCurrentEnvironment(),vTheDeftemplate);
620   }
621 
GetNextFactInTemplate(void * theTemplate,void * factPtr)622 globle void *GetNextFactInTemplate(
623   void *theTemplate,
624   void *factPtr)
625   {
626    return EnvGetNextFactInTemplate(GetCurrentEnvironment(),theTemplate,factPtr);
627   }
628 
629 #endif /* ALLOW_ENVIRONMENT_GLOBALS */
630 
631 #endif /* DEFTEMPLATE_CONSTRUCT */
632 
633 
634