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,1583 @@
|
|
1
|
+
/*******************************************************/
|
2
|
+
/* "C" Language Integrated Production System */
|
3
|
+
/* */
|
4
|
+
/* CLIPS Version 6.41 12/04/22 */
|
5
|
+
/* */
|
6
|
+
/* RULE COMMANDS MODULE */
|
7
|
+
/*******************************************************/
|
8
|
+
|
9
|
+
/*************************************************************/
|
10
|
+
/* Purpose: Provides the matches command. Also provides the */
|
11
|
+
/* the developer commands show-joins and rule-complexity. */
|
12
|
+
/* Also provides the initialization routine which */
|
13
|
+
/* registers rule commands found in other modules. */
|
14
|
+
/* */
|
15
|
+
/* Principal Programmer(s): */
|
16
|
+
/* Gary D. Riley */
|
17
|
+
/* */
|
18
|
+
/* Contributing Programmer(s): */
|
19
|
+
/* */
|
20
|
+
/* Revision History: */
|
21
|
+
/* */
|
22
|
+
/* 6.24: Removed CONFLICT_RESOLUTION_STRATEGIES */
|
23
|
+
/* INCREMENTAL_RESET, and LOGICAL_DEPENDENCIES */
|
24
|
+
/* compilation flags. */
|
25
|
+
/* */
|
26
|
+
/* Renamed BOOLEAN macro type to intBool. */
|
27
|
+
/* */
|
28
|
+
/* 6.30: Removed conditional code for unsupported */
|
29
|
+
/* compilers/operating systems (IBM_MCW and */
|
30
|
+
/* MAC_MCW). */
|
31
|
+
/* */
|
32
|
+
/* Added support for hashed memories. */
|
33
|
+
/* */
|
34
|
+
/* Improvements to matches command. */
|
35
|
+
/* */
|
36
|
+
/* Add join-activity and join-activity-reset */
|
37
|
+
/* commands. */
|
38
|
+
/* */
|
39
|
+
/* Added get-beta-memory-resizing and */
|
40
|
+
/* set-beta-memory-resizing functions. */
|
41
|
+
/* */
|
42
|
+
/* Added timetag function. */
|
43
|
+
/* */
|
44
|
+
/* Added const qualifiers to remove C++ */
|
45
|
+
/* deprecation warnings. */
|
46
|
+
/* */
|
47
|
+
/* Converted API macros to function calls. */
|
48
|
+
/* */
|
49
|
+
/* 6.31: Fixes for show-joins command. */
|
50
|
+
/* */
|
51
|
+
/* Fixes for matches command where the */
|
52
|
+
/* activations listed were not correct if the */
|
53
|
+
/* current module was different than the module */
|
54
|
+
/* for the specified rule. */
|
55
|
+
/* */
|
56
|
+
/* 6.32: Fixed embedded reset of error flags. */
|
57
|
+
/* */
|
58
|
+
/* 6.40: Added Env prefix to GetHaltExecution and */
|
59
|
+
/* SetHaltExecution functions. */
|
60
|
+
/* */
|
61
|
+
/* Pragma once and other inclusion changes. */
|
62
|
+
/* */
|
63
|
+
/* Added support for booleans with <stdbool.h>. */
|
64
|
+
/* */
|
65
|
+
/* Removed use of void pointers for specific */
|
66
|
+
/* data structures. */
|
67
|
+
/* */
|
68
|
+
/* ALLOW_ENVIRONMENT_GLOBALS no longer supported. */
|
69
|
+
/* */
|
70
|
+
/* Incremental reset is always enabled. */
|
71
|
+
/* */
|
72
|
+
/* UDF redesign. */
|
73
|
+
/* */
|
74
|
+
/* 6.41: Used gensnprintf in place of gensprintf and. */
|
75
|
+
/* sprintf. */
|
76
|
+
/* */
|
77
|
+
/*************************************************************/
|
78
|
+
|
79
|
+
#include <stdio.h>
|
80
|
+
#include <string.h>
|
81
|
+
|
82
|
+
#include "setup.h"
|
83
|
+
|
84
|
+
#if DEFRULE_CONSTRUCT
|
85
|
+
|
86
|
+
#include "argacces.h"
|
87
|
+
#include "constant.h"
|
88
|
+
#include "constrct.h"
|
89
|
+
#include "crstrtgy.h"
|
90
|
+
#include "engine.h"
|
91
|
+
#include "envrnmnt.h"
|
92
|
+
#include "evaluatn.h"
|
93
|
+
#include "extnfunc.h"
|
94
|
+
#include "incrrset.h"
|
95
|
+
#include "lgcldpnd.h"
|
96
|
+
#include "memalloc.h"
|
97
|
+
#include "multifld.h"
|
98
|
+
#include "pattern.h"
|
99
|
+
#include "prntutil.h"
|
100
|
+
#include "reteutil.h"
|
101
|
+
#include "router.h"
|
102
|
+
#include "ruledlt.h"
|
103
|
+
#include "sysdep.h"
|
104
|
+
#include "utility.h"
|
105
|
+
#include "watch.h"
|
106
|
+
|
107
|
+
#if BLOAD || BLOAD_AND_BSAVE || BLOAD_ONLY
|
108
|
+
#include "rulebin.h"
|
109
|
+
#endif
|
110
|
+
|
111
|
+
#include "rulecom.h"
|
112
|
+
|
113
|
+
/***************************************/
|
114
|
+
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
|
115
|
+
/***************************************/
|
116
|
+
|
117
|
+
#if DEVELOPER
|
118
|
+
static void ShowJoins(Environment *,Defrule *);
|
119
|
+
#endif
|
120
|
+
#if DEBUGGING_FUNCTIONS
|
121
|
+
static long long ListAlphaMatches(Environment *,struct joinInformation *,Verbosity);
|
122
|
+
static long long ListBetaMatches(Environment *,struct joinInformation *,long,unsigned short,Verbosity);
|
123
|
+
static void ListBetaJoinActivity(Environment *,struct joinInformation *,long,long,int,UDFValue *);
|
124
|
+
static unsigned short AlphaJoinCountDriver(Environment *,struct joinNode *);
|
125
|
+
static unsigned short BetaJoinCountDriver(Environment *,struct joinNode *);
|
126
|
+
static void AlphaJoinsDriver(Environment *,struct joinNode *,unsigned short,struct joinInformation *);
|
127
|
+
static void BetaJoinsDriver(Environment *,struct joinNode *,unsigned short,struct joinInformation *,struct betaMemory *,struct joinNode *);
|
128
|
+
static int CountPatterns(Environment *,struct joinNode *,bool);
|
129
|
+
static const char *BetaHeaderString(Environment *,struct joinInformation *,long,long);
|
130
|
+
static const char *ActivityHeaderString(Environment *,struct joinInformation *,long,long);
|
131
|
+
static void JoinActivityReset(Environment *,ConstructHeader *,void *);
|
132
|
+
#endif
|
133
|
+
|
134
|
+
/****************************************************************/
|
135
|
+
/* DefruleCommands: Initializes defrule commands and functions. */
|
136
|
+
/****************************************************************/
|
137
|
+
void DefruleCommands(
|
138
|
+
Environment *theEnv)
|
139
|
+
{
|
140
|
+
#if ! RUN_TIME
|
141
|
+
AddUDF(theEnv,"run","v",0,1,"l",RunCommand,"RunCommand",NULL);
|
142
|
+
AddUDF(theEnv,"halt","v",0,0,NULL,HaltCommand,"HaltCommand",NULL);
|
143
|
+
AddUDF(theEnv,"focus","b",1,UNBOUNDED,"y",FocusCommand,"FocusCommand",NULL);
|
144
|
+
AddUDF(theEnv,"clear-focus-stack","v",0,0,NULL,ClearFocusStackCommand,"ClearFocusStackCommand",NULL);
|
145
|
+
AddUDF(theEnv,"get-focus-stack","m",0,0,NULL,GetFocusStackFunction,"GetFocusStackFunction",NULL);
|
146
|
+
AddUDF(theEnv,"pop-focus","y",0,0,NULL,PopFocusFunction,"PopFocusFunction",NULL);
|
147
|
+
AddUDF(theEnv,"get-focus","y",0,0,NULL,GetFocusFunction,"GetFocusFunction",NULL);
|
148
|
+
#if DEBUGGING_FUNCTIONS
|
149
|
+
AddUDF(theEnv,"set-break","v",1,1,"y",SetBreakCommand,"SetBreakCommand",NULL);
|
150
|
+
AddUDF(theEnv,"remove-break","v",0,1,"y",RemoveBreakCommand,"RemoveBreakCommand",NULL);
|
151
|
+
AddUDF(theEnv,"show-breaks","v",0,1,"y",ShowBreaksCommand,"ShowBreaksCommand",NULL);
|
152
|
+
AddUDF(theEnv,"matches","bm",1,2,"y",MatchesCommand,"MatchesCommand",NULL);
|
153
|
+
AddUDF(theEnv,"join-activity","bm",1,2,"y",JoinActivityCommand,"JoinActivityCommand",NULL);
|
154
|
+
AddUDF(theEnv,"join-activity-reset","v",0,0,NULL,JoinActivityResetCommand,"JoinActivityResetCommand",NULL);
|
155
|
+
AddUDF(theEnv,"list-focus-stack","v",0,0,NULL,ListFocusStackCommand,"ListFocusStackCommand",NULL);
|
156
|
+
AddUDF(theEnv,"dependencies","v",1,1,"infly",DependenciesCommand,"DependenciesCommand",NULL);
|
157
|
+
AddUDF(theEnv,"dependents","v",1,1,"infly",DependentsCommand,"DependentsCommand",NULL);
|
158
|
+
|
159
|
+
AddUDF(theEnv,"timetag","l",1,1,"infly" ,TimetagFunction,"TimetagFunction",NULL);
|
160
|
+
#endif /* DEBUGGING_FUNCTIONS */
|
161
|
+
|
162
|
+
AddUDF(theEnv,"get-beta-memory-resizing","b",0,0,NULL,GetBetaMemoryResizingCommand,"GetBetaMemoryResizingCommand",NULL);
|
163
|
+
AddUDF(theEnv,"set-beta-memory-resizing","b",1,1,NULL,SetBetaMemoryResizingCommand,"SetBetaMemoryResizingCommand",NULL);
|
164
|
+
|
165
|
+
AddUDF(theEnv,"get-strategy","y",0,0,NULL,GetStrategyCommand,"GetStrategyCommand",NULL);
|
166
|
+
AddUDF(theEnv,"set-strategy","y",1,1,"y",SetStrategyCommand,"SetStrategyCommand",NULL);
|
167
|
+
|
168
|
+
#if DEVELOPER && (! BLOAD_ONLY)
|
169
|
+
AddUDF(theEnv,"rule-complexity","l",1,1,"y",RuleComplexityCommand,"RuleComplexityCommand",NULL);
|
170
|
+
AddUDF(theEnv,"show-joins","v",1,1,"y",ShowJoinsCommand,"ShowJoinsCommand",NULL);
|
171
|
+
AddUDF(theEnv,"show-aht","v",0,0,NULL,ShowAlphaHashTable,"ShowAlphaHashTable",NULL);
|
172
|
+
#if DEBUGGING_FUNCTIONS
|
173
|
+
AddWatchItem(theEnv,"rule-analysis",0,&DefruleData(theEnv)->WatchRuleAnalysis,0,NULL,NULL);
|
174
|
+
#endif
|
175
|
+
#endif /* DEVELOPER && (! BLOAD_ONLY) */
|
176
|
+
|
177
|
+
#else
|
178
|
+
#if MAC_XCD
|
179
|
+
#pragma unused(theEnv)
|
180
|
+
#endif
|
181
|
+
#endif /* ! RUN_TIME */
|
182
|
+
}
|
183
|
+
|
184
|
+
/***********************************************/
|
185
|
+
/* GetBetaMemoryResizing: C access routine */
|
186
|
+
/* for the get-beta-memory-resizing command. */
|
187
|
+
/***********************************************/
|
188
|
+
bool GetBetaMemoryResizing(
|
189
|
+
Environment *theEnv)
|
190
|
+
{
|
191
|
+
return DefruleData(theEnv)->BetaMemoryResizingFlag;
|
192
|
+
}
|
193
|
+
|
194
|
+
/***********************************************/
|
195
|
+
/* SetBetaMemoryResizing: C access routine */
|
196
|
+
/* for the set-beta-memory-resizing command. */
|
197
|
+
/***********************************************/
|
198
|
+
bool SetBetaMemoryResizing(
|
199
|
+
Environment *theEnv,
|
200
|
+
bool value)
|
201
|
+
{
|
202
|
+
bool ov;
|
203
|
+
|
204
|
+
ov = DefruleData(theEnv)->BetaMemoryResizingFlag;
|
205
|
+
|
206
|
+
DefruleData(theEnv)->BetaMemoryResizingFlag = value;
|
207
|
+
|
208
|
+
return(ov);
|
209
|
+
}
|
210
|
+
|
211
|
+
/****************************************************/
|
212
|
+
/* SetBetaMemoryResizingCommand: H/L access routine */
|
213
|
+
/* for the set-beta-memory-resizing command. */
|
214
|
+
/****************************************************/
|
215
|
+
void SetBetaMemoryResizingCommand(
|
216
|
+
Environment *theEnv,
|
217
|
+
UDFContext *context,
|
218
|
+
UDFValue *returnValue)
|
219
|
+
{
|
220
|
+
UDFValue theArg;
|
221
|
+
|
222
|
+
returnValue->lexemeValue = CreateBoolean(theEnv,GetBetaMemoryResizing(theEnv));
|
223
|
+
|
224
|
+
/*=================================================*/
|
225
|
+
/* The symbol FALSE disables beta memory resizing. */
|
226
|
+
/* Any other value enables beta memory resizing. */
|
227
|
+
/*=================================================*/
|
228
|
+
|
229
|
+
if (! UDFFirstArgument(context,ANY_TYPE_BITS,&theArg))
|
230
|
+
{ return; }
|
231
|
+
|
232
|
+
if (theArg.value == FalseSymbol(theEnv))
|
233
|
+
{ SetBetaMemoryResizing(theEnv,false); }
|
234
|
+
else
|
235
|
+
{ SetBetaMemoryResizing(theEnv,true); }
|
236
|
+
}
|
237
|
+
|
238
|
+
/****************************************************/
|
239
|
+
/* GetBetaMemoryResizingCommand: H/L access routine */
|
240
|
+
/* for the get-beta-memory-resizing command. */
|
241
|
+
/****************************************************/
|
242
|
+
void GetBetaMemoryResizingCommand(
|
243
|
+
Environment *theEnv,
|
244
|
+
UDFContext *context,
|
245
|
+
UDFValue *returnValue)
|
246
|
+
{
|
247
|
+
returnValue->lexemeValue = CreateBoolean(theEnv,GetBetaMemoryResizing(theEnv));
|
248
|
+
}
|
249
|
+
|
250
|
+
/******************************************/
|
251
|
+
/* GetFocusFunction: H/L access routine */
|
252
|
+
/* for the get-focus function. */
|
253
|
+
/******************************************/
|
254
|
+
void GetFocusFunction(
|
255
|
+
Environment *theEnv,
|
256
|
+
UDFContext *context,
|
257
|
+
UDFValue *returnValue)
|
258
|
+
{
|
259
|
+
Defmodule *rv;
|
260
|
+
|
261
|
+
rv = GetFocus(theEnv);
|
262
|
+
|
263
|
+
if (rv == NULL)
|
264
|
+
{
|
265
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
266
|
+
return;
|
267
|
+
}
|
268
|
+
|
269
|
+
returnValue->value = rv->header.name;
|
270
|
+
}
|
271
|
+
|
272
|
+
/*********************************/
|
273
|
+
/* GetFocus: C access routine */
|
274
|
+
/* for the get-focus function. */
|
275
|
+
/*********************************/
|
276
|
+
Defmodule *GetFocus(
|
277
|
+
Environment *theEnv)
|
278
|
+
{
|
279
|
+
if (EngineData(theEnv)->CurrentFocus == NULL) return NULL;
|
280
|
+
|
281
|
+
return EngineData(theEnv)->CurrentFocus->theModule;
|
282
|
+
}
|
283
|
+
|
284
|
+
#if DEBUGGING_FUNCTIONS
|
285
|
+
|
286
|
+
/****************************************/
|
287
|
+
/* MatchesCommand: H/L access routine */
|
288
|
+
/* for the matches command. */
|
289
|
+
/****************************************/
|
290
|
+
void MatchesCommand(
|
291
|
+
Environment *theEnv,
|
292
|
+
UDFContext *context,
|
293
|
+
UDFValue *returnValue)
|
294
|
+
{
|
295
|
+
const char *ruleName, *argument;
|
296
|
+
Defrule *rulePtr;
|
297
|
+
UDFValue theArg;
|
298
|
+
Verbosity output;
|
299
|
+
CLIPSValue result;
|
300
|
+
|
301
|
+
if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
|
302
|
+
{ return; }
|
303
|
+
|
304
|
+
ruleName = theArg.lexemeValue->contents;
|
305
|
+
|
306
|
+
rulePtr = FindDefrule(theEnv,ruleName);
|
307
|
+
if (rulePtr == NULL)
|
308
|
+
{
|
309
|
+
CantFindItemErrorMessage(theEnv,"defrule",ruleName,true);
|
310
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
311
|
+
return;
|
312
|
+
}
|
313
|
+
|
314
|
+
if (UDFHasNextArgument(context))
|
315
|
+
{
|
316
|
+
if (! UDFNextArgument(context,SYMBOL_BIT,&theArg))
|
317
|
+
{ return; }
|
318
|
+
|
319
|
+
argument = theArg.lexemeValue->contents;
|
320
|
+
if (strcmp(argument,"verbose") == 0)
|
321
|
+
{ output = VERBOSE; }
|
322
|
+
else if (strcmp(argument,"succinct") == 0)
|
323
|
+
{ output = SUCCINCT; }
|
324
|
+
else if (strcmp(argument,"terse") == 0)
|
325
|
+
{ output = TERSE; }
|
326
|
+
else
|
327
|
+
{
|
328
|
+
UDFInvalidArgumentMessage(context,"symbol with value verbose, succinct, or terse");
|
329
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
330
|
+
return;
|
331
|
+
}
|
332
|
+
}
|
333
|
+
else
|
334
|
+
{ output = VERBOSE; }
|
335
|
+
|
336
|
+
Matches(rulePtr,output,&result);
|
337
|
+
CLIPSToUDFValue(&result,returnValue);
|
338
|
+
}
|
339
|
+
|
340
|
+
/******************************/
|
341
|
+
/* Matches: C access routine */
|
342
|
+
/* for the matches command. */
|
343
|
+
/******************************/
|
344
|
+
void Matches(
|
345
|
+
Defrule *theDefrule,
|
346
|
+
Verbosity output,
|
347
|
+
CLIPSValue *returnValue)
|
348
|
+
{
|
349
|
+
Defrule *rulePtr;
|
350
|
+
Defrule *topDisjunct = theDefrule;
|
351
|
+
long joinIndex;
|
352
|
+
unsigned short arraySize;
|
353
|
+
struct joinInformation *theInfo;
|
354
|
+
long long alphaMatchCount = 0;
|
355
|
+
long long betaMatchCount = 0;
|
356
|
+
long long activations = 0;
|
357
|
+
Activation *agendaPtr;
|
358
|
+
Environment *theEnv = theDefrule->header.env;
|
359
|
+
|
360
|
+
/*=====================================*/
|
361
|
+
/* If embedded, clear the error flags. */
|
362
|
+
/*=====================================*/
|
363
|
+
|
364
|
+
if (EvaluationData(theEnv)->CurrentExpression == NULL)
|
365
|
+
{ ResetErrorFlags(theEnv); }
|
366
|
+
|
367
|
+
/*==========================*/
|
368
|
+
/* Set up the return value. */
|
369
|
+
/*==========================*/
|
370
|
+
|
371
|
+
returnValue->value = CreateMultifield(theEnv,3L);
|
372
|
+
|
373
|
+
returnValue->multifieldValue->contents[0].integerValue = SymbolData(theEnv)->Zero;
|
374
|
+
returnValue->multifieldValue->contents[1].integerValue = SymbolData(theEnv)->Zero;
|
375
|
+
returnValue->multifieldValue->contents[2].integerValue = SymbolData(theEnv)->Zero;
|
376
|
+
|
377
|
+
/*=================================================*/
|
378
|
+
/* Loop through each of the disjuncts for the rule */
|
379
|
+
/*=================================================*/
|
380
|
+
|
381
|
+
for (rulePtr = topDisjunct; rulePtr != NULL; rulePtr = rulePtr->disjunct)
|
382
|
+
{
|
383
|
+
/*===============================================*/
|
384
|
+
/* Create the array containing the list of alpha */
|
385
|
+
/* join nodes (those connected to a pattern CE). */
|
386
|
+
/*===============================================*/
|
387
|
+
|
388
|
+
arraySize = AlphaJoinCount(theEnv,rulePtr);
|
389
|
+
|
390
|
+
theInfo = CreateJoinArray(theEnv,arraySize);
|
391
|
+
|
392
|
+
AlphaJoins(theEnv,rulePtr,arraySize,theInfo);
|
393
|
+
|
394
|
+
/*=========================*/
|
395
|
+
/* List the alpha matches. */
|
396
|
+
/*=========================*/
|
397
|
+
|
398
|
+
for (joinIndex = 0; joinIndex < arraySize; joinIndex++)
|
399
|
+
{
|
400
|
+
alphaMatchCount += ListAlphaMatches(theEnv,&theInfo[joinIndex],output);
|
401
|
+
returnValue->multifieldValue->contents[0].integerValue = CreateInteger(theEnv,alphaMatchCount);
|
402
|
+
}
|
403
|
+
|
404
|
+
/*================================*/
|
405
|
+
/* Free the array of alpha joins. */
|
406
|
+
/*================================*/
|
407
|
+
|
408
|
+
FreeJoinArray(theEnv,theInfo,arraySize);
|
409
|
+
|
410
|
+
/*==============================================*/
|
411
|
+
/* Create the array containing the list of beta */
|
412
|
+
/* join nodes (joins from the right plus joins */
|
413
|
+
/* connected to a pattern CE). */
|
414
|
+
/*==============================================*/
|
415
|
+
|
416
|
+
arraySize = BetaJoinCount(theEnv,rulePtr);
|
417
|
+
|
418
|
+
theInfo = CreateJoinArray(theEnv,arraySize);
|
419
|
+
|
420
|
+
BetaJoins(theEnv,rulePtr,arraySize,theInfo);
|
421
|
+
|
422
|
+
/*======================================*/
|
423
|
+
/* List the beta matches (for all joins */
|
424
|
+
/* except the first pattern CE). */
|
425
|
+
/*======================================*/
|
426
|
+
|
427
|
+
for (joinIndex = 1; joinIndex < arraySize; joinIndex++)
|
428
|
+
{
|
429
|
+
betaMatchCount += ListBetaMatches(theEnv,theInfo,joinIndex,arraySize,output);
|
430
|
+
returnValue->multifieldValue->contents[1].integerValue = CreateInteger(theEnv,betaMatchCount);
|
431
|
+
}
|
432
|
+
|
433
|
+
/*================================*/
|
434
|
+
/* Free the array of alpha joins. */
|
435
|
+
/*================================*/
|
436
|
+
|
437
|
+
FreeJoinArray(theEnv,theInfo,arraySize);
|
438
|
+
}
|
439
|
+
|
440
|
+
/*===================*/
|
441
|
+
/* List activations. */
|
442
|
+
/*===================*/
|
443
|
+
|
444
|
+
if (output == VERBOSE)
|
445
|
+
{ WriteString(theEnv,STDOUT,"Activations\n"); }
|
446
|
+
|
447
|
+
for (agendaPtr = ((struct defruleModule *) topDisjunct->header.whichModule)->agenda;
|
448
|
+
agendaPtr != NULL;
|
449
|
+
agendaPtr = (struct activation *) GetNextActivation(theEnv,agendaPtr))
|
450
|
+
{
|
451
|
+
if (GetHaltExecution(theEnv) == true) return;
|
452
|
+
|
453
|
+
if (((struct activation *) agendaPtr)->theRule->header.name == topDisjunct->header.name)
|
454
|
+
{
|
455
|
+
activations++;
|
456
|
+
|
457
|
+
if (output == VERBOSE)
|
458
|
+
{
|
459
|
+
PrintPartialMatch(theEnv,STDOUT,GetActivationBasis(theEnv,agendaPtr));
|
460
|
+
WriteString(theEnv,STDOUT,"\n");
|
461
|
+
}
|
462
|
+
}
|
463
|
+
}
|
464
|
+
|
465
|
+
if (output == SUCCINCT)
|
466
|
+
{
|
467
|
+
WriteString(theEnv,STDOUT,"Activations: ");
|
468
|
+
WriteInteger(theEnv,STDOUT,activations);
|
469
|
+
WriteString(theEnv,STDOUT,"\n");
|
470
|
+
}
|
471
|
+
|
472
|
+
if ((activations == 0) && (output == VERBOSE)) WriteString(theEnv,STDOUT," None\n");
|
473
|
+
|
474
|
+
returnValue->multifieldValue->contents[2].integerValue = CreateInteger(theEnv,activations);
|
475
|
+
}
|
476
|
+
|
477
|
+
/****************************************************/
|
478
|
+
/* AlphaJoinCountDriver: Driver routine to iterate */
|
479
|
+
/* over a rule's joins to determine the number of */
|
480
|
+
/* alpha joins. */
|
481
|
+
/****************************************************/
|
482
|
+
static unsigned short AlphaJoinCountDriver(
|
483
|
+
Environment *theEnv,
|
484
|
+
struct joinNode *theJoin)
|
485
|
+
{
|
486
|
+
unsigned short alphaCount = 0;
|
487
|
+
|
488
|
+
if (theJoin == NULL)
|
489
|
+
{ return alphaCount; }
|
490
|
+
|
491
|
+
if (theJoin->joinFromTheRight)
|
492
|
+
{ return AlphaJoinCountDriver(theEnv,(struct joinNode *) theJoin->rightSideEntryStructure); }
|
493
|
+
else if (theJoin->lastLevel != NULL)
|
494
|
+
{ alphaCount += AlphaJoinCountDriver(theEnv,theJoin->lastLevel); }
|
495
|
+
|
496
|
+
alphaCount++;
|
497
|
+
|
498
|
+
return alphaCount;
|
499
|
+
}
|
500
|
+
|
501
|
+
/***********************************************/
|
502
|
+
/* AlphaJoinCount: Returns the number of alpha */
|
503
|
+
/* joins associated with the specified rule. */
|
504
|
+
/***********************************************/
|
505
|
+
unsigned short AlphaJoinCount(
|
506
|
+
Environment *theEnv,
|
507
|
+
Defrule *theDefrule)
|
508
|
+
{
|
509
|
+
return AlphaJoinCountDriver(theEnv,theDefrule->lastJoin->lastLevel);
|
510
|
+
}
|
511
|
+
|
512
|
+
/***************************************/
|
513
|
+
/* AlphaJoinsDriver: Driver routine to */
|
514
|
+
/* retrieve a rule's alpha joins. */
|
515
|
+
/***************************************/
|
516
|
+
static void AlphaJoinsDriver(
|
517
|
+
Environment *theEnv,
|
518
|
+
struct joinNode *theJoin,
|
519
|
+
unsigned short alphaIndex,
|
520
|
+
struct joinInformation *theInfo)
|
521
|
+
{
|
522
|
+
if (theJoin == NULL)
|
523
|
+
{ return; }
|
524
|
+
|
525
|
+
if (theJoin->joinFromTheRight)
|
526
|
+
{
|
527
|
+
AlphaJoinsDriver(theEnv,(struct joinNode *) theJoin->rightSideEntryStructure,alphaIndex,theInfo);
|
528
|
+
return;
|
529
|
+
}
|
530
|
+
else if (theJoin->lastLevel != NULL)
|
531
|
+
{ AlphaJoinsDriver(theEnv,theJoin->lastLevel,alphaIndex-1,theInfo); }
|
532
|
+
|
533
|
+
theInfo[alphaIndex-1].whichCE = alphaIndex;
|
534
|
+
theInfo[alphaIndex-1].theJoin = theJoin;
|
535
|
+
|
536
|
+
return;
|
537
|
+
}
|
538
|
+
|
539
|
+
/*****************************************/
|
540
|
+
/* AlphaJoins: Retrieves the alpha joins */
|
541
|
+
/* associated with the specified rule. */
|
542
|
+
/*****************************************/
|
543
|
+
void AlphaJoins(
|
544
|
+
Environment *theEnv,
|
545
|
+
Defrule *theDefrule,
|
546
|
+
unsigned short alphaCount,
|
547
|
+
struct joinInformation *theInfo)
|
548
|
+
{
|
549
|
+
AlphaJoinsDriver(theEnv,theDefrule->lastJoin->lastLevel,alphaCount,theInfo);
|
550
|
+
}
|
551
|
+
|
552
|
+
/****************************************************/
|
553
|
+
/* BetaJoinCountDriver: Driver routine to iterate */
|
554
|
+
/* over a rule's joins to determine the number of */
|
555
|
+
/* beta joins. */
|
556
|
+
/****************************************************/
|
557
|
+
static unsigned short BetaJoinCountDriver(
|
558
|
+
Environment *theEnv,
|
559
|
+
struct joinNode *theJoin)
|
560
|
+
{
|
561
|
+
unsigned short betaCount = 0;
|
562
|
+
|
563
|
+
if (theJoin == NULL)
|
564
|
+
{ return betaCount; }
|
565
|
+
|
566
|
+
betaCount++;
|
567
|
+
|
568
|
+
if (theJoin->joinFromTheRight)
|
569
|
+
{ betaCount += BetaJoinCountDriver(theEnv,(struct joinNode *) theJoin->rightSideEntryStructure); }
|
570
|
+
else if (theJoin->lastLevel != NULL)
|
571
|
+
{ betaCount += BetaJoinCountDriver(theEnv,theJoin->lastLevel); }
|
572
|
+
|
573
|
+
return betaCount;
|
574
|
+
}
|
575
|
+
|
576
|
+
/***********************************************/
|
577
|
+
/* BetaJoinCount: Returns the number of beta */
|
578
|
+
/* joins associated with the specified rule. */
|
579
|
+
/***********************************************/
|
580
|
+
unsigned short BetaJoinCount(
|
581
|
+
Environment *theEnv,
|
582
|
+
Defrule *theDefrule)
|
583
|
+
{
|
584
|
+
return BetaJoinCountDriver(theEnv,theDefrule->lastJoin->lastLevel);
|
585
|
+
}
|
586
|
+
|
587
|
+
/**************************************/
|
588
|
+
/* BetaJoinsDriver: Driver routine to */
|
589
|
+
/* retrieve a rule's beta joins. */
|
590
|
+
/**************************************/
|
591
|
+
static void BetaJoinsDriver(
|
592
|
+
Environment *theEnv,
|
593
|
+
struct joinNode *theJoin,
|
594
|
+
unsigned short betaIndex,
|
595
|
+
struct joinInformation *theJoinInfoArray,
|
596
|
+
struct betaMemory *lastMemory,
|
597
|
+
struct joinNode *nextJoin)
|
598
|
+
{
|
599
|
+
unsigned short theCE = 0;
|
600
|
+
int theCount;
|
601
|
+
struct joinNode *tmpPtr;
|
602
|
+
|
603
|
+
if (theJoin == NULL)
|
604
|
+
{ return; }
|
605
|
+
|
606
|
+
theJoinInfoArray[betaIndex-1].theJoin = theJoin;
|
607
|
+
theJoinInfoArray[betaIndex-1].theMemory = lastMemory;
|
608
|
+
theJoinInfoArray[betaIndex-1].nextJoin = nextJoin;
|
609
|
+
|
610
|
+
/*===================================*/
|
611
|
+
/* Determine the conditional element */
|
612
|
+
/* index for this join. */
|
613
|
+
/*===================================*/
|
614
|
+
|
615
|
+
for (tmpPtr = theJoin; tmpPtr != NULL; tmpPtr = tmpPtr->lastLevel)
|
616
|
+
{ theCE++; }
|
617
|
+
|
618
|
+
theJoinInfoArray[betaIndex-1].whichCE = theCE;
|
619
|
+
|
620
|
+
/*==============================================*/
|
621
|
+
/* The end pattern in the range of patterns for */
|
622
|
+
/* this join is always the number of patterns */
|
623
|
+
/* remaining to be encountered. */
|
624
|
+
/*==============================================*/
|
625
|
+
|
626
|
+
theCount = CountPatterns(theEnv,theJoin,true);
|
627
|
+
theJoinInfoArray[betaIndex-1].patternEnd = theCount;
|
628
|
+
|
629
|
+
/*========================================================*/
|
630
|
+
/* Determine where the block of patterns for a CE begins. */
|
631
|
+
/*========================================================*/
|
632
|
+
|
633
|
+
|
634
|
+
theCount = CountPatterns(theEnv,theJoin,false);
|
635
|
+
theJoinInfoArray[betaIndex-1].patternBegin = theCount;
|
636
|
+
|
637
|
+
/*==========================*/
|
638
|
+
/* Find the next beta join. */
|
639
|
+
/*==========================*/
|
640
|
+
|
641
|
+
if (theJoin->joinFromTheRight)
|
642
|
+
{ BetaJoinsDriver(theEnv,(struct joinNode *) theJoin->rightSideEntryStructure,betaIndex-1,theJoinInfoArray,theJoin->rightMemory,theJoin); }
|
643
|
+
else if (theJoin->lastLevel != NULL)
|
644
|
+
{ BetaJoinsDriver(theEnv,theJoin->lastLevel,betaIndex-1,theJoinInfoArray,theJoin->leftMemory,theJoin); }
|
645
|
+
|
646
|
+
return;
|
647
|
+
}
|
648
|
+
|
649
|
+
/*****************************************/
|
650
|
+
/* BetaJoins: Retrieves the beta joins */
|
651
|
+
/* associated with the specified rule. */
|
652
|
+
/*****************************************/
|
653
|
+
void BetaJoins(
|
654
|
+
Environment *theEnv,
|
655
|
+
Defrule *theDefrule,
|
656
|
+
unsigned short betaArraySize,
|
657
|
+
struct joinInformation *theInfo)
|
658
|
+
{
|
659
|
+
BetaJoinsDriver(theEnv,theDefrule->lastJoin->lastLevel,betaArraySize,theInfo,theDefrule->lastJoin->leftMemory,theDefrule->lastJoin);
|
660
|
+
}
|
661
|
+
|
662
|
+
/***********************************************/
|
663
|
+
/* CreateJoinArray: Creates a join information */
|
664
|
+
/* array of the specified size. */
|
665
|
+
/***********************************************/
|
666
|
+
struct joinInformation *CreateJoinArray(
|
667
|
+
Environment *theEnv,
|
668
|
+
unsigned short size)
|
669
|
+
{
|
670
|
+
if (size == 0) return NULL;
|
671
|
+
|
672
|
+
return (struct joinInformation *) genalloc(theEnv,sizeof(struct joinInformation) * size);
|
673
|
+
}
|
674
|
+
|
675
|
+
/*******************************************/
|
676
|
+
/* FreeJoinArray: Frees a join information */
|
677
|
+
/* array of the specified size. */
|
678
|
+
/*******************************************/
|
679
|
+
void FreeJoinArray(
|
680
|
+
Environment *theEnv,
|
681
|
+
struct joinInformation *theArray,
|
682
|
+
unsigned short size)
|
683
|
+
{
|
684
|
+
if (size == 0) return;
|
685
|
+
|
686
|
+
genfree(theEnv,theArray,sizeof(struct joinInformation) * size);
|
687
|
+
}
|
688
|
+
|
689
|
+
/*********************/
|
690
|
+
/* ListAlphaMatches: */
|
691
|
+
/*********************/
|
692
|
+
static long long ListAlphaMatches(
|
693
|
+
Environment *theEnv,
|
694
|
+
struct joinInformation *theInfo,
|
695
|
+
Verbosity output)
|
696
|
+
{
|
697
|
+
struct alphaMemoryHash *listOfHashNodes;
|
698
|
+
struct partialMatch *listOfMatches;
|
699
|
+
long long count;
|
700
|
+
struct joinNode *theJoin;
|
701
|
+
long long alphaCount = 0;
|
702
|
+
|
703
|
+
if (GetHaltExecution(theEnv) == true)
|
704
|
+
{ return(alphaCount); }
|
705
|
+
|
706
|
+
theJoin = theInfo->theJoin;
|
707
|
+
|
708
|
+
if (output == VERBOSE)
|
709
|
+
{
|
710
|
+
WriteString(theEnv,STDOUT,"Matches for Pattern ");
|
711
|
+
WriteInteger(theEnv,STDOUT,theInfo->whichCE);
|
712
|
+
WriteString(theEnv,STDOUT,"\n");
|
713
|
+
}
|
714
|
+
|
715
|
+
if (theJoin->rightSideEntryStructure == NULL)
|
716
|
+
{
|
717
|
+
if (theJoin->rightMemory->beta[0]->children != NULL)
|
718
|
+
{ alphaCount += 1; }
|
719
|
+
|
720
|
+
if (output == VERBOSE)
|
721
|
+
{
|
722
|
+
if (theJoin->rightMemory->beta[0]->children != NULL)
|
723
|
+
{ WriteString(theEnv,STDOUT,"*\n"); }
|
724
|
+
else
|
725
|
+
{ WriteString(theEnv,STDOUT," None\n"); }
|
726
|
+
}
|
727
|
+
else if (output == SUCCINCT)
|
728
|
+
{
|
729
|
+
WriteString(theEnv,STDOUT,"Pattern ");
|
730
|
+
WriteInteger(theEnv,STDOUT,theInfo->whichCE);
|
731
|
+
WriteString(theEnv,STDOUT,": ");
|
732
|
+
|
733
|
+
if (theJoin->rightMemory->beta[0]->children != NULL)
|
734
|
+
{ WriteString(theEnv,STDOUT,"1"); }
|
735
|
+
else
|
736
|
+
{ WriteString(theEnv,STDOUT,"0"); }
|
737
|
+
WriteString(theEnv,STDOUT,"\n");
|
738
|
+
}
|
739
|
+
|
740
|
+
return(alphaCount);
|
741
|
+
}
|
742
|
+
|
743
|
+
listOfHashNodes = ((struct patternNodeHeader *) theJoin->rightSideEntryStructure)->firstHash;
|
744
|
+
|
745
|
+
for (count = 0;
|
746
|
+
listOfHashNodes != NULL;
|
747
|
+
listOfHashNodes = listOfHashNodes->nextHash)
|
748
|
+
{
|
749
|
+
listOfMatches = listOfHashNodes->alphaMemory;
|
750
|
+
|
751
|
+
while (listOfMatches != NULL)
|
752
|
+
{
|
753
|
+
if (GetHaltExecution(theEnv) == true)
|
754
|
+
{ return(alphaCount); }
|
755
|
+
|
756
|
+
count++;
|
757
|
+
if (output == VERBOSE)
|
758
|
+
{
|
759
|
+
PrintPartialMatch(theEnv,STDOUT,listOfMatches);
|
760
|
+
WriteString(theEnv,STDOUT,"\n");
|
761
|
+
}
|
762
|
+
listOfMatches = listOfMatches->nextInMemory;
|
763
|
+
}
|
764
|
+
}
|
765
|
+
|
766
|
+
alphaCount += count;
|
767
|
+
|
768
|
+
if ((count == 0) && (output == VERBOSE)) WriteString(theEnv,STDOUT," None\n");
|
769
|
+
|
770
|
+
if (output == SUCCINCT)
|
771
|
+
{
|
772
|
+
WriteString(theEnv,STDOUT,"Pattern ");
|
773
|
+
WriteInteger(theEnv,STDOUT,theInfo->whichCE);
|
774
|
+
WriteString(theEnv,STDOUT,": ");
|
775
|
+
WriteInteger(theEnv,STDOUT,count);
|
776
|
+
WriteString(theEnv,STDOUT,"\n");
|
777
|
+
}
|
778
|
+
|
779
|
+
return(alphaCount);
|
780
|
+
}
|
781
|
+
|
782
|
+
/********************/
|
783
|
+
/* BetaHeaderString */
|
784
|
+
/********************/
|
785
|
+
static const char *BetaHeaderString(
|
786
|
+
Environment *theEnv,
|
787
|
+
struct joinInformation *infoArray,
|
788
|
+
long joinIndex,
|
789
|
+
long arraySize)
|
790
|
+
{
|
791
|
+
struct joinNode *theJoin;
|
792
|
+
struct joinInformation *theInfo;
|
793
|
+
long i, j, startPosition, endPosition, positionsToPrint = 0;
|
794
|
+
bool nestedCEs = false;
|
795
|
+
const char *returnString = "";
|
796
|
+
long lastIndex;
|
797
|
+
char buffer[32];
|
798
|
+
|
799
|
+
/*=============================================*/
|
800
|
+
/* Determine which joins need to be traversed. */
|
801
|
+
/*=============================================*/
|
802
|
+
|
803
|
+
for (i = 0; i < arraySize; i++)
|
804
|
+
{ infoArray[i].marked = false; }
|
805
|
+
|
806
|
+
theInfo = &infoArray[joinIndex];
|
807
|
+
theJoin = theInfo->theJoin;
|
808
|
+
lastIndex = joinIndex;
|
809
|
+
|
810
|
+
while (theJoin != NULL)
|
811
|
+
{
|
812
|
+
for (i = lastIndex; i >= 0; i--)
|
813
|
+
{
|
814
|
+
if (infoArray[i].theJoin == theJoin)
|
815
|
+
{
|
816
|
+
positionsToPrint++;
|
817
|
+
infoArray[i].marked = true;
|
818
|
+
if (infoArray[i].patternBegin != infoArray[i].patternEnd)
|
819
|
+
{ nestedCEs = true; }
|
820
|
+
lastIndex = i - 1;
|
821
|
+
break;
|
822
|
+
}
|
823
|
+
}
|
824
|
+
theJoin = theJoin->lastLevel;
|
825
|
+
}
|
826
|
+
|
827
|
+
for (i = 0; i <= joinIndex; i++)
|
828
|
+
{
|
829
|
+
if (infoArray[i].marked == false) continue;
|
830
|
+
|
831
|
+
positionsToPrint--;
|
832
|
+
startPosition = i;
|
833
|
+
endPosition = i;
|
834
|
+
|
835
|
+
if (infoArray[i].patternBegin == infoArray[i].patternEnd)
|
836
|
+
{
|
837
|
+
for (j = i + 1; j <= joinIndex; j++)
|
838
|
+
{
|
839
|
+
if (infoArray[j].marked == false) continue;
|
840
|
+
|
841
|
+
if (infoArray[j].patternBegin != infoArray[j].patternEnd) break;
|
842
|
+
|
843
|
+
positionsToPrint--;
|
844
|
+
i = j;
|
845
|
+
endPosition = j;
|
846
|
+
}
|
847
|
+
}
|
848
|
+
|
849
|
+
theInfo = &infoArray[startPosition];
|
850
|
+
|
851
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->whichCE);
|
852
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
853
|
+
|
854
|
+
if (nestedCEs)
|
855
|
+
{
|
856
|
+
if (theInfo->patternBegin == theInfo->patternEnd)
|
857
|
+
{
|
858
|
+
returnString = AppendStrings(theEnv,returnString," (P");
|
859
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->patternBegin);
|
860
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
861
|
+
returnString = AppendStrings(theEnv,returnString,")");
|
862
|
+
}
|
863
|
+
else
|
864
|
+
{
|
865
|
+
returnString = AppendStrings(theEnv,returnString," (P");
|
866
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->patternBegin);
|
867
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
868
|
+
returnString = AppendStrings(theEnv,returnString," - P");
|
869
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->patternEnd);
|
870
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
871
|
+
returnString = AppendStrings(theEnv,returnString,")");
|
872
|
+
}
|
873
|
+
}
|
874
|
+
|
875
|
+
if (startPosition != endPosition)
|
876
|
+
{
|
877
|
+
theInfo = &infoArray[endPosition];
|
878
|
+
|
879
|
+
returnString = AppendStrings(theEnv,returnString," - ");
|
880
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->whichCE);
|
881
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
882
|
+
|
883
|
+
if (nestedCEs)
|
884
|
+
{
|
885
|
+
if (theInfo->patternBegin == theInfo->patternEnd)
|
886
|
+
{
|
887
|
+
returnString = AppendStrings(theEnv,returnString," (P");
|
888
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->patternBegin);
|
889
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
890
|
+
returnString = AppendStrings(theEnv,returnString,")");
|
891
|
+
}
|
892
|
+
else
|
893
|
+
{
|
894
|
+
returnString = AppendStrings(theEnv,returnString," (P");
|
895
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->patternBegin);
|
896
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
897
|
+
returnString = AppendStrings(theEnv,returnString," - P");
|
898
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->patternEnd);
|
899
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
900
|
+
returnString = AppendStrings(theEnv,returnString,")");
|
901
|
+
}
|
902
|
+
}
|
903
|
+
}
|
904
|
+
|
905
|
+
if (positionsToPrint > 0)
|
906
|
+
{ returnString = AppendStrings(theEnv,returnString," , "); }
|
907
|
+
}
|
908
|
+
|
909
|
+
return returnString;
|
910
|
+
}
|
911
|
+
|
912
|
+
/********************/
|
913
|
+
/* ListBetaMatches: */
|
914
|
+
/********************/
|
915
|
+
static long long ListBetaMatches(
|
916
|
+
Environment *theEnv,
|
917
|
+
struct joinInformation *infoArray,
|
918
|
+
long joinIndex,
|
919
|
+
unsigned short arraySize,
|
920
|
+
Verbosity output)
|
921
|
+
{
|
922
|
+
long betaCount = 0;
|
923
|
+
struct joinInformation *theInfo;
|
924
|
+
unsigned long count;
|
925
|
+
|
926
|
+
if (GetHaltExecution(theEnv) == true)
|
927
|
+
{ return(betaCount); }
|
928
|
+
|
929
|
+
theInfo = &infoArray[joinIndex];
|
930
|
+
|
931
|
+
if (output == VERBOSE)
|
932
|
+
{
|
933
|
+
WriteString(theEnv,STDOUT,"Partial matches for CEs ");
|
934
|
+
WriteString(theEnv,STDOUT,
|
935
|
+
BetaHeaderString(theEnv,infoArray,joinIndex,arraySize));
|
936
|
+
WriteString(theEnv,STDOUT,"\n");
|
937
|
+
}
|
938
|
+
|
939
|
+
count = PrintBetaMemory(theEnv,STDOUT,theInfo->theMemory,true,"",output);
|
940
|
+
|
941
|
+
betaCount += count;
|
942
|
+
|
943
|
+
if ((output == VERBOSE) && (count == 0))
|
944
|
+
{ WriteString(theEnv,STDOUT," None\n"); }
|
945
|
+
else if (output == SUCCINCT)
|
946
|
+
{
|
947
|
+
WriteString(theEnv,STDOUT,"CEs ");
|
948
|
+
WriteString(theEnv,STDOUT,
|
949
|
+
BetaHeaderString(theEnv,infoArray,joinIndex,arraySize));
|
950
|
+
WriteString(theEnv,STDOUT,": ");
|
951
|
+
WriteInteger(theEnv,STDOUT,betaCount);
|
952
|
+
WriteString(theEnv,STDOUT,"\n");
|
953
|
+
}
|
954
|
+
|
955
|
+
return betaCount;
|
956
|
+
}
|
957
|
+
|
958
|
+
/******************/
|
959
|
+
/* CountPatterns: */
|
960
|
+
/******************/
|
961
|
+
static int CountPatterns(
|
962
|
+
Environment *theEnv,
|
963
|
+
struct joinNode *theJoin,
|
964
|
+
bool followRight)
|
965
|
+
{
|
966
|
+
int theCount = 0;
|
967
|
+
|
968
|
+
if (theJoin == NULL) return theCount;
|
969
|
+
|
970
|
+
if (theJoin->joinFromTheRight && (followRight == false))
|
971
|
+
{ theCount++; }
|
972
|
+
|
973
|
+
while (theJoin != NULL)
|
974
|
+
{
|
975
|
+
if (theJoin->joinFromTheRight)
|
976
|
+
{
|
977
|
+
if (followRight)
|
978
|
+
{ theJoin = (struct joinNode *) theJoin->rightSideEntryStructure; }
|
979
|
+
else
|
980
|
+
{ theJoin = theJoin->lastLevel; }
|
981
|
+
}
|
982
|
+
else
|
983
|
+
{
|
984
|
+
theCount++;
|
985
|
+
theJoin = theJoin->lastLevel;
|
986
|
+
}
|
987
|
+
|
988
|
+
followRight = true;
|
989
|
+
}
|
990
|
+
|
991
|
+
return theCount;
|
992
|
+
}
|
993
|
+
|
994
|
+
/*******************************************/
|
995
|
+
/* JoinActivityCommand: H/L access routine */
|
996
|
+
/* for the join-activity command. */
|
997
|
+
/*******************************************/
|
998
|
+
void JoinActivityCommand(
|
999
|
+
Environment *theEnv,
|
1000
|
+
UDFContext *context,
|
1001
|
+
UDFValue *returnValue)
|
1002
|
+
{
|
1003
|
+
const char *ruleName, *argument;
|
1004
|
+
Defrule *rulePtr;
|
1005
|
+
UDFValue theArg;
|
1006
|
+
int output;
|
1007
|
+
|
1008
|
+
if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
|
1009
|
+
{ return; }
|
1010
|
+
|
1011
|
+
ruleName = theArg.lexemeValue->contents;
|
1012
|
+
|
1013
|
+
rulePtr = FindDefrule(theEnv,ruleName);
|
1014
|
+
if (rulePtr == NULL)
|
1015
|
+
{
|
1016
|
+
CantFindItemErrorMessage(theEnv,"defrule",ruleName,true);
|
1017
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
1018
|
+
return;
|
1019
|
+
}
|
1020
|
+
|
1021
|
+
if (UDFHasNextArgument(context))
|
1022
|
+
{
|
1023
|
+
if (! UDFNextArgument(context,SYMBOL_BIT,&theArg))
|
1024
|
+
{ return; }
|
1025
|
+
|
1026
|
+
argument = theArg.lexemeValue->contents;
|
1027
|
+
if (strcmp(argument,"verbose") == 0)
|
1028
|
+
{ output = VERBOSE; }
|
1029
|
+
else if (strcmp(argument,"succinct") == 0)
|
1030
|
+
{ output = SUCCINCT; }
|
1031
|
+
else if (strcmp(argument,"terse") == 0)
|
1032
|
+
{ output = TERSE; }
|
1033
|
+
else
|
1034
|
+
{
|
1035
|
+
UDFInvalidArgumentMessage(context,"symbol with value verbose, succinct, or terse");
|
1036
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
1037
|
+
return;
|
1038
|
+
}
|
1039
|
+
}
|
1040
|
+
else
|
1041
|
+
{ output = VERBOSE; }
|
1042
|
+
|
1043
|
+
JoinActivity(theEnv,rulePtr,output,returnValue);
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
/************************************/
|
1047
|
+
/* JoinActivity: C access routine */
|
1048
|
+
/* for the join-activity command. */
|
1049
|
+
/************************************/
|
1050
|
+
void JoinActivity(
|
1051
|
+
Environment *theEnv,
|
1052
|
+
Defrule *theRule,
|
1053
|
+
int output,
|
1054
|
+
UDFValue *returnValue)
|
1055
|
+
{
|
1056
|
+
Defrule *rulePtr;
|
1057
|
+
long disjunctCount, disjunctIndex, joinIndex;
|
1058
|
+
unsigned short arraySize;
|
1059
|
+
struct joinInformation *theInfo;
|
1060
|
+
|
1061
|
+
/*==========================*/
|
1062
|
+
/* Set up the return value. */
|
1063
|
+
/*==========================*/
|
1064
|
+
|
1065
|
+
returnValue->begin = 0;
|
1066
|
+
returnValue->range = 3;
|
1067
|
+
returnValue->value = CreateMultifield(theEnv,3L);
|
1068
|
+
|
1069
|
+
returnValue->multifieldValue->contents[0].integerValue = SymbolData(theEnv)->Zero;
|
1070
|
+
returnValue->multifieldValue->contents[1].integerValue = SymbolData(theEnv)->Zero;
|
1071
|
+
returnValue->multifieldValue->contents[2].integerValue = SymbolData(theEnv)->Zero;
|
1072
|
+
|
1073
|
+
/*=================================================*/
|
1074
|
+
/* Loop through each of the disjuncts for the rule */
|
1075
|
+
/*=================================================*/
|
1076
|
+
|
1077
|
+
disjunctCount = GetDisjunctCount(theEnv,theRule);
|
1078
|
+
|
1079
|
+
for (disjunctIndex = 1; disjunctIndex <= disjunctCount; disjunctIndex++)
|
1080
|
+
{
|
1081
|
+
rulePtr = GetNthDisjunct(theEnv,theRule,disjunctIndex);
|
1082
|
+
|
1083
|
+
/*==============================================*/
|
1084
|
+
/* Create the array containing the list of beta */
|
1085
|
+
/* join nodes (joins from the right plus joins */
|
1086
|
+
/* connected to a pattern CE). */
|
1087
|
+
/*==============================================*/
|
1088
|
+
|
1089
|
+
arraySize = BetaJoinCount(theEnv,rulePtr);
|
1090
|
+
|
1091
|
+
theInfo = CreateJoinArray(theEnv,arraySize);
|
1092
|
+
|
1093
|
+
BetaJoins(theEnv,rulePtr,arraySize,theInfo);
|
1094
|
+
|
1095
|
+
/*======================================*/
|
1096
|
+
/* List the beta matches (for all joins */
|
1097
|
+
/* except the first pattern CE). */
|
1098
|
+
/*======================================*/
|
1099
|
+
|
1100
|
+
for (joinIndex = 0; joinIndex < arraySize; joinIndex++)
|
1101
|
+
{ ListBetaJoinActivity(theEnv,theInfo,joinIndex,arraySize,output,returnValue); }
|
1102
|
+
|
1103
|
+
/*================================*/
|
1104
|
+
/* Free the array of alpha joins. */
|
1105
|
+
/*================================*/
|
1106
|
+
|
1107
|
+
FreeJoinArray(theEnv,theInfo,arraySize);
|
1108
|
+
}
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
/************************/
|
1112
|
+
/* ActivityHeaderString */
|
1113
|
+
/************************/
|
1114
|
+
static const char *ActivityHeaderString(
|
1115
|
+
Environment *theEnv,
|
1116
|
+
struct joinInformation *infoArray,
|
1117
|
+
long joinIndex,
|
1118
|
+
long arraySize)
|
1119
|
+
{
|
1120
|
+
struct joinNode *theJoin;
|
1121
|
+
struct joinInformation *theInfo;
|
1122
|
+
long i;
|
1123
|
+
bool nestedCEs = false;
|
1124
|
+
const char *returnString = "";
|
1125
|
+
long lastIndex;
|
1126
|
+
char buffer[32];
|
1127
|
+
|
1128
|
+
/*=============================================*/
|
1129
|
+
/* Determine which joins need to be traversed. */
|
1130
|
+
/*=============================================*/
|
1131
|
+
|
1132
|
+
for (i = 0; i < arraySize; i++)
|
1133
|
+
{ infoArray[i].marked = false; }
|
1134
|
+
|
1135
|
+
theInfo = &infoArray[joinIndex];
|
1136
|
+
theJoin = theInfo->theJoin;
|
1137
|
+
lastIndex = joinIndex;
|
1138
|
+
|
1139
|
+
while (theJoin != NULL)
|
1140
|
+
{
|
1141
|
+
for (i = lastIndex; i >= 0; i--)
|
1142
|
+
{
|
1143
|
+
if (infoArray[i].theJoin == theJoin)
|
1144
|
+
{
|
1145
|
+
if (infoArray[i].patternBegin != infoArray[i].patternEnd)
|
1146
|
+
{ nestedCEs = true; }
|
1147
|
+
lastIndex = i - 1;
|
1148
|
+
break;
|
1149
|
+
}
|
1150
|
+
}
|
1151
|
+
theJoin = theJoin->lastLevel;
|
1152
|
+
}
|
1153
|
+
|
1154
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->whichCE);
|
1155
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
1156
|
+
if (nestedCEs == false)
|
1157
|
+
{ return returnString; }
|
1158
|
+
|
1159
|
+
if (theInfo->patternBegin == theInfo->patternEnd)
|
1160
|
+
{
|
1161
|
+
returnString = AppendStrings(theEnv,returnString," (P");
|
1162
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->patternBegin);
|
1163
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
1164
|
+
|
1165
|
+
returnString = AppendStrings(theEnv,returnString,")");
|
1166
|
+
}
|
1167
|
+
else
|
1168
|
+
{
|
1169
|
+
returnString = AppendStrings(theEnv,returnString," (P");
|
1170
|
+
|
1171
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->patternBegin);
|
1172
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
1173
|
+
|
1174
|
+
returnString = AppendStrings(theEnv,returnString," - P");
|
1175
|
+
|
1176
|
+
gensnprintf(buffer,sizeof(buffer),"%d",theInfo->patternEnd);
|
1177
|
+
returnString = AppendStrings(theEnv,returnString,buffer);
|
1178
|
+
|
1179
|
+
returnString = AppendStrings(theEnv,returnString,")");
|
1180
|
+
}
|
1181
|
+
|
1182
|
+
return returnString;
|
1183
|
+
}
|
1184
|
+
|
1185
|
+
/*************************/
|
1186
|
+
/* ListBetaJoinActivity: */
|
1187
|
+
/*************************/
|
1188
|
+
static void ListBetaJoinActivity(
|
1189
|
+
Environment *theEnv,
|
1190
|
+
struct joinInformation *infoArray,
|
1191
|
+
long joinIndex,
|
1192
|
+
long arraySize,
|
1193
|
+
int output,
|
1194
|
+
UDFValue *returnValue)
|
1195
|
+
{
|
1196
|
+
long long activity = 0;
|
1197
|
+
long long compares, adds, deletes;
|
1198
|
+
struct joinNode *theJoin, *nextJoin;
|
1199
|
+
struct joinInformation *theInfo;
|
1200
|
+
|
1201
|
+
if (GetHaltExecution(theEnv) == true)
|
1202
|
+
{ return; }
|
1203
|
+
|
1204
|
+
theInfo = &infoArray[joinIndex];
|
1205
|
+
|
1206
|
+
theJoin = theInfo->theJoin;
|
1207
|
+
nextJoin = theInfo->nextJoin;
|
1208
|
+
|
1209
|
+
compares = theJoin->memoryCompares;
|
1210
|
+
if (theInfo->nextJoin->joinFromTheRight)
|
1211
|
+
{
|
1212
|
+
adds = nextJoin->memoryRightAdds;
|
1213
|
+
deletes = nextJoin->memoryRightDeletes;
|
1214
|
+
}
|
1215
|
+
else
|
1216
|
+
{
|
1217
|
+
adds = nextJoin->memoryLeftAdds;
|
1218
|
+
deletes = nextJoin->memoryLeftDeletes;
|
1219
|
+
}
|
1220
|
+
|
1221
|
+
activity = compares + adds + deletes;
|
1222
|
+
|
1223
|
+
if (output == VERBOSE)
|
1224
|
+
{
|
1225
|
+
char buffer[100];
|
1226
|
+
|
1227
|
+
WriteString(theEnv,STDOUT,"Activity for CE ");
|
1228
|
+
WriteString(theEnv,STDOUT,
|
1229
|
+
ActivityHeaderString(theEnv,infoArray,joinIndex,arraySize));
|
1230
|
+
WriteString(theEnv,STDOUT,"\n");
|
1231
|
+
|
1232
|
+
gensnprintf(buffer,sizeof(buffer)," Compares: %10lld\n",compares);
|
1233
|
+
WriteString(theEnv,STDOUT,buffer);
|
1234
|
+
gensnprintf(buffer,sizeof(buffer)," Adds: %10lld\n",adds);
|
1235
|
+
WriteString(theEnv,STDOUT,buffer);
|
1236
|
+
gensnprintf(buffer,sizeof(buffer)," Deletes: %10lld\n",deletes);
|
1237
|
+
WriteString(theEnv,STDOUT,buffer);
|
1238
|
+
}
|
1239
|
+
else if (output == SUCCINCT)
|
1240
|
+
{
|
1241
|
+
WriteString(theEnv,STDOUT,"CE ");
|
1242
|
+
WriteString(theEnv,STDOUT,
|
1243
|
+
ActivityHeaderString(theEnv,infoArray,joinIndex,arraySize));
|
1244
|
+
WriteString(theEnv,STDOUT,": ");
|
1245
|
+
WriteInteger(theEnv,STDOUT,activity);
|
1246
|
+
WriteString(theEnv,STDOUT,"\n");
|
1247
|
+
}
|
1248
|
+
|
1249
|
+
compares += returnValue->multifieldValue->contents[0].integerValue->contents;
|
1250
|
+
adds += returnValue->multifieldValue->contents[1].integerValue->contents;
|
1251
|
+
deletes += returnValue->multifieldValue->contents[2].integerValue->contents;
|
1252
|
+
|
1253
|
+
returnValue->multifieldValue->contents[0].integerValue = CreateInteger(theEnv,compares);
|
1254
|
+
returnValue->multifieldValue->contents[1].integerValue = CreateInteger(theEnv,adds);
|
1255
|
+
returnValue->multifieldValue->contents[2].integerValue = CreateInteger(theEnv,deletes);
|
1256
|
+
}
|
1257
|
+
|
1258
|
+
/*********************************************/
|
1259
|
+
/* JoinActivityReset: Sets the join activity */
|
1260
|
+
/* counts for each rule back to 0. */
|
1261
|
+
/*********************************************/
|
1262
|
+
static void JoinActivityReset(
|
1263
|
+
Environment *theEnv,
|
1264
|
+
ConstructHeader *theConstruct,
|
1265
|
+
void *buffer)
|
1266
|
+
{
|
1267
|
+
#if MAC_XCD
|
1268
|
+
#pragma unused(buffer)
|
1269
|
+
#endif
|
1270
|
+
Defrule *theDefrule = (Defrule *) theConstruct;
|
1271
|
+
struct joinNode *theJoin = theDefrule->lastJoin;
|
1272
|
+
|
1273
|
+
while (theJoin != NULL)
|
1274
|
+
{
|
1275
|
+
theJoin->memoryCompares = 0;
|
1276
|
+
theJoin->memoryLeftAdds = 0;
|
1277
|
+
theJoin->memoryRightAdds = 0;
|
1278
|
+
theJoin->memoryLeftDeletes = 0;
|
1279
|
+
theJoin->memoryRightDeletes = 0;
|
1280
|
+
|
1281
|
+
if (theJoin->joinFromTheRight)
|
1282
|
+
{ theJoin = (struct joinNode *) theJoin->rightSideEntryStructure; }
|
1283
|
+
else
|
1284
|
+
{ theJoin = theJoin->lastLevel; }
|
1285
|
+
}
|
1286
|
+
}
|
1287
|
+
|
1288
|
+
/************************************************/
|
1289
|
+
/* JoinActivityResetCommand: H/L access routine */
|
1290
|
+
/* for the reset-join-activity command. */
|
1291
|
+
/************************************************/
|
1292
|
+
void JoinActivityResetCommand(
|
1293
|
+
Environment *theEnv,
|
1294
|
+
UDFContext *context,
|
1295
|
+
UDFValue *returnValue)
|
1296
|
+
{
|
1297
|
+
DoForAllConstructs(theEnv,
|
1298
|
+
JoinActivityReset,
|
1299
|
+
DefruleData(theEnv)->DefruleModuleIndex,true,NULL);
|
1300
|
+
}
|
1301
|
+
|
1302
|
+
/***************************************/
|
1303
|
+
/* TimetagFunction: H/L access routine */
|
1304
|
+
/* for the timetag function. */
|
1305
|
+
/***************************************/
|
1306
|
+
void TimetagFunction(
|
1307
|
+
Environment *theEnv,
|
1308
|
+
UDFContext *context,
|
1309
|
+
UDFValue *returnValue)
|
1310
|
+
{
|
1311
|
+
UDFValue theArg;
|
1312
|
+
void *ptr;
|
1313
|
+
|
1314
|
+
ptr = GetFactOrInstanceArgument(context,1,&theArg);
|
1315
|
+
|
1316
|
+
if (ptr == NULL)
|
1317
|
+
{
|
1318
|
+
returnValue->integerValue = CreateInteger(theEnv,-1LL);
|
1319
|
+
return;
|
1320
|
+
}
|
1321
|
+
|
1322
|
+
returnValue->integerValue = CreateInteger(theEnv,(long long) ((struct patternEntity *) ptr)->timeTag);
|
1323
|
+
}
|
1324
|
+
|
1325
|
+
#endif /* DEBUGGING_FUNCTIONS */
|
1326
|
+
|
1327
|
+
#if DEVELOPER
|
1328
|
+
/***********************************************/
|
1329
|
+
/* RuleComplexityCommand: H/L access routine */
|
1330
|
+
/* for the rule-complexity function. */
|
1331
|
+
/***********************************************/
|
1332
|
+
void RuleComplexityCommand(
|
1333
|
+
Environment *theEnv,
|
1334
|
+
UDFContext *context,
|
1335
|
+
UDFValue *returnValue)
|
1336
|
+
{
|
1337
|
+
const char *ruleName;
|
1338
|
+
Defrule *rulePtr;
|
1339
|
+
|
1340
|
+
ruleName = GetConstructName(context,"rule-complexity","rule name");
|
1341
|
+
if (ruleName == NULL)
|
1342
|
+
{
|
1343
|
+
returnValue->integerValue = CreateInteger(theEnv,-1);
|
1344
|
+
return;
|
1345
|
+
}
|
1346
|
+
|
1347
|
+
rulePtr = FindDefrule(theEnv,ruleName);
|
1348
|
+
if (rulePtr == NULL)
|
1349
|
+
{
|
1350
|
+
CantFindItemErrorMessage(theEnv,"defrule",ruleName,true);
|
1351
|
+
returnValue->integerValue = CreateInteger(theEnv,-1);
|
1352
|
+
return;
|
1353
|
+
}
|
1354
|
+
|
1355
|
+
returnValue->integerValue = CreateInteger(theEnv,rulePtr->complexity);
|
1356
|
+
}
|
1357
|
+
|
1358
|
+
/******************************************/
|
1359
|
+
/* ShowJoinsCommand: H/L access routine */
|
1360
|
+
/* for the show-joins command. */
|
1361
|
+
/******************************************/
|
1362
|
+
void ShowJoinsCommand(
|
1363
|
+
Environment *theEnv,
|
1364
|
+
UDFContext *context,
|
1365
|
+
UDFValue *returnValue)
|
1366
|
+
{
|
1367
|
+
const char *ruleName;
|
1368
|
+
Defrule *rulePtr;
|
1369
|
+
|
1370
|
+
ruleName = GetConstructName(context,"show-joins","rule name");
|
1371
|
+
if (ruleName == NULL) return;
|
1372
|
+
|
1373
|
+
rulePtr = FindDefrule(theEnv,ruleName);
|
1374
|
+
if (rulePtr == NULL)
|
1375
|
+
{
|
1376
|
+
CantFindItemErrorMessage(theEnv,"defrule",ruleName,true);
|
1377
|
+
return;
|
1378
|
+
}
|
1379
|
+
|
1380
|
+
ShowJoins(theEnv,rulePtr);
|
1381
|
+
|
1382
|
+
return;
|
1383
|
+
}
|
1384
|
+
|
1385
|
+
/*********************************/
|
1386
|
+
/* ShowJoins: C access routine */
|
1387
|
+
/* for the show-joins command. */
|
1388
|
+
/*********************************/
|
1389
|
+
static void ShowJoins(
|
1390
|
+
Environment *theEnv,
|
1391
|
+
Defrule *theRule)
|
1392
|
+
{
|
1393
|
+
Defrule *rulePtr;
|
1394
|
+
struct joinNode *theJoin;
|
1395
|
+
struct joinNode *joinList[MAXIMUM_NUMBER_OF_PATTERNS];
|
1396
|
+
int numberOfJoins;
|
1397
|
+
char rhsType;
|
1398
|
+
unsigned int disjunct = 0;
|
1399
|
+
unsigned long count = 0;
|
1400
|
+
|
1401
|
+
rulePtr = theRule;
|
1402
|
+
|
1403
|
+
if ((rulePtr != NULL) && (rulePtr->disjunct != NULL))
|
1404
|
+
{ disjunct = 1; }
|
1405
|
+
|
1406
|
+
/*=================================================*/
|
1407
|
+
/* Loop through each of the disjuncts for the rule */
|
1408
|
+
/*=================================================*/
|
1409
|
+
|
1410
|
+
while (rulePtr != NULL)
|
1411
|
+
{
|
1412
|
+
if (disjunct > 0)
|
1413
|
+
{
|
1414
|
+
WriteString(theEnv,STDOUT,"Disjunct #");
|
1415
|
+
PrintUnsignedInteger(theEnv,STDOUT,disjunct++);
|
1416
|
+
WriteString(theEnv,STDOUT,"\n");
|
1417
|
+
}
|
1418
|
+
|
1419
|
+
/*=====================================*/
|
1420
|
+
/* Determine the number of join nodes. */
|
1421
|
+
/*=====================================*/
|
1422
|
+
|
1423
|
+
numberOfJoins = -1;
|
1424
|
+
theJoin = rulePtr->lastJoin;
|
1425
|
+
while (theJoin != NULL)
|
1426
|
+
{
|
1427
|
+
if (theJoin->joinFromTheRight)
|
1428
|
+
{
|
1429
|
+
numberOfJoins++;
|
1430
|
+
joinList[numberOfJoins] = theJoin;
|
1431
|
+
theJoin = (struct joinNode *) theJoin->rightSideEntryStructure;
|
1432
|
+
}
|
1433
|
+
else
|
1434
|
+
{
|
1435
|
+
numberOfJoins++;
|
1436
|
+
joinList[numberOfJoins] = theJoin;
|
1437
|
+
theJoin = theJoin->lastLevel;
|
1438
|
+
}
|
1439
|
+
}
|
1440
|
+
|
1441
|
+
/*====================*/
|
1442
|
+
/* Display the joins. */
|
1443
|
+
/*====================*/
|
1444
|
+
|
1445
|
+
while (numberOfJoins >= 0)
|
1446
|
+
{
|
1447
|
+
char buffer[20];
|
1448
|
+
|
1449
|
+
if (joinList[numberOfJoins]->patternIsNegated)
|
1450
|
+
{ rhsType = 'n'; }
|
1451
|
+
else if (joinList[numberOfJoins]->patternIsExists)
|
1452
|
+
{ rhsType = 'x'; }
|
1453
|
+
else
|
1454
|
+
{ rhsType = ' '; }
|
1455
|
+
|
1456
|
+
gensnprintf(buffer,sizeof(buffer),"%2hu%c%c%c%c : ",joinList[numberOfJoins]->depth,
|
1457
|
+
(joinList[numberOfJoins]->firstJoin) ? 'f' : ' ',
|
1458
|
+
rhsType,
|
1459
|
+
(joinList[numberOfJoins]->joinFromTheRight) ? 'j' : ' ',
|
1460
|
+
(joinList[numberOfJoins]->logicalJoin) ? 'l' : ' ');
|
1461
|
+
WriteString(theEnv,STDOUT,buffer);
|
1462
|
+
PrintExpression(theEnv,STDOUT,joinList[numberOfJoins]->networkTest);
|
1463
|
+
WriteString(theEnv,STDOUT,"\n");
|
1464
|
+
|
1465
|
+
if (joinList[numberOfJoins]->ruleToActivate != NULL)
|
1466
|
+
{
|
1467
|
+
WriteString(theEnv,STDOUT," RA : ");
|
1468
|
+
WriteString(theEnv,STDOUT,DefruleName(joinList[numberOfJoins]->ruleToActivate));
|
1469
|
+
WriteString(theEnv,STDOUT,"\n");
|
1470
|
+
}
|
1471
|
+
|
1472
|
+
if (joinList[numberOfJoins]->secondaryNetworkTest != NULL)
|
1473
|
+
{
|
1474
|
+
WriteString(theEnv,STDOUT," SNT : ");
|
1475
|
+
PrintExpression(theEnv,STDOUT,joinList[numberOfJoins]->secondaryNetworkTest);
|
1476
|
+
WriteString(theEnv,STDOUT,"\n");
|
1477
|
+
}
|
1478
|
+
|
1479
|
+
if (joinList[numberOfJoins]->leftHash != NULL)
|
1480
|
+
{
|
1481
|
+
WriteString(theEnv,STDOUT," LH : ");
|
1482
|
+
PrintExpression(theEnv,STDOUT,joinList[numberOfJoins]->leftHash);
|
1483
|
+
WriteString(theEnv,STDOUT,"\n");
|
1484
|
+
}
|
1485
|
+
|
1486
|
+
if (joinList[numberOfJoins]->rightHash != NULL)
|
1487
|
+
{
|
1488
|
+
WriteString(theEnv,STDOUT," RH : ");
|
1489
|
+
PrintExpression(theEnv,STDOUT,joinList[numberOfJoins]->rightHash);
|
1490
|
+
WriteString(theEnv,STDOUT,"\n");
|
1491
|
+
}
|
1492
|
+
|
1493
|
+
if (! joinList[numberOfJoins]->firstJoin)
|
1494
|
+
{
|
1495
|
+
WriteString(theEnv,STDOUT," LM : ");
|
1496
|
+
count = PrintBetaMemory(theEnv,STDOUT,joinList[numberOfJoins]->leftMemory,false,"",SUCCINCT);
|
1497
|
+
if (count == 0)
|
1498
|
+
{ WriteString(theEnv,STDOUT,"None\n"); }
|
1499
|
+
else
|
1500
|
+
{
|
1501
|
+
gensnprintf(buffer,sizeof(buffer),"%lu\n",count);
|
1502
|
+
WriteString(theEnv,STDOUT,buffer);
|
1503
|
+
}
|
1504
|
+
}
|
1505
|
+
|
1506
|
+
if (joinList[numberOfJoins]->joinFromTheRight)
|
1507
|
+
{
|
1508
|
+
WriteString(theEnv,STDOUT," RM : ");
|
1509
|
+
count = PrintBetaMemory(theEnv,STDOUT,joinList[numberOfJoins]->rightMemory,false,"",SUCCINCT);
|
1510
|
+
if (count == 0)
|
1511
|
+
{ WriteString(theEnv,STDOUT,"None\n"); }
|
1512
|
+
else
|
1513
|
+
{
|
1514
|
+
gensnprintf(buffer,sizeof(buffer),"%lu\n",count);
|
1515
|
+
WriteString(theEnv,STDOUT,buffer);
|
1516
|
+
}
|
1517
|
+
}
|
1518
|
+
|
1519
|
+
numberOfJoins--;
|
1520
|
+
};
|
1521
|
+
|
1522
|
+
/*===============================*/
|
1523
|
+
/* Proceed to the next disjunct. */
|
1524
|
+
/*===============================*/
|
1525
|
+
|
1526
|
+
rulePtr = rulePtr->disjunct;
|
1527
|
+
if (rulePtr != NULL) WriteString(theEnv,STDOUT,"\n");
|
1528
|
+
}
|
1529
|
+
}
|
1530
|
+
|
1531
|
+
/******************************************************/
|
1532
|
+
/* ShowAlphaHashTable: Displays the number of entries */
|
1533
|
+
/* in each slot of the alpha hash table. */
|
1534
|
+
/******************************************************/
|
1535
|
+
void ShowAlphaHashTable(
|
1536
|
+
Environment *theEnv,
|
1537
|
+
UDFContext *context,
|
1538
|
+
UDFValue *returnValue)
|
1539
|
+
{
|
1540
|
+
int i, count;
|
1541
|
+
long totalCount = 0;
|
1542
|
+
struct alphaMemoryHash *theEntry;
|
1543
|
+
struct partialMatch *theMatch;
|
1544
|
+
char buffer[40];
|
1545
|
+
|
1546
|
+
for (i = 0; i < ALPHA_MEMORY_HASH_SIZE; i++)
|
1547
|
+
{
|
1548
|
+
for (theEntry = DefruleData(theEnv)->AlphaMemoryTable[i], count = 0;
|
1549
|
+
theEntry != NULL;
|
1550
|
+
theEntry = theEntry->next)
|
1551
|
+
{ count++; }
|
1552
|
+
|
1553
|
+
if (count != 0)
|
1554
|
+
{
|
1555
|
+
totalCount += count;
|
1556
|
+
gensnprintf(buffer,sizeof(buffer),"%4d: %4d ->",i,count);
|
1557
|
+
WriteString(theEnv,STDOUT,buffer);
|
1558
|
+
|
1559
|
+
for (theEntry = DefruleData(theEnv)->AlphaMemoryTable[i], count = 0;
|
1560
|
+
theEntry != NULL;
|
1561
|
+
theEntry = theEntry->next)
|
1562
|
+
{
|
1563
|
+
for (theMatch = theEntry->alphaMemory;
|
1564
|
+
theMatch != NULL;
|
1565
|
+
theMatch = theMatch->nextInMemory)
|
1566
|
+
{ count++; }
|
1567
|
+
|
1568
|
+
gensnprintf(buffer,sizeof(buffer)," %4d",count);
|
1569
|
+
WriteString(theEnv,STDOUT,buffer);
|
1570
|
+
if (theEntry->owner->rightHash == NULL)
|
1571
|
+
{ WriteString(theEnv,STDOUT,"*"); }
|
1572
|
+
}
|
1573
|
+
|
1574
|
+
WriteString(theEnv,STDOUT,"\n");
|
1575
|
+
}
|
1576
|
+
}
|
1577
|
+
gensnprintf(buffer,sizeof(buffer),"Total Count: %ld\n",totalCount);
|
1578
|
+
WriteString(theEnv,STDOUT,buffer);
|
1579
|
+
}
|
1580
|
+
|
1581
|
+
#endif /* DEVELOPER */
|
1582
|
+
|
1583
|
+
#endif /* DEFRULE_CONSTRUCT */
|