clipsruby 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/clipsruby/agenda.c +1373 -0
- data/ext/clipsruby/agenda.h +169 -0
- data/ext/clipsruby/analysis.c +1142 -0
- data/ext/clipsruby/analysis.h +61 -0
- data/ext/clipsruby/argacces.c +526 -0
- data/ext/clipsruby/argacces.h +77 -0
- data/ext/clipsruby/bload.c +884 -0
- data/ext/clipsruby/bload.h +94 -0
- data/ext/clipsruby/bmathfun.c +557 -0
- data/ext/clipsruby/bmathfun.h +66 -0
- data/ext/clipsruby/bsave.c +634 -0
- data/ext/clipsruby/bsave.h +130 -0
- data/ext/clipsruby/classcom.c +976 -0
- data/ext/clipsruby/classcom.h +115 -0
- data/ext/clipsruby/classexm.c +1376 -0
- data/ext/clipsruby/classexm.h +97 -0
- data/ext/clipsruby/classfun.c +1392 -0
- data/ext/clipsruby/classfun.h +164 -0
- data/ext/clipsruby/classinf.c +1245 -0
- data/ext/clipsruby/classinf.h +94 -0
- data/ext/clipsruby/classini.c +843 -0
- data/ext/clipsruby/classini.h +75 -0
- data/ext/clipsruby/classpsr.c +957 -0
- data/ext/clipsruby/classpsr.h +73 -0
- data/ext/clipsruby/clips.h +133 -0
- data/ext/clipsruby/clipsruby.c +619 -0
- data/ext/clipsruby/clsltpsr.c +931 -0
- data/ext/clipsruby/clsltpsr.h +72 -0
- data/ext/clipsruby/commline.c +1217 -0
- data/ext/clipsruby/commline.h +131 -0
- data/ext/clipsruby/conscomp.c +1593 -0
- data/ext/clipsruby/conscomp.h +150 -0
- data/ext/clipsruby/constant.h +264 -0
- data/ext/clipsruby/constrct.c +1090 -0
- data/ext/clipsruby/constrct.h +216 -0
- data/ext/clipsruby/constrnt.c +554 -0
- data/ext/clipsruby/constrnt.h +132 -0
- data/ext/clipsruby/crstrtgy.c +1088 -0
- data/ext/clipsruby/crstrtgy.h +85 -0
- data/ext/clipsruby/cstrcbin.c +185 -0
- data/ext/clipsruby/cstrcbin.h +61 -0
- data/ext/clipsruby/cstrccmp.h +43 -0
- data/ext/clipsruby/cstrccom.c +1791 -0
- data/ext/clipsruby/cstrccom.h +115 -0
- data/ext/clipsruby/cstrcpsr.c +835 -0
- data/ext/clipsruby/cstrcpsr.h +97 -0
- data/ext/clipsruby/cstrnbin.c +282 -0
- data/ext/clipsruby/cstrnbin.h +55 -0
- data/ext/clipsruby/cstrnchk.c +826 -0
- data/ext/clipsruby/cstrnchk.h +91 -0
- data/ext/clipsruby/cstrncmp.c +238 -0
- data/ext/clipsruby/cstrncmp.h +57 -0
- data/ext/clipsruby/cstrnops.c +1176 -0
- data/ext/clipsruby/cstrnops.h +47 -0
- data/ext/clipsruby/cstrnpsr.c +1394 -0
- data/ext/clipsruby/cstrnpsr.h +88 -0
- data/ext/clipsruby/cstrnutl.c +564 -0
- data/ext/clipsruby/cstrnutl.h +54 -0
- data/ext/clipsruby/default.c +454 -0
- data/ext/clipsruby/default.h +57 -0
- data/ext/clipsruby/defins.c +971 -0
- data/ext/clipsruby/defins.h +127 -0
- data/ext/clipsruby/developr.c +677 -0
- data/ext/clipsruby/developr.h +69 -0
- data/ext/clipsruby/dffctbin.c +477 -0
- data/ext/clipsruby/dffctbin.h +76 -0
- data/ext/clipsruby/dffctbsc.c +308 -0
- data/ext/clipsruby/dffctbsc.h +72 -0
- data/ext/clipsruby/dffctcmp.c +297 -0
- data/ext/clipsruby/dffctcmp.h +44 -0
- data/ext/clipsruby/dffctdef.c +364 -0
- data/ext/clipsruby/dffctdef.h +104 -0
- data/ext/clipsruby/dffctpsr.c +179 -0
- data/ext/clipsruby/dffctpsr.h +49 -0
- data/ext/clipsruby/dffnxbin.c +520 -0
- data/ext/clipsruby/dffnxbin.h +67 -0
- data/ext/clipsruby/dffnxcmp.c +378 -0
- data/ext/clipsruby/dffnxcmp.h +54 -0
- data/ext/clipsruby/dffnxexe.c +241 -0
- data/ext/clipsruby/dffnxexe.h +58 -0
- data/ext/clipsruby/dffnxfun.c +1192 -0
- data/ext/clipsruby/dffnxfun.h +155 -0
- data/ext/clipsruby/dffnxpsr.c +514 -0
- data/ext/clipsruby/dffnxpsr.h +57 -0
- data/ext/clipsruby/dfinsbin.c +509 -0
- data/ext/clipsruby/dfinsbin.h +66 -0
- data/ext/clipsruby/dfinscmp.c +345 -0
- data/ext/clipsruby/dfinscmp.h +48 -0
- data/ext/clipsruby/drive.c +1191 -0
- data/ext/clipsruby/drive.h +65 -0
- data/ext/clipsruby/emathfun.c +1213 -0
- data/ext/clipsruby/emathfun.h +99 -0
- data/ext/clipsruby/engine.c +1568 -0
- data/ext/clipsruby/engine.h +203 -0
- data/ext/clipsruby/entities.h +276 -0
- data/ext/clipsruby/envrnbld.c +514 -0
- data/ext/clipsruby/envrnbld.h +40 -0
- data/ext/clipsruby/envrnmnt.c +257 -0
- data/ext/clipsruby/envrnmnt.h +112 -0
- data/ext/clipsruby/evaluatn.c +1736 -0
- data/ext/clipsruby/evaluatn.h +211 -0
- data/ext/clipsruby/expressn.c +494 -0
- data/ext/clipsruby/expressn.h +154 -0
- data/ext/clipsruby/exprnbin.c +538 -0
- data/ext/clipsruby/exprnbin.h +60 -0
- data/ext/clipsruby/exprnops.c +564 -0
- data/ext/clipsruby/exprnops.h +67 -0
- data/ext/clipsruby/exprnpsr.c +1112 -0
- data/ext/clipsruby/exprnpsr.h +98 -0
- data/ext/clipsruby/extconf.rb +2 -0
- data/ext/clipsruby/extnfunc.c +1015 -0
- data/ext/clipsruby/extnfunc.h +157 -0
- data/ext/clipsruby/factbin.c +447 -0
- data/ext/clipsruby/factbin.h +56 -0
- data/ext/clipsruby/factbld.c +1035 -0
- data/ext/clipsruby/factbld.h +63 -0
- data/ext/clipsruby/factcmp.c +386 -0
- data/ext/clipsruby/factcmp.h +46 -0
- data/ext/clipsruby/factcom.c +759 -0
- data/ext/clipsruby/factcom.h +80 -0
- data/ext/clipsruby/factfile.c +1761 -0
- data/ext/clipsruby/factfile.h +54 -0
- data/ext/clipsruby/factfun.c +682 -0
- data/ext/clipsruby/factfun.h +77 -0
- data/ext/clipsruby/factgen.c +1305 -0
- data/ext/clipsruby/factgen.h +229 -0
- data/ext/clipsruby/facthsh.c +438 -0
- data/ext/clipsruby/facthsh.h +81 -0
- data/ext/clipsruby/factlhs.c +250 -0
- data/ext/clipsruby/factlhs.h +54 -0
- data/ext/clipsruby/factmch.c +905 -0
- data/ext/clipsruby/factmch.h +68 -0
- data/ext/clipsruby/factmngr.c +3373 -0
- data/ext/clipsruby/factmngr.h +325 -0
- data/ext/clipsruby/factprt.c +498 -0
- data/ext/clipsruby/factprt.h +60 -0
- data/ext/clipsruby/factqpsr.c +796 -0
- data/ext/clipsruby/factqpsr.h +61 -0
- data/ext/clipsruby/factqury.c +1267 -0
- data/ext/clipsruby/factqury.h +112 -0
- data/ext/clipsruby/factrete.c +978 -0
- data/ext/clipsruby/factrete.h +70 -0
- data/ext/clipsruby/factrhs.c +667 -0
- data/ext/clipsruby/factrhs.h +55 -0
- data/ext/clipsruby/filecom.c +353 -0
- data/ext/clipsruby/filecom.h +137 -0
- data/ext/clipsruby/filertr.c +481 -0
- data/ext/clipsruby/filertr.h +94 -0
- data/ext/clipsruby/fileutil.c +1020 -0
- data/ext/clipsruby/fileutil.h +50 -0
- data/ext/clipsruby/generate.c +1079 -0
- data/ext/clipsruby/generate.h +57 -0
- data/ext/clipsruby/genrcbin.c +902 -0
- data/ext/clipsruby/genrcbin.h +69 -0
- data/ext/clipsruby/genrccmp.c +640 -0
- data/ext/clipsruby/genrccmp.h +59 -0
- data/ext/clipsruby/genrccom.c +2017 -0
- data/ext/clipsruby/genrccom.h +119 -0
- data/ext/clipsruby/genrcexe.c +737 -0
- data/ext/clipsruby/genrcexe.h +73 -0
- data/ext/clipsruby/genrcfun.c +890 -0
- data/ext/clipsruby/genrcfun.h +185 -0
- data/ext/clipsruby/genrcpsr.c +1618 -0
- data/ext/clipsruby/genrcpsr.h +80 -0
- data/ext/clipsruby/globlbin.c +458 -0
- data/ext/clipsruby/globlbin.h +71 -0
- data/ext/clipsruby/globlbsc.c +361 -0
- data/ext/clipsruby/globlbsc.h +83 -0
- data/ext/clipsruby/globlcmp.c +330 -0
- data/ext/clipsruby/globlcmp.h +52 -0
- data/ext/clipsruby/globlcom.c +289 -0
- data/ext/clipsruby/globlcom.h +63 -0
- data/ext/clipsruby/globldef.c +1087 -0
- data/ext/clipsruby/globldef.h +151 -0
- data/ext/clipsruby/globlpsr.c +530 -0
- data/ext/clipsruby/globlpsr.h +59 -0
- data/ext/clipsruby/immthpsr.c +431 -0
- data/ext/clipsruby/immthpsr.h +55 -0
- data/ext/clipsruby/incrrset.c +530 -0
- data/ext/clipsruby/incrrset.h +73 -0
- data/ext/clipsruby/inherpsr.c +850 -0
- data/ext/clipsruby/inherpsr.h +52 -0
- data/ext/clipsruby/inscom.c +2076 -0
- data/ext/clipsruby/inscom.h +182 -0
- data/ext/clipsruby/insfile.c +1764 -0
- data/ext/clipsruby/insfile.h +96 -0
- data/ext/clipsruby/insfun.c +1451 -0
- data/ext/clipsruby/insfun.h +134 -0
- data/ext/clipsruby/insmngr.c +2550 -0
- data/ext/clipsruby/insmngr.h +125 -0
- data/ext/clipsruby/insmoddp.c +1041 -0
- data/ext/clipsruby/insmoddp.h +91 -0
- data/ext/clipsruby/insmult.c +804 -0
- data/ext/clipsruby/insmult.h +62 -0
- data/ext/clipsruby/inspsr.c +602 -0
- data/ext/clipsruby/inspsr.h +60 -0
- data/ext/clipsruby/insquery.c +1278 -0
- data/ext/clipsruby/insquery.h +115 -0
- data/ext/clipsruby/insqypsr.c +729 -0
- data/ext/clipsruby/insqypsr.h +63 -0
- data/ext/clipsruby/iofun.c +2045 -0
- data/ext/clipsruby/iofun.h +116 -0
- data/ext/clipsruby/lgcldpnd.c +644 -0
- data/ext/clipsruby/lgcldpnd.h +75 -0
- data/ext/clipsruby/main.c +112 -0
- data/ext/clipsruby/match.h +142 -0
- data/ext/clipsruby/memalloc.c +481 -0
- data/ext/clipsruby/memalloc.h +197 -0
- data/ext/clipsruby/miscfun.c +1801 -0
- data/ext/clipsruby/miscfun.h +132 -0
- data/ext/clipsruby/modulbin.c +607 -0
- data/ext/clipsruby/modulbin.h +84 -0
- data/ext/clipsruby/modulbsc.c +347 -0
- data/ext/clipsruby/modulbsc.h +67 -0
- data/ext/clipsruby/modulcmp.c +499 -0
- data/ext/clipsruby/modulcmp.h +54 -0
- data/ext/clipsruby/moduldef.c +817 -0
- data/ext/clipsruby/moduldef.h +271 -0
- data/ext/clipsruby/modulpsr.c +1150 -0
- data/ext/clipsruby/modulpsr.h +69 -0
- data/ext/clipsruby/modulutl.c +1036 -0
- data/ext/clipsruby/modulutl.h +84 -0
- data/ext/clipsruby/msgcom.c +1221 -0
- data/ext/clipsruby/msgcom.h +125 -0
- data/ext/clipsruby/msgfun.c +1076 -0
- data/ext/clipsruby/msgfun.h +118 -0
- data/ext/clipsruby/msgpass.c +1441 -0
- data/ext/clipsruby/msgpass.h +103 -0
- data/ext/clipsruby/msgpsr.c +698 -0
- data/ext/clipsruby/msgpsr.h +73 -0
- data/ext/clipsruby/multifld.c +1404 -0
- data/ext/clipsruby/multifld.h +130 -0
- data/ext/clipsruby/multifun.c +2182 -0
- data/ext/clipsruby/multifun.h +102 -0
- data/ext/clipsruby/network.h +142 -0
- data/ext/clipsruby/objbin.c +1522 -0
- data/ext/clipsruby/objbin.h +79 -0
- data/ext/clipsruby/objcmp.c +1507 -0
- data/ext/clipsruby/objcmp.h +71 -0
- data/ext/clipsruby/object.h +260 -0
- data/ext/clipsruby/objrtbin.c +701 -0
- data/ext/clipsruby/objrtbin.h +79 -0
- data/ext/clipsruby/objrtbld.c +2393 -0
- data/ext/clipsruby/objrtbld.h +66 -0
- data/ext/clipsruby/objrtcmp.c +734 -0
- data/ext/clipsruby/objrtcmp.h +66 -0
- data/ext/clipsruby/objrtfnx.c +1330 -0
- data/ext/clipsruby/objrtfnx.h +222 -0
- data/ext/clipsruby/objrtgen.c +736 -0
- data/ext/clipsruby/objrtgen.h +63 -0
- data/ext/clipsruby/objrtmch.c +1524 -0
- data/ext/clipsruby/objrtmch.h +160 -0
- data/ext/clipsruby/parsefun.c +415 -0
- data/ext/clipsruby/parsefun.h +67 -0
- data/ext/clipsruby/pattern.c +1265 -0
- data/ext/clipsruby/pattern.h +163 -0
- data/ext/clipsruby/pprint.c +328 -0
- data/ext/clipsruby/pprint.h +79 -0
- data/ext/clipsruby/prccode.c +1478 -0
- data/ext/clipsruby/prccode.h +145 -0
- data/ext/clipsruby/prcdrfun.c +640 -0
- data/ext/clipsruby/prcdrfun.h +95 -0
- data/ext/clipsruby/prcdrpsr.c +1068 -0
- data/ext/clipsruby/prcdrpsr.h +79 -0
- data/ext/clipsruby/prdctfun.c +869 -0
- data/ext/clipsruby/prdctfun.h +77 -0
- data/ext/clipsruby/prntutil.c +878 -0
- data/ext/clipsruby/prntutil.h +125 -0
- data/ext/clipsruby/proflfun.c +827 -0
- data/ext/clipsruby/proflfun.h +118 -0
- data/ext/clipsruby/reorder.c +2082 -0
- data/ext/clipsruby/reorder.h +172 -0
- data/ext/clipsruby/reteutil.c +1732 -0
- data/ext/clipsruby/reteutil.h +111 -0
- data/ext/clipsruby/retract.c +710 -0
- data/ext/clipsruby/retract.h +74 -0
- data/ext/clipsruby/router.c +737 -0
- data/ext/clipsruby/router.h +147 -0
- data/ext/clipsruby/rulebin.c +1136 -0
- data/ext/clipsruby/rulebin.h +153 -0
- data/ext/clipsruby/rulebld.c +1328 -0
- data/ext/clipsruby/rulebld.h +62 -0
- data/ext/clipsruby/rulebsc.c +517 -0
- data/ext/clipsruby/rulebsc.h +91 -0
- data/ext/clipsruby/rulecmp.c +733 -0
- data/ext/clipsruby/rulecmp.h +63 -0
- data/ext/clipsruby/rulecom.c +1583 -0
- data/ext/clipsruby/rulecom.h +116 -0
- data/ext/clipsruby/rulecstr.c +892 -0
- data/ext/clipsruby/rulecstr.h +53 -0
- data/ext/clipsruby/ruledef.c +559 -0
- data/ext/clipsruby/ruledef.h +179 -0
- data/ext/clipsruby/ruledlt.c +599 -0
- data/ext/clipsruby/ruledlt.h +58 -0
- data/ext/clipsruby/rulelhs.c +1216 -0
- data/ext/clipsruby/rulelhs.h +52 -0
- data/ext/clipsruby/rulepsr.c +1073 -0
- data/ext/clipsruby/rulepsr.h +61 -0
- data/ext/clipsruby/scanner.c +856 -0
- data/ext/clipsruby/scanner.h +112 -0
- data/ext/clipsruby/setup.h +488 -0
- data/ext/clipsruby/sortfun.c +433 -0
- data/ext/clipsruby/sortfun.h +55 -0
- data/ext/clipsruby/strngfun.c +1173 -0
- data/ext/clipsruby/strngfun.h +96 -0
- data/ext/clipsruby/strngrtr.c +523 -0
- data/ext/clipsruby/strngrtr.h +97 -0
- data/ext/clipsruby/symblbin.c +648 -0
- data/ext/clipsruby/symblbin.h +64 -0
- data/ext/clipsruby/symblcmp.c +893 -0
- data/ext/clipsruby/symblcmp.h +61 -0
- data/ext/clipsruby/symbol.c +1961 -0
- data/ext/clipsruby/symbol.h +243 -0
- data/ext/clipsruby/sysdep.c +894 -0
- data/ext/clipsruby/sysdep.h +164 -0
- data/ext/clipsruby/textpro.c +1388 -0
- data/ext/clipsruby/textpro.h +77 -0
- data/ext/clipsruby/tmpltbin.c +609 -0
- data/ext/clipsruby/tmpltbin.h +108 -0
- data/ext/clipsruby/tmpltbsc.c +327 -0
- data/ext/clipsruby/tmpltbsc.h +87 -0
- data/ext/clipsruby/tmpltcmp.c +450 -0
- data/ext/clipsruby/tmpltcmp.h +57 -0
- data/ext/clipsruby/tmpltdef.c +584 -0
- data/ext/clipsruby/tmpltdef.h +155 -0
- data/ext/clipsruby/tmpltfun.c +2477 -0
- data/ext/clipsruby/tmpltfun.h +122 -0
- data/ext/clipsruby/tmpltlhs.c +379 -0
- data/ext/clipsruby/tmpltlhs.h +50 -0
- data/ext/clipsruby/tmpltpsr.c +819 -0
- data/ext/clipsruby/tmpltpsr.h +59 -0
- data/ext/clipsruby/tmpltrhs.c +595 -0
- data/ext/clipsruby/tmpltrhs.h +55 -0
- data/ext/clipsruby/tmpltutl.c +637 -0
- data/ext/clipsruby/tmpltutl.h +82 -0
- data/ext/clipsruby/userdata.c +156 -0
- data/ext/clipsruby/userdata.h +72 -0
- data/ext/clipsruby/userfunctions.c +70 -0
- data/ext/clipsruby/usrsetup.h +7 -0
- data/ext/clipsruby/utility.c +1594 -0
- data/ext/clipsruby/utility.h +250 -0
- data/ext/clipsruby/watch.c +865 -0
- data/ext/clipsruby/watch.h +124 -0
- data/lib/clipsruby.rb +1 -0
- metadata +388 -0
@@ -0,0 +1,1568 @@
|
|
1
|
+
/*******************************************************/
|
2
|
+
/* "C" Language Integrated Production System */
|
3
|
+
/* */
|
4
|
+
/* CLIPS Version 6.41 12/04/22 */
|
5
|
+
/* */
|
6
|
+
/* ENGINE MODULE */
|
7
|
+
/*******************************************************/
|
8
|
+
|
9
|
+
/*************************************************************/
|
10
|
+
/* Purpose: Provides functionality primarily associated with */
|
11
|
+
/* the run and focus commands. */
|
12
|
+
/* */
|
13
|
+
/* Principal Programmer(s): */
|
14
|
+
/* Gary D. Riley */
|
15
|
+
/* */
|
16
|
+
/* Contributing Programmer(s): */
|
17
|
+
/* Bebe Ly */
|
18
|
+
/* Brian L. Dantes */
|
19
|
+
/* */
|
20
|
+
/* Revision History: */
|
21
|
+
/* */
|
22
|
+
/* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
|
23
|
+
/* */
|
24
|
+
/* Corrected compilation errors for files */
|
25
|
+
/* generated by constructs-to-c. DR0861 */
|
26
|
+
/* */
|
27
|
+
/* 6.24: Removed DYNAMIC_SALIENCE, INCREMENTAL_RESET, */
|
28
|
+
/* and LOGICAL_DEPENDENCIES compilation flags. */
|
29
|
+
/* */
|
30
|
+
/* Renamed BOOLEAN macro type to intBool. */
|
31
|
+
/* */
|
32
|
+
/* Added access functions to the HaltRules flag. */
|
33
|
+
/* */
|
34
|
+
/* Added EnvGetNextFocus, EnvGetFocusChanged, and */
|
35
|
+
/* EnvSetFocusChanged functions. */
|
36
|
+
/* */
|
37
|
+
/* 6.30: Added additional developer statistics to help */
|
38
|
+
/* analyze join network performance. */
|
39
|
+
/* */
|
40
|
+
/* Removed pseudo-facts used in not CEs. */
|
41
|
+
/* */
|
42
|
+
/* Added context information for run functions. */
|
43
|
+
/* */
|
44
|
+
/* Added before rule firing callback function. */
|
45
|
+
/* */
|
46
|
+
/* Changed garbage collection algorithm. */
|
47
|
+
/* */
|
48
|
+
/* Changed integer type/precision. */
|
49
|
+
/* */
|
50
|
+
/* Added EnvHalt function. */
|
51
|
+
/* */
|
52
|
+
/* Used gensprintf instead of sprintf. */
|
53
|
+
/* */
|
54
|
+
/* Removed conditional code for unsupported */
|
55
|
+
/* compilers/operating systems (IBM_MCW, */
|
56
|
+
/* MAC_MCW, and IBM_TBC). */
|
57
|
+
/* Added const qualifiers to remove C++ */
|
58
|
+
/* deprecation warnings. */
|
59
|
+
/* */
|
60
|
+
/* Converted API macros to function calls. */
|
61
|
+
/* */
|
62
|
+
/* 6.31: Fixed dangling construct issue. */
|
63
|
+
/* */
|
64
|
+
/* 6.40: Added Env prefix to GetEvaluationError and */
|
65
|
+
/* SetEvaluationError functions. */
|
66
|
+
/* */
|
67
|
+
/* Added Env prefix to GetHaltExecution and */
|
68
|
+
/* SetHaltExecution functions. */
|
69
|
+
/* */
|
70
|
+
/* Pragma once and other inclusion changes. */
|
71
|
+
/* */
|
72
|
+
/* Added support for booleans with <stdbool.h>. */
|
73
|
+
/* */
|
74
|
+
/* Removed use of void pointers for specific */
|
75
|
+
/* data structures. */
|
76
|
+
/* */
|
77
|
+
/* ALLOW_ENVIRONMENT_GLOBALS no longer supported. */
|
78
|
+
/* */
|
79
|
+
/* Callbacks must be environment aware. */
|
80
|
+
/* */
|
81
|
+
/* Incremental reset is always enabled. */
|
82
|
+
/* */
|
83
|
+
/* UDF redesign. */
|
84
|
+
/* */
|
85
|
+
/* Added GCBlockStart and GCBlockEnd functions */
|
86
|
+
/* for garbage collection blocks. */
|
87
|
+
/* */
|
88
|
+
/* 6.41: Used gensnprintf in place of gensprintf and. */
|
89
|
+
/* sprintf. */
|
90
|
+
/* */
|
91
|
+
/*************************************************************/
|
92
|
+
|
93
|
+
#include <stdio.h>
|
94
|
+
#include <string.h>
|
95
|
+
|
96
|
+
#include "setup.h"
|
97
|
+
|
98
|
+
#if DEFRULE_CONSTRUCT
|
99
|
+
|
100
|
+
#include "agenda.h"
|
101
|
+
#include "argacces.h"
|
102
|
+
#include "commline.h"
|
103
|
+
#include "constant.h"
|
104
|
+
#include "envrnmnt.h"
|
105
|
+
#include "factmngr.h"
|
106
|
+
#include "inscom.h"
|
107
|
+
#include "memalloc.h"
|
108
|
+
#include "modulutl.h"
|
109
|
+
#include "prccode.h"
|
110
|
+
#include "prcdrfun.h"
|
111
|
+
#include "prntutil.h"
|
112
|
+
#include "proflfun.h"
|
113
|
+
#include "reteutil.h"
|
114
|
+
#include "retract.h"
|
115
|
+
#include "router.h"
|
116
|
+
#include "ruledlt.h"
|
117
|
+
#include "sysdep.h"
|
118
|
+
#include "utility.h"
|
119
|
+
#include "watch.h"
|
120
|
+
|
121
|
+
#include "engine.h"
|
122
|
+
|
123
|
+
/***************************************/
|
124
|
+
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
|
125
|
+
/***************************************/
|
126
|
+
|
127
|
+
static Defmodule *RemoveFocus(Environment *,Defmodule *);
|
128
|
+
static void DeallocateEngineData(Environment *);
|
129
|
+
|
130
|
+
/*****************************************************************************/
|
131
|
+
/* InitializeEngine: Initializes the activations and statistics watch items. */
|
132
|
+
/*****************************************************************************/
|
133
|
+
void InitializeEngine(
|
134
|
+
Environment *theEnv)
|
135
|
+
{
|
136
|
+
AllocateEnvironmentData(theEnv,ENGINE_DATA,sizeof(struct engineData),DeallocateEngineData);
|
137
|
+
|
138
|
+
#if DEBUGGING_FUNCTIONS
|
139
|
+
AddWatchItem(theEnv,"statistics",0,&EngineData(theEnv)->WatchStatistics,20,NULL,NULL);
|
140
|
+
AddWatchItem(theEnv,"focus",0,&EngineData(theEnv)->WatchFocus,0,NULL,NULL);
|
141
|
+
#endif
|
142
|
+
}
|
143
|
+
|
144
|
+
/*************************************************/
|
145
|
+
/* DeallocateEngineData: Deallocates environment */
|
146
|
+
/* data for engine functionality. */
|
147
|
+
/*************************************************/
|
148
|
+
static void DeallocateEngineData(
|
149
|
+
Environment *theEnv)
|
150
|
+
{
|
151
|
+
FocalModule *tmpPtr, *nextPtr;
|
152
|
+
|
153
|
+
DeallocateRuleFiredCallList(theEnv,EngineData(theEnv)->ListOfAfterRuleFiresFunctions);
|
154
|
+
DeallocateRuleFiredCallList(theEnv,EngineData(theEnv)->ListOfBeforeRuleFiresFunctions);
|
155
|
+
|
156
|
+
tmpPtr = EngineData(theEnv)->CurrentFocus;
|
157
|
+
while (tmpPtr != NULL)
|
158
|
+
{
|
159
|
+
nextPtr = tmpPtr->next;
|
160
|
+
rtn_struct(theEnv,focalModule,tmpPtr);
|
161
|
+
tmpPtr = nextPtr;
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
/**********************************************/
|
166
|
+
/* Run: C access routine for the run command. */
|
167
|
+
/**********************************************/
|
168
|
+
long long Run(
|
169
|
+
Environment *theEnv,
|
170
|
+
long long runLimit)
|
171
|
+
{
|
172
|
+
long long rulesFired = 0;
|
173
|
+
UDFValue returnValue;
|
174
|
+
RuleFiredFunctionItem *ruleFiresFunction;
|
175
|
+
#if DEBUGGING_FUNCTIONS
|
176
|
+
unsigned long maxActivations = 0, sumActivations = 0;
|
177
|
+
#if DEFTEMPLATE_CONSTRUCT
|
178
|
+
unsigned long maxFacts = 0, sumFacts = 0;
|
179
|
+
#endif
|
180
|
+
#if OBJECT_SYSTEM
|
181
|
+
unsigned long maxInstances = 0, sumInstances = 0;
|
182
|
+
#endif
|
183
|
+
#if (! GENERIC)
|
184
|
+
double endTime, startTime = 0.0;
|
185
|
+
#endif
|
186
|
+
unsigned long tempValue;
|
187
|
+
#endif
|
188
|
+
unsigned short i;
|
189
|
+
struct patternEntity *theMatchingItem;
|
190
|
+
struct partialMatch *theBasis = NULL;
|
191
|
+
Activation *theActivation;
|
192
|
+
const char *ruleFiring;
|
193
|
+
#if PROFILING_FUNCTIONS
|
194
|
+
struct profileFrameInfo profileFrame;
|
195
|
+
#endif
|
196
|
+
struct trackedMemory *theTM;
|
197
|
+
int danglingConstructs;
|
198
|
+
GCBlock gcb;
|
199
|
+
bool error = false;
|
200
|
+
|
201
|
+
/*=====================================================*/
|
202
|
+
/* Make sure the run command is not already executing. */
|
203
|
+
/*=====================================================*/
|
204
|
+
|
205
|
+
if (EngineData(theEnv)->AlreadyRunning)
|
206
|
+
{ return 0; }
|
207
|
+
EngineData(theEnv)->AlreadyRunning = true;
|
208
|
+
|
209
|
+
/*========================================*/
|
210
|
+
/* Set up the frame for tracking garbage. */
|
211
|
+
/*========================================*/
|
212
|
+
|
213
|
+
GCBlockStart(theEnv,&gcb);
|
214
|
+
|
215
|
+
/*================================*/
|
216
|
+
/* Set up statistics information. */
|
217
|
+
/*================================*/
|
218
|
+
|
219
|
+
#if DEBUGGING_FUNCTIONS
|
220
|
+
if (EngineData(theEnv)->WatchStatistics)
|
221
|
+
{
|
222
|
+
#if DEFTEMPLATE_CONSTRUCT
|
223
|
+
maxFacts = GetNumberOfFacts(theEnv);
|
224
|
+
sumFacts = maxFacts;
|
225
|
+
#endif
|
226
|
+
#if OBJECT_SYSTEM
|
227
|
+
maxInstances = GetGlobalNumberOfInstances(theEnv);
|
228
|
+
sumInstances = maxInstances;
|
229
|
+
#endif
|
230
|
+
maxActivations = GetNumberOfActivations(theEnv);
|
231
|
+
sumActivations = maxActivations;
|
232
|
+
#if (! GENERIC)
|
233
|
+
startTime = gentime();
|
234
|
+
#endif
|
235
|
+
}
|
236
|
+
#endif
|
237
|
+
|
238
|
+
/*=====================================*/
|
239
|
+
/* If embedded, clear the error flags. */
|
240
|
+
/*=====================================*/
|
241
|
+
|
242
|
+
if (EvaluationData(theEnv)->CurrentExpression == NULL)
|
243
|
+
{ ResetErrorFlags(theEnv); }
|
244
|
+
|
245
|
+
/*=============================*/
|
246
|
+
/* Set up execution variables. */
|
247
|
+
/*=============================*/
|
248
|
+
|
249
|
+
EngineData(theEnv)->HaltRules = false;
|
250
|
+
|
251
|
+
#if DEVELOPER
|
252
|
+
EngineData(theEnv)->leftToRightComparisons = 0;
|
253
|
+
EngineData(theEnv)->rightToLeftComparisons = 0;
|
254
|
+
EngineData(theEnv)->leftToRightSucceeds = 0;
|
255
|
+
EngineData(theEnv)->rightToLeftSucceeds = 0;
|
256
|
+
EngineData(theEnv)->leftToRightLoops = 0;
|
257
|
+
EngineData(theEnv)->rightToLeftLoops = 0;
|
258
|
+
EngineData(theEnv)->findNextConflictingComparisons = 0;
|
259
|
+
EngineData(theEnv)->betaHashListSkips = 0;
|
260
|
+
EngineData(theEnv)->betaHashHTSkips = 0;
|
261
|
+
EngineData(theEnv)->unneededMarkerCompare = 0;
|
262
|
+
#endif
|
263
|
+
|
264
|
+
/*=====================================================*/
|
265
|
+
/* Fire rules until the agenda is empty, the run limit */
|
266
|
+
/* has been reached, or a rule execution error occurs. */
|
267
|
+
/*=====================================================*/
|
268
|
+
|
269
|
+
theActivation = NextActivationToFire(theEnv);
|
270
|
+
while ((theActivation != NULL) &&
|
271
|
+
(runLimit != 0) &&
|
272
|
+
(EvaluationData(theEnv)->HaltExecution == false) &&
|
273
|
+
(EngineData(theEnv)->HaltRules == false))
|
274
|
+
{
|
275
|
+
/*========================================*/
|
276
|
+
/* Execute the list of functions that are */
|
277
|
+
/* to be called before each rule firing. */
|
278
|
+
/*========================================*/
|
279
|
+
|
280
|
+
for (ruleFiresFunction = EngineData(theEnv)->ListOfBeforeRuleFiresFunctions;
|
281
|
+
ruleFiresFunction != NULL;
|
282
|
+
ruleFiresFunction = ruleFiresFunction->next)
|
283
|
+
{
|
284
|
+
(*ruleFiresFunction->func)(theEnv,theActivation,ruleFiresFunction->context);
|
285
|
+
}
|
286
|
+
|
287
|
+
/*===========================================*/
|
288
|
+
/* Detach the activation from the agenda and */
|
289
|
+
/* determine which rule is firing. */
|
290
|
+
/*===========================================*/
|
291
|
+
|
292
|
+
DetachActivation(theEnv,theActivation);
|
293
|
+
theTM = AddTrackedMemory(theEnv,theActivation,sizeof(struct activation));
|
294
|
+
ruleFiring = ActivationRuleName(theActivation);
|
295
|
+
theBasis = (struct partialMatch *) GetActivationBasis(theEnv,theActivation);
|
296
|
+
EngineData(theEnv)->ExecutingRule = GetActivationRule(theEnv,theActivation);
|
297
|
+
|
298
|
+
/*=============================================*/
|
299
|
+
/* Update the number of rules that have fired. */
|
300
|
+
/*=============================================*/
|
301
|
+
|
302
|
+
rulesFired++;
|
303
|
+
if (runLimit > 0) { runLimit--; }
|
304
|
+
|
305
|
+
/*==================================*/
|
306
|
+
/* If rules are being watched, then */
|
307
|
+
/* print an information message. */
|
308
|
+
/*==================================*/
|
309
|
+
|
310
|
+
#if DEBUGGING_FUNCTIONS
|
311
|
+
if (EngineData(theEnv)->ExecutingRule->watchFiring)
|
312
|
+
{
|
313
|
+
char printSpace[60];
|
314
|
+
|
315
|
+
gensnprintf(printSpace,sizeof(printSpace),"FIRE %4lld ",rulesFired);
|
316
|
+
WriteString(theEnv,STDOUT,printSpace);
|
317
|
+
WriteString(theEnv,STDOUT,ruleFiring);
|
318
|
+
WriteString(theEnv,STDOUT,": ");
|
319
|
+
PrintPartialMatch(theEnv,STDOUT,theBasis);
|
320
|
+
WriteString(theEnv,STDOUT,"\n");
|
321
|
+
}
|
322
|
+
#endif
|
323
|
+
|
324
|
+
/*=================================================*/
|
325
|
+
/* Remove the link between the activation and the */
|
326
|
+
/* completed match for the rule. Set the busy flag */
|
327
|
+
/* for the completed match to true (so the match */
|
328
|
+
/* upon which our RHS variables are dependent is */
|
329
|
+
/* not deleted while our rule is firing). Set up */
|
330
|
+
/* the global pointers to the completed match for */
|
331
|
+
/* routines which do variable extractions. */
|
332
|
+
/*=================================================*/
|
333
|
+
|
334
|
+
theBasis->marker = NULL;
|
335
|
+
theBasis->busy = true;
|
336
|
+
|
337
|
+
EngineData(theEnv)->GlobalLHSBinds = theBasis;
|
338
|
+
EngineData(theEnv)->GlobalRHSBinds = NULL;
|
339
|
+
|
340
|
+
/*===================================================================*/
|
341
|
+
/* Increment the count for each of the facts/objects associated with */
|
342
|
+
/* the rule activation so that the facts/objects cannot be deleted */
|
343
|
+
/* by garbage collection while the rule is executing. */
|
344
|
+
/*===================================================================*/
|
345
|
+
|
346
|
+
for (i = 0; i < theBasis->bcount; i++)
|
347
|
+
{
|
348
|
+
if (theBasis->binds[i].gm.theMatch == NULL) continue;
|
349
|
+
theMatchingItem = theBasis->binds[i].gm.theMatch->matchingItem;
|
350
|
+
if (theMatchingItem != NULL)
|
351
|
+
{ (*theMatchingItem->theInfo->incrementBasisCount)(theEnv,theMatchingItem); }
|
352
|
+
}
|
353
|
+
|
354
|
+
/*====================================================*/
|
355
|
+
/* If the rule has logical CEs, set up the pointer to */
|
356
|
+
/* the rules logical join so the assert command will */
|
357
|
+
/* attach the appropriate dependencies to the facts. */
|
358
|
+
/*====================================================*/
|
359
|
+
|
360
|
+
EngineData(theEnv)->TheLogicalJoin = EngineData(theEnv)->ExecutingRule->logicalJoin;
|
361
|
+
|
362
|
+
if (EngineData(theEnv)->TheLogicalJoin != NULL)
|
363
|
+
{
|
364
|
+
EngineData(theEnv)->TheLogicalBind = FindLogicalBind(EngineData(theEnv)->TheLogicalJoin,EngineData(theEnv)->GlobalLHSBinds);
|
365
|
+
EngineData(theEnv)->TheLogicalBind->busy = true;
|
366
|
+
}
|
367
|
+
else
|
368
|
+
{ EngineData(theEnv)->TheLogicalBind = NULL; }
|
369
|
+
|
370
|
+
/*=============================================*/
|
371
|
+
/* Execute the rule's right hand side actions. */
|
372
|
+
/*=============================================*/
|
373
|
+
|
374
|
+
EvaluationData(theEnv)->CurrentEvaluationDepth++;
|
375
|
+
SetEvaluationError(theEnv,false);
|
376
|
+
EngineData(theEnv)->ExecutingRule->executing = true;
|
377
|
+
danglingConstructs = ConstructData(theEnv)->DanglingConstructs;
|
378
|
+
|
379
|
+
#if PROFILING_FUNCTIONS
|
380
|
+
StartProfile(theEnv,&profileFrame,
|
381
|
+
&EngineData(theEnv)->ExecutingRule->header.usrData,
|
382
|
+
ProfileFunctionData(theEnv)->ProfileConstructs);
|
383
|
+
#endif
|
384
|
+
|
385
|
+
EvaluateProcActions(theEnv,EngineData(theEnv)->ExecutingRule->header.whichModule->theModule,
|
386
|
+
EngineData(theEnv)->ExecutingRule->actions,EngineData(theEnv)->ExecutingRule->localVarCnt,
|
387
|
+
&returnValue,NULL);
|
388
|
+
|
389
|
+
#if PROFILING_FUNCTIONS
|
390
|
+
EndProfile(theEnv,&profileFrame);
|
391
|
+
#endif
|
392
|
+
|
393
|
+
error = GetEvaluationError(theEnv);
|
394
|
+
EngineData(theEnv)->ExecutingRule->executing = false;
|
395
|
+
SetEvaluationError(theEnv,false);
|
396
|
+
EvaluationData(theEnv)->CurrentEvaluationDepth--;
|
397
|
+
if (EvaluationData(theEnv)->CurrentExpression == NULL)
|
398
|
+
{ ConstructData(theEnv)->DanglingConstructs = danglingConstructs; }
|
399
|
+
|
400
|
+
/*========================================*/
|
401
|
+
/* Execute the list of functions that are */
|
402
|
+
/* to be called after each rule firing. */
|
403
|
+
/*========================================*/
|
404
|
+
|
405
|
+
for (ruleFiresFunction = EngineData(theEnv)->ListOfAfterRuleFiresFunctions;
|
406
|
+
ruleFiresFunction != NULL;
|
407
|
+
ruleFiresFunction = ruleFiresFunction->next)
|
408
|
+
{ (*ruleFiresFunction->func)(theEnv,theActivation,ruleFiresFunction->context); }
|
409
|
+
|
410
|
+
/*=====================================*/
|
411
|
+
/* Remove information for logical CEs. */
|
412
|
+
/*=====================================*/
|
413
|
+
|
414
|
+
EngineData(theEnv)->TheLogicalJoin = NULL;
|
415
|
+
|
416
|
+
if (EngineData(theEnv)->TheLogicalBind != NULL)
|
417
|
+
{
|
418
|
+
EngineData(theEnv)->TheLogicalBind->busy = false;
|
419
|
+
EngineData(theEnv)->TheLogicalBind = NULL;
|
420
|
+
}
|
421
|
+
|
422
|
+
/*=====================================================*/
|
423
|
+
/* If rule execution was halted, then print a message. */
|
424
|
+
/*=====================================================*/
|
425
|
+
|
426
|
+
#if DEBUGGING_FUNCTIONS
|
427
|
+
if ((EvaluationData(theEnv)->HaltExecution) || (EngineData(theEnv)->HaltRules && EngineData(theEnv)->ExecutingRule->watchFiring))
|
428
|
+
#else
|
429
|
+
if ((EvaluationData(theEnv)->HaltExecution) || (EngineData(theEnv)->HaltRules))
|
430
|
+
#endif
|
431
|
+
|
432
|
+
{
|
433
|
+
const char *logName;
|
434
|
+
|
435
|
+
if (error)
|
436
|
+
{
|
437
|
+
PrintErrorID(theEnv,"PRCCODE",4,false);
|
438
|
+
logName = STDERR;
|
439
|
+
}
|
440
|
+
else
|
441
|
+
{
|
442
|
+
PrintWarningID(theEnv,"PRCCODE",4,false);
|
443
|
+
logName = STDWRN;
|
444
|
+
}
|
445
|
+
|
446
|
+
WriteString(theEnv,logName,"Execution halted during the actions of defrule '");
|
447
|
+
WriteString(theEnv,logName,ruleFiring);
|
448
|
+
WriteString(theEnv,logName,"'.\n");
|
449
|
+
}
|
450
|
+
|
451
|
+
/*===================================================*/
|
452
|
+
/* Decrement the count for each of the facts/objects */
|
453
|
+
/* associated with the rule activation. */
|
454
|
+
/*===================================================*/
|
455
|
+
|
456
|
+
theBasis->busy = false;
|
457
|
+
|
458
|
+
for (i = 0; i < (theBasis->bcount); i++)
|
459
|
+
{
|
460
|
+
if (theBasis->binds[i].gm.theMatch == NULL) continue;
|
461
|
+
theMatchingItem = theBasis->binds[i].gm.theMatch->matchingItem;
|
462
|
+
if (theMatchingItem != NULL)
|
463
|
+
{ (*theMatchingItem->theInfo->decrementBasisCount)(theEnv,theMatchingItem); }
|
464
|
+
}
|
465
|
+
|
466
|
+
/*========================================*/
|
467
|
+
/* Return the agenda node to free memory. */
|
468
|
+
/*========================================*/
|
469
|
+
|
470
|
+
RemoveTrackedMemory(theEnv,theTM);
|
471
|
+
RemoveActivation(theEnv,theActivation,false,false);
|
472
|
+
|
473
|
+
/*======================================*/
|
474
|
+
/* Get rid of partial matches discarded */
|
475
|
+
/* while executing the rule's RHS. */
|
476
|
+
/*======================================*/
|
477
|
+
|
478
|
+
FlushGarbagePartialMatches(theEnv);
|
479
|
+
|
480
|
+
/*==================================*/
|
481
|
+
/* Get rid of other garbage created */
|
482
|
+
/* while executing the rule's RHS. */
|
483
|
+
/*==================================*/
|
484
|
+
|
485
|
+
CleanCurrentGarbageFrame(theEnv,NULL);
|
486
|
+
CallPeriodicTasks(theEnv);
|
487
|
+
|
488
|
+
/*==========================*/
|
489
|
+
/* Keep up with statistics. */
|
490
|
+
/*==========================*/
|
491
|
+
|
492
|
+
#if DEBUGGING_FUNCTIONS
|
493
|
+
if (EngineData(theEnv)->WatchStatistics)
|
494
|
+
{
|
495
|
+
#if DEFTEMPLATE_CONSTRUCT
|
496
|
+
tempValue = GetNumberOfFacts(theEnv);
|
497
|
+
if (tempValue > maxFacts) maxFacts = tempValue;
|
498
|
+
sumFacts += tempValue;
|
499
|
+
#endif
|
500
|
+
#if OBJECT_SYSTEM
|
501
|
+
tempValue = GetGlobalNumberOfInstances(theEnv);
|
502
|
+
if (tempValue > maxInstances) maxInstances = tempValue;
|
503
|
+
sumInstances += tempValue;
|
504
|
+
#endif
|
505
|
+
tempValue = GetNumberOfActivations(theEnv);
|
506
|
+
if (tempValue > maxActivations) maxActivations = tempValue;
|
507
|
+
sumActivations += tempValue;
|
508
|
+
}
|
509
|
+
#endif
|
510
|
+
|
511
|
+
/*==================================*/
|
512
|
+
/* Update saliences if appropriate. */
|
513
|
+
/*==================================*/
|
514
|
+
|
515
|
+
if (GetSalienceEvaluation(theEnv) == EVERY_CYCLE)
|
516
|
+
{ RefreshAllAgendas(theEnv); }
|
517
|
+
|
518
|
+
/*========================================*/
|
519
|
+
/* If a return was issued on the RHS of a */
|
520
|
+
/* rule, then remove *that* rule's module */
|
521
|
+
/* from the focus stack */
|
522
|
+
/*========================================*/
|
523
|
+
|
524
|
+
if (ProcedureFunctionData(theEnv)->ReturnFlag == true)
|
525
|
+
{ RemoveFocus(theEnv,EngineData(theEnv)->ExecutingRule->header.whichModule->theModule); }
|
526
|
+
ProcedureFunctionData(theEnv)->ReturnFlag = false;
|
527
|
+
|
528
|
+
/*========================================*/
|
529
|
+
/* Determine the next activation to fire. */
|
530
|
+
/*========================================*/
|
531
|
+
|
532
|
+
theActivation = (struct activation *) NextActivationToFire(theEnv);
|
533
|
+
|
534
|
+
/*==============================*/
|
535
|
+
/* Check for a rule breakpoint. */
|
536
|
+
/*==============================*/
|
537
|
+
|
538
|
+
if (theActivation != NULL)
|
539
|
+
{
|
540
|
+
if (GetActivationRule(theEnv,theActivation)->afterBreakpoint)
|
541
|
+
{
|
542
|
+
EngineData(theEnv)->HaltRules = true;
|
543
|
+
WriteString(theEnv,STDOUT,"Breaking on rule ");
|
544
|
+
WriteString(theEnv,STDOUT,ActivationRuleName(theActivation));
|
545
|
+
WriteString(theEnv,STDOUT,".\n");
|
546
|
+
}
|
547
|
+
}
|
548
|
+
}
|
549
|
+
|
550
|
+
/*=====================================================*/
|
551
|
+
/* Make sure run functions are executed at least once. */
|
552
|
+
/*=====================================================*/
|
553
|
+
|
554
|
+
if (rulesFired == 0)
|
555
|
+
{
|
556
|
+
for (ruleFiresFunction = EngineData(theEnv)->ListOfAfterRuleFiresFunctions;
|
557
|
+
ruleFiresFunction != NULL;
|
558
|
+
ruleFiresFunction = ruleFiresFunction->next)
|
559
|
+
{ (*ruleFiresFunction->func)(theEnv,NULL,ruleFiresFunction->context); }
|
560
|
+
}
|
561
|
+
|
562
|
+
/*======================================================*/
|
563
|
+
/* If rule execution was halted because the rule firing */
|
564
|
+
/* limit was reached, then print a message. */
|
565
|
+
/*======================================================*/
|
566
|
+
|
567
|
+
if (runLimit == rulesFired)
|
568
|
+
{ WriteString(theEnv,STDOUT,"rule firing limit reached\n"); }
|
569
|
+
|
570
|
+
/*==============================*/
|
571
|
+
/* Restore execution variables. */
|
572
|
+
/*==============================*/
|
573
|
+
|
574
|
+
EngineData(theEnv)->ExecutingRule = NULL;
|
575
|
+
EngineData(theEnv)->HaltRules = false;
|
576
|
+
|
577
|
+
/*=================================================*/
|
578
|
+
/* Print out statistics if they are being watched. */
|
579
|
+
/*=================================================*/
|
580
|
+
|
581
|
+
#if DEBUGGING_FUNCTIONS
|
582
|
+
if (EngineData(theEnv)->WatchStatistics)
|
583
|
+
{
|
584
|
+
#if DEFTEMPLATE_CONSTRUCT || OBJECT_SYSTEM || DEVELOPER
|
585
|
+
char printSpace[60];
|
586
|
+
#endif
|
587
|
+
#if (! GENERIC)
|
588
|
+
endTime = gentime();
|
589
|
+
#endif
|
590
|
+
|
591
|
+
WriteInteger(theEnv,STDOUT,rulesFired);
|
592
|
+
WriteString(theEnv,STDOUT," rules fired");
|
593
|
+
|
594
|
+
#if (! GENERIC)
|
595
|
+
if (startTime != endTime)
|
596
|
+
{
|
597
|
+
WriteString(theEnv,STDOUT," Run time is ");
|
598
|
+
WriteFloat(theEnv,STDOUT,endTime - startTime);
|
599
|
+
WriteString(theEnv,STDOUT," seconds.\n");
|
600
|
+
WriteFloat(theEnv,STDOUT,(double) rulesFired / (endTime - startTime));
|
601
|
+
WriteString(theEnv,STDOUT," rules per second.\n");
|
602
|
+
}
|
603
|
+
else
|
604
|
+
{ WriteString(theEnv,STDOUT,"\n"); }
|
605
|
+
#else
|
606
|
+
WriteString(theEnv,STDOUT,"\n");
|
607
|
+
#endif
|
608
|
+
|
609
|
+
#if DEFTEMPLATE_CONSTRUCT
|
610
|
+
gensnprintf(printSpace,sizeof(printSpace),"%ld mean number of facts (%ld maximum).\n",
|
611
|
+
(long) (((double) sumFacts / (rulesFired + 1)) + 0.5),
|
612
|
+
maxFacts);
|
613
|
+
WriteString(theEnv,STDOUT,printSpace);
|
614
|
+
#endif
|
615
|
+
|
616
|
+
#if OBJECT_SYSTEM
|
617
|
+
gensnprintf(printSpace,sizeof(printSpace),"%ld mean number of instances (%ld maximum).\n",
|
618
|
+
(long) (((double) sumInstances / (rulesFired + 1)) + 0.5),
|
619
|
+
maxInstances);
|
620
|
+
WriteString(theEnv,STDOUT,printSpace);
|
621
|
+
#endif
|
622
|
+
|
623
|
+
gensnprintf(printSpace,sizeof(printSpace),"%ld mean number of activations (%ld maximum).\n",
|
624
|
+
(long) (((double) sumActivations / (rulesFired + 1)) + 0.5),
|
625
|
+
maxActivations);
|
626
|
+
WriteString(theEnv,STDOUT,printSpace);
|
627
|
+
|
628
|
+
#if DEVELOPER
|
629
|
+
gensnprintf(printSpace,sizeof(printSpace),"%9ld left to right comparisons.\n",
|
630
|
+
EngineData(theEnv)->leftToRightComparisons);
|
631
|
+
WriteString(theEnv,STDOUT,printSpace);
|
632
|
+
|
633
|
+
gensnprintf(printSpace,sizeof(printSpace),"%9ld left to right succeeds.\n",
|
634
|
+
EngineData(theEnv)->leftToRightSucceeds);
|
635
|
+
WriteString(theEnv,STDOUT,printSpace);
|
636
|
+
|
637
|
+
gensnprintf(printSpace,sizeof(printSpace),"%9ld left to right loops.\n",
|
638
|
+
EngineData(theEnv)->leftToRightLoops);
|
639
|
+
WriteString(theEnv,STDOUT,printSpace);
|
640
|
+
|
641
|
+
gensnprintf(printSpace,sizeof(printSpace),"%9ld right to left comparisons.\n",
|
642
|
+
EngineData(theEnv)->rightToLeftComparisons);
|
643
|
+
WriteString(theEnv,STDOUT,printSpace);
|
644
|
+
|
645
|
+
gensnprintf(printSpace,sizeof(printSpace),"%9ld right to left succeeds.\n",
|
646
|
+
EngineData(theEnv)->rightToLeftSucceeds);
|
647
|
+
WriteString(theEnv,STDOUT,printSpace);
|
648
|
+
|
649
|
+
gensnprintf(printSpace,sizeof(printSpace),"%9ld right to left loops.\n",
|
650
|
+
EngineData(theEnv)->rightToLeftLoops);
|
651
|
+
WriteString(theEnv,STDOUT,printSpace);
|
652
|
+
|
653
|
+
gensnprintf(printSpace,sizeof(printSpace),"%9ld find next conflicting comparisons.\n",
|
654
|
+
EngineData(theEnv)->findNextConflictingComparisons);
|
655
|
+
WriteString(theEnv,STDOUT,printSpace);
|
656
|
+
|
657
|
+
gensnprintf(printSpace,sizeof(printSpace),"%9ld beta hash list skips.\n",
|
658
|
+
EngineData(theEnv)->betaHashListSkips);
|
659
|
+
WriteString(theEnv,STDOUT,printSpace);
|
660
|
+
|
661
|
+
gensnprintf(printSpace,sizeof(printSpace),"%9ld beta hash hash table skips.\n",
|
662
|
+
EngineData(theEnv)->betaHashHTSkips);
|
663
|
+
WriteString(theEnv,STDOUT,printSpace);
|
664
|
+
|
665
|
+
gensnprintf(printSpace,sizeof(printSpace),"%9ld unneeded marker compare.\n",
|
666
|
+
EngineData(theEnv)->unneededMarkerCompare);
|
667
|
+
WriteString(theEnv,STDOUT,printSpace);
|
668
|
+
|
669
|
+
#endif
|
670
|
+
}
|
671
|
+
#endif
|
672
|
+
|
673
|
+
/*==========================================*/
|
674
|
+
/* The current module should be the current */
|
675
|
+
/* focus when the run finishes. */
|
676
|
+
/*==========================================*/
|
677
|
+
|
678
|
+
if (EngineData(theEnv)->CurrentFocus != NULL)
|
679
|
+
{
|
680
|
+
if (EngineData(theEnv)->CurrentFocus->theModule != GetCurrentModule(theEnv))
|
681
|
+
{ SetCurrentModule(theEnv,EngineData(theEnv)->CurrentFocus->theModule); }
|
682
|
+
}
|
683
|
+
|
684
|
+
/*================================*/
|
685
|
+
/* Restore the old garbage frame. */
|
686
|
+
/*================================*/
|
687
|
+
|
688
|
+
GCBlockEnd(theEnv,&gcb);
|
689
|
+
CallPeriodicTasks(theEnv);
|
690
|
+
|
691
|
+
/*===================================*/
|
692
|
+
/* Return the number of rules fired. */
|
693
|
+
/*===================================*/
|
694
|
+
|
695
|
+
EngineData(theEnv)->AlreadyRunning = false;
|
696
|
+
return rulesFired;
|
697
|
+
}
|
698
|
+
|
699
|
+
/***********************************************************/
|
700
|
+
/* NextActivationToFire: Returns the next activation which */
|
701
|
+
/* should be executed based on the current focus. */
|
702
|
+
/***********************************************************/
|
703
|
+
Activation *NextActivationToFire(
|
704
|
+
Environment *theEnv)
|
705
|
+
{
|
706
|
+
struct activation *theActivation;
|
707
|
+
Defmodule *theModule;
|
708
|
+
|
709
|
+
/*====================================*/
|
710
|
+
/* If there is no current focus, then */
|
711
|
+
/* focus on the MAIN module. */
|
712
|
+
/*====================================*/
|
713
|
+
|
714
|
+
if (EngineData(theEnv)->CurrentFocus == NULL)
|
715
|
+
{
|
716
|
+
theModule = FindDefmodule(theEnv,"MAIN");
|
717
|
+
Focus(theModule);
|
718
|
+
}
|
719
|
+
|
720
|
+
/*===========================================================*/
|
721
|
+
/* Determine the top activation on the agenda of the current */
|
722
|
+
/* focus. If the current focus has no activations on its */
|
723
|
+
/* agenda, then pop the focus off the focus stack until */
|
724
|
+
/* a focus that has an activation on its agenda is found. */
|
725
|
+
/*===========================================================*/
|
726
|
+
|
727
|
+
theActivation = EngineData(theEnv)->CurrentFocus->theDefruleModule->agenda;
|
728
|
+
while ((theActivation == NULL) && (EngineData(theEnv)->CurrentFocus != NULL))
|
729
|
+
{
|
730
|
+
if (EngineData(theEnv)->CurrentFocus != NULL) PopFocus(theEnv);
|
731
|
+
if (EngineData(theEnv)->CurrentFocus != NULL) theActivation = EngineData(theEnv)->CurrentFocus->theDefruleModule->agenda;
|
732
|
+
}
|
733
|
+
|
734
|
+
/*=========================================*/
|
735
|
+
/* Return the next activation to be fired. */
|
736
|
+
/*=========================================*/
|
737
|
+
|
738
|
+
return(theActivation);
|
739
|
+
}
|
740
|
+
|
741
|
+
/***************************************************/
|
742
|
+
/* RemoveFocus: Removes the first occurence of the */
|
743
|
+
/* specified module from the focus stack. */
|
744
|
+
/***************************************************/
|
745
|
+
static Defmodule *RemoveFocus(
|
746
|
+
Environment *theEnv,
|
747
|
+
Defmodule *theModule)
|
748
|
+
{
|
749
|
+
FocalModule *tempFocus,*prevFocus, *nextFocus;
|
750
|
+
bool found = false;
|
751
|
+
bool currentFocusRemoved = false;
|
752
|
+
|
753
|
+
/*====================================*/
|
754
|
+
/* Return NULL if there is nothing on */
|
755
|
+
/* the focus stack to remove. */
|
756
|
+
/*====================================*/
|
757
|
+
|
758
|
+
if (EngineData(theEnv)->CurrentFocus == NULL) return NULL;
|
759
|
+
|
760
|
+
/*=============================================*/
|
761
|
+
/* Remove the first occurence of the specified */
|
762
|
+
/* module from the focus stack. */
|
763
|
+
/*=============================================*/
|
764
|
+
|
765
|
+
prevFocus = NULL;
|
766
|
+
tempFocus = EngineData(theEnv)->CurrentFocus;
|
767
|
+
while ((tempFocus != NULL) && (! found))
|
768
|
+
{
|
769
|
+
if (tempFocus->theModule == theModule)
|
770
|
+
{
|
771
|
+
found = true;
|
772
|
+
|
773
|
+
nextFocus = tempFocus->next;
|
774
|
+
rtn_struct(theEnv,focalModule,tempFocus);
|
775
|
+
tempFocus = nextFocus;
|
776
|
+
|
777
|
+
if (prevFocus == NULL)
|
778
|
+
{
|
779
|
+
currentFocusRemoved = true;
|
780
|
+
EngineData(theEnv)->CurrentFocus = tempFocus;
|
781
|
+
}
|
782
|
+
else
|
783
|
+
{ prevFocus->next = tempFocus; }
|
784
|
+
}
|
785
|
+
else
|
786
|
+
{
|
787
|
+
prevFocus = tempFocus;
|
788
|
+
tempFocus = tempFocus->next;
|
789
|
+
}
|
790
|
+
}
|
791
|
+
|
792
|
+
/*=========================================*/
|
793
|
+
/* If the given module is not in the focus */
|
794
|
+
/* stack, simply return the current focus */
|
795
|
+
/*=========================================*/
|
796
|
+
|
797
|
+
if (! found) return EngineData(theEnv)->CurrentFocus->theModule;
|
798
|
+
|
799
|
+
/*========================================*/
|
800
|
+
/* If the current focus is being watched, */
|
801
|
+
/* then print an informational message. */
|
802
|
+
/*========================================*/
|
803
|
+
|
804
|
+
#if DEBUGGING_FUNCTIONS
|
805
|
+
if (EngineData(theEnv)->WatchFocus &&
|
806
|
+
(! ConstructData(theEnv)->ClearReadyInProgress) &&
|
807
|
+
(! ConstructData(theEnv)->ClearInProgress))
|
808
|
+
{
|
809
|
+
WriteString(theEnv,STDOUT,"<== Focus ");
|
810
|
+
WriteString(theEnv,STDOUT,theModule->header.name->contents);
|
811
|
+
|
812
|
+
if ((EngineData(theEnv)->CurrentFocus != NULL) && currentFocusRemoved)
|
813
|
+
{
|
814
|
+
WriteString(theEnv,STDOUT," to ");
|
815
|
+
WriteString(theEnv,STDOUT,EngineData(theEnv)->CurrentFocus->theModule->header.name->contents);
|
816
|
+
}
|
817
|
+
|
818
|
+
WriteString(theEnv,STDOUT,"\n");
|
819
|
+
}
|
820
|
+
#endif
|
821
|
+
|
822
|
+
/*======================================================*/
|
823
|
+
/* Set the current module to the module associated with */
|
824
|
+
/* the current focus (if it changed) and set a boolean */
|
825
|
+
/* flag indicating that the focus has changed. */
|
826
|
+
/*======================================================*/
|
827
|
+
|
828
|
+
if ((EngineData(theEnv)->CurrentFocus != NULL) && currentFocusRemoved)
|
829
|
+
{ SetCurrentModule(theEnv,EngineData(theEnv)->CurrentFocus->theModule); }
|
830
|
+
EngineData(theEnv)->FocusChanged = true;
|
831
|
+
|
832
|
+
/*====================================*/
|
833
|
+
/* Return the module that was removed */
|
834
|
+
/* from the focus stack. */
|
835
|
+
/*====================================*/
|
836
|
+
|
837
|
+
return(theModule);
|
838
|
+
}
|
839
|
+
|
840
|
+
/**********************************************************/
|
841
|
+
/* PopFocus: C access routine for the pop-focus function. */
|
842
|
+
/**********************************************************/
|
843
|
+
Defmodule *PopFocus(
|
844
|
+
Environment *theEnv)
|
845
|
+
{
|
846
|
+
if (EngineData(theEnv)->CurrentFocus == NULL) return NULL;
|
847
|
+
return RemoveFocus(theEnv,EngineData(theEnv)->CurrentFocus->theModule);
|
848
|
+
}
|
849
|
+
|
850
|
+
/************************************************************/
|
851
|
+
/* GetNextFocus: Returns the next focus on the focus stack. */
|
852
|
+
/************************************************************/
|
853
|
+
FocalModule *GetNextFocus(
|
854
|
+
Environment *theEnv,
|
855
|
+
FocalModule *theFocus)
|
856
|
+
{
|
857
|
+
/*==================================================*/
|
858
|
+
/* If NULL is passed as an argument, return the top */
|
859
|
+
/* focus on the focus stack (the current focus). */
|
860
|
+
/*==================================================*/
|
861
|
+
|
862
|
+
if (theFocus == NULL) return EngineData(theEnv)->CurrentFocus;
|
863
|
+
|
864
|
+
/*=======================================*/
|
865
|
+
/* Otherwise, return the focus following */
|
866
|
+
/* the focus passed as an argument. */
|
867
|
+
/*=======================================*/
|
868
|
+
|
869
|
+
return theFocus->next;
|
870
|
+
}
|
871
|
+
|
872
|
+
/*********************************************************/
|
873
|
+
/* FocalModuleName: Returns the name of the FocalModule. */
|
874
|
+
/*********************************************************/
|
875
|
+
const char *FocalModuleName(
|
876
|
+
FocalModule *theFocus)
|
877
|
+
{
|
878
|
+
return theFocus->theModule->header.name->contents;
|
879
|
+
}
|
880
|
+
|
881
|
+
/****************************************************************/
|
882
|
+
/* FocalModuleModule: Returns the Defmodule of the FocalModule. */
|
883
|
+
/****************************************************************/
|
884
|
+
Defmodule *FocalModuleModule(
|
885
|
+
FocalModule *theFocus)
|
886
|
+
{
|
887
|
+
return theFocus->theModule;
|
888
|
+
}
|
889
|
+
|
890
|
+
/***************************************************/
|
891
|
+
/* Focus: C access routine for the focus function. */
|
892
|
+
/***************************************************/
|
893
|
+
void Focus(
|
894
|
+
Defmodule *theModule)
|
895
|
+
{
|
896
|
+
FocalModule *tempFocus;
|
897
|
+
Environment *theEnv;
|
898
|
+
|
899
|
+
if (theModule == NULL) return;
|
900
|
+
|
901
|
+
theEnv = theModule->header.env;
|
902
|
+
|
903
|
+
/*==================================================*/
|
904
|
+
/* Make the specified module be the current module. */
|
905
|
+
/* If the specified module is the current focus, */
|
906
|
+
/* then no further action is needed. */
|
907
|
+
/*==================================================*/
|
908
|
+
|
909
|
+
SetCurrentModule(theEnv,theModule);
|
910
|
+
if (EngineData(theEnv)->CurrentFocus != NULL)
|
911
|
+
{ if (EngineData(theEnv)->CurrentFocus->theModule == theModule) return; }
|
912
|
+
|
913
|
+
/*=====================================*/
|
914
|
+
/* If the focus is being watched, then */
|
915
|
+
/* print an information message. */
|
916
|
+
/*=====================================*/
|
917
|
+
|
918
|
+
#if DEBUGGING_FUNCTIONS
|
919
|
+
if (EngineData(theEnv)->WatchFocus &&
|
920
|
+
(! ConstructData(theEnv)->ClearReadyInProgress) &&
|
921
|
+
(! ConstructData(theEnv)->ClearInProgress))
|
922
|
+
{
|
923
|
+
WriteString(theEnv,STDOUT,"==> Focus ");
|
924
|
+
WriteString(theEnv,STDOUT,theModule->header.name->contents);
|
925
|
+
if (EngineData(theEnv)->CurrentFocus != NULL)
|
926
|
+
{
|
927
|
+
WriteString(theEnv,STDOUT," from ");
|
928
|
+
WriteString(theEnv,STDOUT,EngineData(theEnv)->CurrentFocus->theModule->header.name->contents);
|
929
|
+
}
|
930
|
+
WriteString(theEnv,STDOUT,"\n");
|
931
|
+
}
|
932
|
+
#endif
|
933
|
+
|
934
|
+
/*=======================================*/
|
935
|
+
/* Add the new focus to the focus stack. */
|
936
|
+
/*=======================================*/
|
937
|
+
|
938
|
+
tempFocus = get_struct(theEnv,focalModule);
|
939
|
+
tempFocus->theModule = theModule;
|
940
|
+
tempFocus->theDefruleModule = GetDefruleModuleItem(theEnv,theModule);
|
941
|
+
tempFocus->next = EngineData(theEnv)->CurrentFocus;
|
942
|
+
EngineData(theEnv)->CurrentFocus = tempFocus;
|
943
|
+
EngineData(theEnv)->FocusChanged = true;
|
944
|
+
}
|
945
|
+
|
946
|
+
/************************************************/
|
947
|
+
/* ClearFocusStackCommand: H/L access routine */
|
948
|
+
/* for the clear-focus-stack command. */
|
949
|
+
/************************************************/
|
950
|
+
void ClearFocusStackCommand(
|
951
|
+
Environment *theEnv,
|
952
|
+
UDFContext *context,
|
953
|
+
UDFValue *returnValue)
|
954
|
+
{
|
955
|
+
ClearFocusStack(theEnv);
|
956
|
+
}
|
957
|
+
|
958
|
+
/****************************************/
|
959
|
+
/* ClearFocusStack: C access routine */
|
960
|
+
/* for the clear-focus-stack command. */
|
961
|
+
/****************************************/
|
962
|
+
void ClearFocusStack(
|
963
|
+
Environment *theEnv)
|
964
|
+
{
|
965
|
+
while (EngineData(theEnv)->CurrentFocus != NULL) PopFocus(theEnv);
|
966
|
+
|
967
|
+
EngineData(theEnv)->FocusChanged = true;
|
968
|
+
}
|
969
|
+
|
970
|
+
/**********************************************/
|
971
|
+
/* AddAfterRuleFiresFunction: Adds a function */
|
972
|
+
/* to the ListOfAfterRuleFiresFunctions. */
|
973
|
+
/**********************************************/
|
974
|
+
bool AddAfterRuleFiresFunction(
|
975
|
+
Environment *theEnv,
|
976
|
+
const char *name,
|
977
|
+
RuleFiredFunction *functionPtr,
|
978
|
+
int priority,
|
979
|
+
void *context)
|
980
|
+
{
|
981
|
+
EngineData(theEnv)->ListOfAfterRuleFiresFunctions =
|
982
|
+
AddRuleFiredFunctionToCallList(theEnv,name,priority,functionPtr,
|
983
|
+
EngineData(theEnv)->ListOfAfterRuleFiresFunctions,context);
|
984
|
+
return true;
|
985
|
+
}
|
986
|
+
|
987
|
+
/***********************************************/
|
988
|
+
/* AddBeforeRuleFiresFunction: Adds a function */
|
989
|
+
/* to the ListOfBeforeRuleFiresFunctions. */
|
990
|
+
/***********************************************/
|
991
|
+
bool AddBeforeRuleFiresFunction(
|
992
|
+
Environment *theEnv,
|
993
|
+
const char *name,
|
994
|
+
RuleFiredFunction *functionPtr,
|
995
|
+
int priority,
|
996
|
+
void *context)
|
997
|
+
{
|
998
|
+
EngineData(theEnv)->ListOfBeforeRuleFiresFunctions =
|
999
|
+
AddRuleFiredFunctionToCallList(theEnv,name,priority,functionPtr,
|
1000
|
+
EngineData(theEnv)->ListOfBeforeRuleFiresFunctions,context);
|
1001
|
+
return true;
|
1002
|
+
}
|
1003
|
+
|
1004
|
+
/****************************************************/
|
1005
|
+
/* RemoveAfterRuleFiresFunction: Removes a function */
|
1006
|
+
/* from the ListOfAfterRuleFiresFunctions. */
|
1007
|
+
/****************************************************/
|
1008
|
+
bool RemoveAfterRuleFiresFunction(
|
1009
|
+
Environment *theEnv,
|
1010
|
+
const char *name)
|
1011
|
+
{
|
1012
|
+
bool found;
|
1013
|
+
|
1014
|
+
EngineData(theEnv)->ListOfAfterRuleFiresFunctions =
|
1015
|
+
RemoveRuleFiredFunctionFromCallList(theEnv,name,EngineData(theEnv)->ListOfAfterRuleFiresFunctions,&found);
|
1016
|
+
|
1017
|
+
return found;
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
/*****************************************************/
|
1021
|
+
/* RemoveBeforeRuleFiresFunction: Removes a function */
|
1022
|
+
/* from the ListOfBeforeRuleFiresFunctions. */
|
1023
|
+
/*****************************************************/
|
1024
|
+
bool RemoveBeforeRuleFiresFunction(
|
1025
|
+
Environment *theEnv,
|
1026
|
+
const char *name)
|
1027
|
+
{
|
1028
|
+
bool found;
|
1029
|
+
|
1030
|
+
EngineData(theEnv)->ListOfBeforeRuleFiresFunctions =
|
1031
|
+
RemoveRuleFiredFunctionFromCallList(theEnv,name,EngineData(theEnv)->ListOfBeforeRuleFiresFunctions,&found);
|
1032
|
+
|
1033
|
+
return found;
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
/***************************************************/
|
1037
|
+
/* AddRuleFiredFunctionToCallList: Adds a function */
|
1038
|
+
/* to a rule fired function list. */
|
1039
|
+
/***************************************************/
|
1040
|
+
RuleFiredFunctionItem *AddRuleFiredFunctionToCallList(
|
1041
|
+
Environment *theEnv,
|
1042
|
+
const char *name,
|
1043
|
+
int priority,
|
1044
|
+
RuleFiredFunction *func,
|
1045
|
+
RuleFiredFunctionItem *head,
|
1046
|
+
void *context)
|
1047
|
+
{
|
1048
|
+
RuleFiredFunctionItem *newPtr, *currentPtr, *lastPtr = NULL;
|
1049
|
+
char *nameCopy;
|
1050
|
+
|
1051
|
+
newPtr = get_struct(theEnv,ruleFiredFunctionItem);
|
1052
|
+
|
1053
|
+
nameCopy = (char *) genalloc(theEnv,strlen(name) + 1);
|
1054
|
+
genstrcpy(nameCopy,name);
|
1055
|
+
newPtr->name = nameCopy;
|
1056
|
+
|
1057
|
+
newPtr->func = func;
|
1058
|
+
newPtr->priority = priority;
|
1059
|
+
newPtr->context = context;
|
1060
|
+
|
1061
|
+
if (head == NULL)
|
1062
|
+
{
|
1063
|
+
newPtr->next = NULL;
|
1064
|
+
return newPtr;
|
1065
|
+
}
|
1066
|
+
|
1067
|
+
currentPtr = head;
|
1068
|
+
while ((currentPtr != NULL) ? (priority < currentPtr->priority) : false)
|
1069
|
+
{
|
1070
|
+
lastPtr = currentPtr;
|
1071
|
+
currentPtr = currentPtr->next;
|
1072
|
+
}
|
1073
|
+
|
1074
|
+
if (lastPtr == NULL)
|
1075
|
+
{
|
1076
|
+
newPtr->next = head;
|
1077
|
+
head = newPtr;
|
1078
|
+
}
|
1079
|
+
else
|
1080
|
+
{
|
1081
|
+
newPtr->next = currentPtr;
|
1082
|
+
lastPtr->next = newPtr;
|
1083
|
+
}
|
1084
|
+
|
1085
|
+
return head;
|
1086
|
+
}
|
1087
|
+
|
1088
|
+
/***********************************************************/
|
1089
|
+
/* RemoveRuleFiredFunctionFromCallList: Removes a function */
|
1090
|
+
/* from a rule fired function list. */
|
1091
|
+
/***********************************************************/
|
1092
|
+
RuleFiredFunctionItem *RemoveRuleFiredFunctionFromCallList(
|
1093
|
+
Environment *theEnv,
|
1094
|
+
const char *name,
|
1095
|
+
RuleFiredFunctionItem *head,
|
1096
|
+
bool *found)
|
1097
|
+
{
|
1098
|
+
RuleFiredFunctionItem *currentPtr, *lastPtr;
|
1099
|
+
|
1100
|
+
*found = false;
|
1101
|
+
lastPtr = NULL;
|
1102
|
+
currentPtr = head;
|
1103
|
+
|
1104
|
+
while (currentPtr != NULL)
|
1105
|
+
{
|
1106
|
+
if (strcmp(name,currentPtr->name) == 0)
|
1107
|
+
{
|
1108
|
+
*found = true;
|
1109
|
+
if (lastPtr == NULL)
|
1110
|
+
{ head = currentPtr->next; }
|
1111
|
+
else
|
1112
|
+
{ lastPtr->next = currentPtr->next; }
|
1113
|
+
|
1114
|
+
genfree(theEnv,(void *) currentPtr->name,strlen(currentPtr->name) + 1);
|
1115
|
+
rtn_struct(theEnv,voidCallFunctionItem,currentPtr);
|
1116
|
+
return head;
|
1117
|
+
}
|
1118
|
+
|
1119
|
+
lastPtr = currentPtr;
|
1120
|
+
currentPtr = currentPtr->next;
|
1121
|
+
}
|
1122
|
+
|
1123
|
+
return head;
|
1124
|
+
}
|
1125
|
+
|
1126
|
+
/******************************************************/
|
1127
|
+
/* DeallocateRuleFiredCallList: Removes all functions */
|
1128
|
+
/* from a list of rule fired functions. */
|
1129
|
+
/******************************************************/
|
1130
|
+
void DeallocateRuleFiredCallList(
|
1131
|
+
Environment *theEnv,
|
1132
|
+
RuleFiredFunctionItem *theList)
|
1133
|
+
{
|
1134
|
+
RuleFiredFunctionItem *tmpPtr, *nextPtr;
|
1135
|
+
|
1136
|
+
tmpPtr = theList;
|
1137
|
+
while (tmpPtr != NULL)
|
1138
|
+
{
|
1139
|
+
nextPtr = tmpPtr->next;
|
1140
|
+
genfree(theEnv,(void *) tmpPtr->name,strlen(tmpPtr->name) + 1);
|
1141
|
+
rtn_struct(theEnv,ruleFiredFunctionItem,tmpPtr);
|
1142
|
+
tmpPtr = nextPtr;
|
1143
|
+
}
|
1144
|
+
}
|
1145
|
+
|
1146
|
+
/*******************************************************/
|
1147
|
+
/* RunCommand: H/L access routine for the run command. */
|
1148
|
+
/*******************************************************/
|
1149
|
+
void RunCommand(
|
1150
|
+
Environment *theEnv,
|
1151
|
+
UDFContext *context,
|
1152
|
+
UDFValue *returnValue)
|
1153
|
+
{
|
1154
|
+
unsigned int numArgs;
|
1155
|
+
long long runLimit = -1LL;
|
1156
|
+
UDFValue theArg;
|
1157
|
+
|
1158
|
+
numArgs = UDFArgumentCount(context);
|
1159
|
+
if (numArgs == 0)
|
1160
|
+
{ runLimit = -1LL; }
|
1161
|
+
else if (numArgs == 1)
|
1162
|
+
{
|
1163
|
+
if (! UDFFirstArgument(context,INTEGER_BIT,&theArg)) return;
|
1164
|
+
runLimit = theArg.integerValue->contents;
|
1165
|
+
}
|
1166
|
+
|
1167
|
+
Run(theEnv,runLimit);
|
1168
|
+
}
|
1169
|
+
|
1170
|
+
/***********************************************/
|
1171
|
+
/* HaltCommand: Causes rule execution to halt. */
|
1172
|
+
/***********************************************/
|
1173
|
+
void HaltCommand(
|
1174
|
+
Environment *theEnv,
|
1175
|
+
UDFContext *context,
|
1176
|
+
UDFValue *returnValue)
|
1177
|
+
{
|
1178
|
+
Halt(theEnv);
|
1179
|
+
}
|
1180
|
+
|
1181
|
+
/***************************/
|
1182
|
+
/* Halt: C access routine */
|
1183
|
+
/* for the halt command. */
|
1184
|
+
/***************************/
|
1185
|
+
void Halt(
|
1186
|
+
Environment *theEnv)
|
1187
|
+
{
|
1188
|
+
EngineData(theEnv)->HaltRules = true;
|
1189
|
+
}
|
1190
|
+
|
1191
|
+
#if DEBUGGING_FUNCTIONS
|
1192
|
+
|
1193
|
+
/********************************/
|
1194
|
+
/* SetBreak: C access routine */
|
1195
|
+
/* for the set-break command. */
|
1196
|
+
/********************************/
|
1197
|
+
void SetBreak(
|
1198
|
+
Defrule *theRule)
|
1199
|
+
{
|
1200
|
+
Defrule *thePtr;
|
1201
|
+
|
1202
|
+
for (thePtr = theRule;
|
1203
|
+
thePtr != NULL;
|
1204
|
+
thePtr = thePtr->disjunct)
|
1205
|
+
{ thePtr->afterBreakpoint = 1; }
|
1206
|
+
}
|
1207
|
+
|
1208
|
+
/***********************************/
|
1209
|
+
/* RemoveBreak: C access routine */
|
1210
|
+
/* for the remove-break command. */
|
1211
|
+
/***********************************/
|
1212
|
+
bool RemoveBreak(
|
1213
|
+
Defrule *theRule)
|
1214
|
+
{
|
1215
|
+
Defrule *thePtr;
|
1216
|
+
bool rv = false;
|
1217
|
+
|
1218
|
+
for (thePtr = theRule;
|
1219
|
+
thePtr != NULL;
|
1220
|
+
thePtr = thePtr->disjunct)
|
1221
|
+
{
|
1222
|
+
if (thePtr->afterBreakpoint == 1)
|
1223
|
+
{
|
1224
|
+
thePtr->afterBreakpoint = 0;
|
1225
|
+
rv = true;
|
1226
|
+
}
|
1227
|
+
}
|
1228
|
+
|
1229
|
+
return rv;
|
1230
|
+
}
|
1231
|
+
|
1232
|
+
/**************************************************/
|
1233
|
+
/* RemoveAllBreakpoints: Removes all breakpoints. */
|
1234
|
+
/**************************************************/
|
1235
|
+
void RemoveAllBreakpoints(
|
1236
|
+
Environment *theEnv)
|
1237
|
+
{
|
1238
|
+
Defrule *theRule;
|
1239
|
+
Defmodule *theDefmodule = NULL;
|
1240
|
+
|
1241
|
+
while ((theDefmodule = GetNextDefmodule(theEnv,theDefmodule)) != NULL)
|
1242
|
+
{
|
1243
|
+
theRule = NULL;
|
1244
|
+
while ((theRule = GetNextDefrule(theEnv,theRule)) != NULL)
|
1245
|
+
{ RemoveBreak(theRule); }
|
1246
|
+
}
|
1247
|
+
}
|
1248
|
+
|
1249
|
+
/**********************************/
|
1250
|
+
/* ShowBreaks: C access routine */
|
1251
|
+
/* for the show-breaks command. */
|
1252
|
+
/**********************************/
|
1253
|
+
void ShowBreaks(
|
1254
|
+
Environment *theEnv,
|
1255
|
+
const char *logicalName,
|
1256
|
+
Defmodule *theModule)
|
1257
|
+
{
|
1258
|
+
ListItemsDriver(theEnv,logicalName,theModule,
|
1259
|
+
NULL,NULL,
|
1260
|
+
(GetNextItemFunction *) GetNextDefrule,
|
1261
|
+
(const char *(*)(void *)) GetConstructNameString,
|
1262
|
+
NULL,
|
1263
|
+
(bool (*)(void *)) DefruleHasBreakpoint);
|
1264
|
+
}
|
1265
|
+
|
1266
|
+
/***********************************************/
|
1267
|
+
/* DefruleHasBreakpoint: Indicates whether the */
|
1268
|
+
/* specified rule has a breakpoint set. */
|
1269
|
+
/***********************************************/
|
1270
|
+
bool DefruleHasBreakpoint(
|
1271
|
+
Defrule *theRule)
|
1272
|
+
{
|
1273
|
+
return theRule->afterBreakpoint;
|
1274
|
+
}
|
1275
|
+
|
1276
|
+
/*****************************************/
|
1277
|
+
/* SetBreakCommand: H/L access routine */
|
1278
|
+
/* for the set-break command. */
|
1279
|
+
/*****************************************/
|
1280
|
+
void SetBreakCommand(
|
1281
|
+
Environment *theEnv,
|
1282
|
+
UDFContext *context,
|
1283
|
+
UDFValue *returnValue)
|
1284
|
+
{
|
1285
|
+
UDFValue theArg;
|
1286
|
+
const char *argument;
|
1287
|
+
Defrule *defrulePtr;
|
1288
|
+
|
1289
|
+
if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg)) return;
|
1290
|
+
|
1291
|
+
argument = theArg.lexemeValue->contents;
|
1292
|
+
|
1293
|
+
if ((defrulePtr = FindDefrule(theEnv,argument)) == NULL)
|
1294
|
+
{
|
1295
|
+
CantFindItemErrorMessage(theEnv,"defrule",argument,true);
|
1296
|
+
return;
|
1297
|
+
}
|
1298
|
+
|
1299
|
+
SetBreak(defrulePtr);
|
1300
|
+
}
|
1301
|
+
|
1302
|
+
/********************************************/
|
1303
|
+
/* RemoveBreakCommand: H/L access routine */
|
1304
|
+
/* for the remove-break command. */
|
1305
|
+
/********************************************/
|
1306
|
+
void RemoveBreakCommand(
|
1307
|
+
Environment *theEnv,
|
1308
|
+
UDFContext *context,
|
1309
|
+
UDFValue *returnValue)
|
1310
|
+
{
|
1311
|
+
UDFValue theArg;
|
1312
|
+
const char *argument;
|
1313
|
+
Defrule *defrulePtr;
|
1314
|
+
|
1315
|
+
if (UDFArgumentCount(context) == 0)
|
1316
|
+
{
|
1317
|
+
RemoveAllBreakpoints(theEnv);
|
1318
|
+
return;
|
1319
|
+
}
|
1320
|
+
|
1321
|
+
if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg)) return;
|
1322
|
+
|
1323
|
+
argument = theArg.lexemeValue->contents;
|
1324
|
+
|
1325
|
+
if ((defrulePtr = FindDefrule(theEnv,argument)) == NULL)
|
1326
|
+
{
|
1327
|
+
CantFindItemErrorMessage(theEnv,"defrule",argument,true);
|
1328
|
+
return;
|
1329
|
+
}
|
1330
|
+
|
1331
|
+
if (RemoveBreak(defrulePtr) == false)
|
1332
|
+
{
|
1333
|
+
WriteString(theEnv,STDERR,"Rule ");
|
1334
|
+
WriteString(theEnv,STDERR,argument);
|
1335
|
+
WriteString(theEnv,STDERR," does not have a breakpoint set.\n");
|
1336
|
+
}
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
/*******************************************/
|
1340
|
+
/* ShowBreaksCommand: H/L access routine */
|
1341
|
+
/* for the show-breaks command. */
|
1342
|
+
/*******************************************/
|
1343
|
+
void ShowBreaksCommand(
|
1344
|
+
Environment *theEnv,
|
1345
|
+
UDFContext *context,
|
1346
|
+
UDFValue *returnValue)
|
1347
|
+
{
|
1348
|
+
unsigned int numArgs;
|
1349
|
+
bool error;
|
1350
|
+
Defmodule *theModule;
|
1351
|
+
|
1352
|
+
numArgs = UDFArgumentCount(context);
|
1353
|
+
|
1354
|
+
if (numArgs == 1)
|
1355
|
+
{
|
1356
|
+
theModule = GetModuleName(context,1,&error);
|
1357
|
+
if (error) return;
|
1358
|
+
}
|
1359
|
+
else
|
1360
|
+
{ theModule = GetCurrentModule(theEnv); }
|
1361
|
+
|
1362
|
+
ShowBreaks(theEnv,STDOUT,theModule);
|
1363
|
+
}
|
1364
|
+
|
1365
|
+
/***********************************************/
|
1366
|
+
/* ListFocusStackCommand: H/L access routine */
|
1367
|
+
/* for the list-focus-stack command. */
|
1368
|
+
/***********************************************/
|
1369
|
+
void ListFocusStackCommand(
|
1370
|
+
Environment *theEnv,
|
1371
|
+
UDFContext *context,
|
1372
|
+
UDFValue *returnValue)
|
1373
|
+
{
|
1374
|
+
ListFocusStack(theEnv,STDOUT);
|
1375
|
+
}
|
1376
|
+
|
1377
|
+
/***************************************/
|
1378
|
+
/* ListFocusStack: C access routine */
|
1379
|
+
/* for the list-focus-stack command. */
|
1380
|
+
/***************************************/
|
1381
|
+
void ListFocusStack(
|
1382
|
+
Environment *theEnv,
|
1383
|
+
const char *logicalName)
|
1384
|
+
{
|
1385
|
+
FocalModule *theFocus;
|
1386
|
+
|
1387
|
+
for (theFocus = EngineData(theEnv)->CurrentFocus;
|
1388
|
+
theFocus != NULL;
|
1389
|
+
theFocus = theFocus->next)
|
1390
|
+
{
|
1391
|
+
WriteString(theEnv,logicalName,DefmoduleName(theFocus->theModule));
|
1392
|
+
WriteString(theEnv,logicalName,"\n");
|
1393
|
+
}
|
1394
|
+
}
|
1395
|
+
|
1396
|
+
#endif /* DEBUGGING_FUNCTIONS */
|
1397
|
+
|
1398
|
+
/***********************************************/
|
1399
|
+
/* GetFocusStackFunction: H/L access routine */
|
1400
|
+
/* for the get-focus-stack function. */
|
1401
|
+
/***********************************************/
|
1402
|
+
void GetFocusStackFunction(
|
1403
|
+
Environment *theEnv,
|
1404
|
+
UDFContext *context,
|
1405
|
+
UDFValue *returnValue)
|
1406
|
+
{
|
1407
|
+
CLIPSValue result;
|
1408
|
+
|
1409
|
+
GetFocusStack(theEnv,&result);
|
1410
|
+
CLIPSToUDFValue(&result,returnValue);
|
1411
|
+
}
|
1412
|
+
|
1413
|
+
/***************************************/
|
1414
|
+
/* GetFocusStack: C access routine */
|
1415
|
+
/* for the get-focus-stack function. */
|
1416
|
+
/***************************************/
|
1417
|
+
void GetFocusStack(
|
1418
|
+
Environment *theEnv,
|
1419
|
+
CLIPSValue *returnValue)
|
1420
|
+
{
|
1421
|
+
FocalModule *theFocus;
|
1422
|
+
Multifield *theList;
|
1423
|
+
unsigned long count = 0;
|
1424
|
+
|
1425
|
+
/*===========================================*/
|
1426
|
+
/* If there is no current focus, then return */
|
1427
|
+
/* a multifield value of length zero. */
|
1428
|
+
/*===========================================*/
|
1429
|
+
|
1430
|
+
if (EngineData(theEnv)->CurrentFocus == NULL)
|
1431
|
+
{
|
1432
|
+
returnValue->value = CreateMultifield(theEnv,0L);
|
1433
|
+
return;
|
1434
|
+
}
|
1435
|
+
|
1436
|
+
/*=====================================================*/
|
1437
|
+
/* Determine the number of modules on the focus stack. */
|
1438
|
+
/*=====================================================*/
|
1439
|
+
|
1440
|
+
for (theFocus = EngineData(theEnv)->CurrentFocus; theFocus != NULL; theFocus = theFocus->next)
|
1441
|
+
{ count++; }
|
1442
|
+
|
1443
|
+
/*=============================================*/
|
1444
|
+
/* Create a multifield of the appropriate size */
|
1445
|
+
/* in which to store the module names. */
|
1446
|
+
/*=============================================*/
|
1447
|
+
|
1448
|
+
theList = CreateMultifield(theEnv,count);
|
1449
|
+
returnValue->multifieldValue = theList;
|
1450
|
+
|
1451
|
+
/*=================================================*/
|
1452
|
+
/* Store the module names in the multifield value. */
|
1453
|
+
/*=================================================*/
|
1454
|
+
|
1455
|
+
for (theFocus = EngineData(theEnv)->CurrentFocus, count = 0;
|
1456
|
+
theFocus != NULL;
|
1457
|
+
theFocus = theFocus->next, count++)
|
1458
|
+
{
|
1459
|
+
theList->contents[count].value = theFocus->theModule->header.name;
|
1460
|
+
}
|
1461
|
+
}
|
1462
|
+
|
1463
|
+
/******************************************/
|
1464
|
+
/* PopFocusFunction: H/L access routine */
|
1465
|
+
/* for the pop-focus function. */
|
1466
|
+
/******************************************/
|
1467
|
+
void PopFocusFunction(
|
1468
|
+
Environment *theEnv,
|
1469
|
+
UDFContext *context,
|
1470
|
+
UDFValue *returnValue)
|
1471
|
+
{
|
1472
|
+
Defmodule *theModule;
|
1473
|
+
|
1474
|
+
theModule = PopFocus(theEnv);
|
1475
|
+
if (theModule == NULL)
|
1476
|
+
{
|
1477
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
1478
|
+
return;
|
1479
|
+
}
|
1480
|
+
|
1481
|
+
returnValue->value = theModule->header.name;
|
1482
|
+
}
|
1483
|
+
|
1484
|
+
/**************************************/
|
1485
|
+
/* FocusCommand: H/L access routine */
|
1486
|
+
/* for the focus function. */
|
1487
|
+
/**************************************/
|
1488
|
+
void FocusCommand(
|
1489
|
+
Environment *theEnv,
|
1490
|
+
UDFContext *context,
|
1491
|
+
UDFValue *returnValue)
|
1492
|
+
{
|
1493
|
+
UDFValue theArg;
|
1494
|
+
const char *argument;
|
1495
|
+
Defmodule *theModule;
|
1496
|
+
unsigned int argCount, i;
|
1497
|
+
|
1498
|
+
/*===========================================*/
|
1499
|
+
/* Focus on the specified defrule module(s). */
|
1500
|
+
/*===========================================*/
|
1501
|
+
|
1502
|
+
argCount = UDFArgumentCount(context);
|
1503
|
+
|
1504
|
+
for (i = argCount; i > 0; i--)
|
1505
|
+
{
|
1506
|
+
if (! UDFNthArgument(context,i,SYMBOL_BIT,&theArg))
|
1507
|
+
{ return; }
|
1508
|
+
|
1509
|
+
argument = theArg.lexemeValue->contents;
|
1510
|
+
theModule = FindDefmodule(theEnv,argument);
|
1511
|
+
|
1512
|
+
if (theModule == NULL)
|
1513
|
+
{
|
1514
|
+
CantFindItemErrorMessage(theEnv,"defmodule",argument,true);
|
1515
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
1516
|
+
return;
|
1517
|
+
}
|
1518
|
+
|
1519
|
+
Focus(theModule);
|
1520
|
+
}
|
1521
|
+
|
1522
|
+
/*===================================================*/
|
1523
|
+
/* Return true to indicate success of focus command. */
|
1524
|
+
/*===================================================*/
|
1525
|
+
|
1526
|
+
returnValue->lexemeValue = TrueSymbol(theEnv);
|
1527
|
+
}
|
1528
|
+
|
1529
|
+
/********************************************************************/
|
1530
|
+
/* GetFocusChanged: Returns the value of the variable FocusChanged. */
|
1531
|
+
/********************************************************************/
|
1532
|
+
bool GetFocusChanged(
|
1533
|
+
Environment *theEnv)
|
1534
|
+
{
|
1535
|
+
return EngineData(theEnv)->FocusChanged;
|
1536
|
+
}
|
1537
|
+
|
1538
|
+
/*****************************************************************/
|
1539
|
+
/* SetFocusChanged: Sets the value of the variable FocusChanged. */
|
1540
|
+
/*****************************************************************/
|
1541
|
+
void SetFocusChanged(
|
1542
|
+
Environment *theEnv,
|
1543
|
+
bool value)
|
1544
|
+
{
|
1545
|
+
EngineData(theEnv)->FocusChanged = value;
|
1546
|
+
}
|
1547
|
+
|
1548
|
+
/******************************************/
|
1549
|
+
/* SetHaltRules: Sets the HaltRules flag. */
|
1550
|
+
/******************************************/
|
1551
|
+
void SetHaltRules(
|
1552
|
+
Environment *theEnv,
|
1553
|
+
bool value)
|
1554
|
+
{
|
1555
|
+
EngineData(theEnv)->HaltRules = value;
|
1556
|
+
}
|
1557
|
+
|
1558
|
+
/*************************************************/
|
1559
|
+
/* GetHaltRules: Returns the HaltExecution flag. */
|
1560
|
+
/*************************************************/
|
1561
|
+
bool GetHaltRules(
|
1562
|
+
Environment *theEnv)
|
1563
|
+
{
|
1564
|
+
return(EngineData(theEnv)->HaltRules);
|
1565
|
+
}
|
1566
|
+
|
1567
|
+
#endif /* DEFRULE_CONSTRUCT */
|
1568
|
+
|