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,1732 @@
|
|
1
|
+
/*******************************************************/
|
2
|
+
/* "C" Language Integrated Production System */
|
3
|
+
/* */
|
4
|
+
/* CLIPS Version 6.40 10/03/19 */
|
5
|
+
/* */
|
6
|
+
/* RETE UTILITY MODULE */
|
7
|
+
/*******************************************************/
|
8
|
+
|
9
|
+
/*************************************************************/
|
10
|
+
/* Purpose: Provides a set of utility functions useful to */
|
11
|
+
/* other modules. */
|
12
|
+
/* */
|
13
|
+
/* Principal Programmer(s): */
|
14
|
+
/* Gary D. Riley */
|
15
|
+
/* */
|
16
|
+
/* Contributing Programmer(s): */
|
17
|
+
/* */
|
18
|
+
/* Revision History: */
|
19
|
+
/* */
|
20
|
+
/* 6.24: Removed INCREMENTAL_RESET compilation flag. */
|
21
|
+
/* */
|
22
|
+
/* Rule with exists CE has incorrect activation. */
|
23
|
+
/* DR0867 */
|
24
|
+
/* */
|
25
|
+
/* 6.30: Changed integer type/precision. */
|
26
|
+
/* */
|
27
|
+
/* Support for join network changes. */
|
28
|
+
/* */
|
29
|
+
/* Support for using an asterick (*) to indicate */
|
30
|
+
/* that existential patterns are matched. */
|
31
|
+
/* */
|
32
|
+
/* Support for partial match changes. */
|
33
|
+
/* */
|
34
|
+
/* Removed conditional code for unsupported */
|
35
|
+
/* compilers/operating systems (IBM_MCW and */
|
36
|
+
/* MAC_MCW). */
|
37
|
+
/* */
|
38
|
+
/* Added support for hashed memories. */
|
39
|
+
/* */
|
40
|
+
/* Removed pseudo-facts used in not CEs. */
|
41
|
+
/* */
|
42
|
+
/* Added const qualifiers to remove C++ */
|
43
|
+
/* deprecation warnings. */
|
44
|
+
/* */
|
45
|
+
/* 6.31: Bug fix to prevent rule activations for */
|
46
|
+
/* partial matches being deleted. */
|
47
|
+
/* */
|
48
|
+
/* 6.40: Added Env prefix to GetHaltExecution and */
|
49
|
+
/* SetHaltExecution functions. */
|
50
|
+
/* */
|
51
|
+
/* Pragma once and other inclusion changes. */
|
52
|
+
/* */
|
53
|
+
/* Added support for booleans with <stdbool.h>. */
|
54
|
+
/* */
|
55
|
+
/* Removed use of void pointers for specific */
|
56
|
+
/* data structures. */
|
57
|
+
/* */
|
58
|
+
/* Incremental reset is always enabled. */
|
59
|
+
/* */
|
60
|
+
/* UDF redesign. */
|
61
|
+
/* */
|
62
|
+
/*************************************************************/
|
63
|
+
|
64
|
+
#include <stdio.h>
|
65
|
+
|
66
|
+
#include "setup.h"
|
67
|
+
|
68
|
+
#if DEFRULE_CONSTRUCT
|
69
|
+
|
70
|
+
#include "drive.h"
|
71
|
+
#include "engine.h"
|
72
|
+
#include "envrnmnt.h"
|
73
|
+
#include "incrrset.h"
|
74
|
+
#include "match.h"
|
75
|
+
#include "memalloc.h"
|
76
|
+
#include "moduldef.h"
|
77
|
+
#include "pattern.h"
|
78
|
+
#include "prntutil.h"
|
79
|
+
#include "retract.h"
|
80
|
+
#include "router.h"
|
81
|
+
#include "rulecom.h"
|
82
|
+
|
83
|
+
#include "reteutil.h"
|
84
|
+
|
85
|
+
/***************************************/
|
86
|
+
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
|
87
|
+
/***************************************/
|
88
|
+
|
89
|
+
static void TraceErrorToRuleDriver(Environment *,struct joinNode *,const char *,int,bool);
|
90
|
+
static struct alphaMemoryHash *FindAlphaMemory(Environment *,struct patternNodeHeader *,unsigned long);
|
91
|
+
static unsigned long AlphaMemoryHashValue(struct patternNodeHeader *,unsigned long);
|
92
|
+
static void UnlinkAlphaMemory(Environment *,struct patternNodeHeader *,struct alphaMemoryHash *);
|
93
|
+
static void UnlinkAlphaMemoryBucketSiblings(Environment *,struct alphaMemoryHash *);
|
94
|
+
static void InitializePMLinks(struct partialMatch *);
|
95
|
+
static void UnlinkBetaPartialMatchfromAlphaAndBetaLineage(struct partialMatch *);
|
96
|
+
static int CountPriorPatterns(struct joinNode *);
|
97
|
+
static void ResizeBetaMemory(Environment *,struct betaMemory *);
|
98
|
+
static void ResetBetaMemory(Environment *,struct betaMemory *);
|
99
|
+
#if (CONSTRUCT_COMPILER || BLOAD_AND_BSAVE) && (! RUN_TIME)
|
100
|
+
static void TagNetworkTraverseJoins(Environment *,unsigned long *,unsigned long *,struct joinNode *);
|
101
|
+
#endif
|
102
|
+
|
103
|
+
/***********************************************************/
|
104
|
+
/* PrintPartialMatch: Prints out the list of fact indices */
|
105
|
+
/* and/or instance names associated with a partial match */
|
106
|
+
/* or rule instantiation. */
|
107
|
+
/***********************************************************/
|
108
|
+
void PrintPartialMatch(
|
109
|
+
Environment *theEnv,
|
110
|
+
const char *logicalName,
|
111
|
+
struct partialMatch *list)
|
112
|
+
{
|
113
|
+
struct patternEntity *matchingItem;
|
114
|
+
unsigned short i;
|
115
|
+
|
116
|
+
for (i = 0; i < list->bcount;)
|
117
|
+
{
|
118
|
+
if ((get_nth_pm_match(list,i) != NULL) &&
|
119
|
+
(get_nth_pm_match(list,i)->matchingItem != NULL))
|
120
|
+
{
|
121
|
+
matchingItem = get_nth_pm_match(list,i)->matchingItem;
|
122
|
+
(*matchingItem->theInfo->base.shortPrintFunction)(theEnv,logicalName,matchingItem);
|
123
|
+
}
|
124
|
+
else
|
125
|
+
{ WriteString(theEnv,logicalName,"*"); }
|
126
|
+
i++;
|
127
|
+
if (i < list->bcount) WriteString(theEnv,logicalName,",");
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
/**********************************************/
|
132
|
+
/* CopyPartialMatch: Copies a partial match. */
|
133
|
+
/**********************************************/
|
134
|
+
struct partialMatch *CopyPartialMatch(
|
135
|
+
Environment *theEnv,
|
136
|
+
struct partialMatch *list)
|
137
|
+
{
|
138
|
+
struct partialMatch *linker;
|
139
|
+
unsigned short i;
|
140
|
+
|
141
|
+
linker = get_var_struct(theEnv,partialMatch,sizeof(struct genericMatch) *
|
142
|
+
(list->bcount - 1));
|
143
|
+
|
144
|
+
InitializePMLinks(linker);
|
145
|
+
linker->betaMemory = true;
|
146
|
+
linker->busy = false;
|
147
|
+
linker->rhsMemory = false;
|
148
|
+
linker->deleting = false;
|
149
|
+
linker->bcount = list->bcount;
|
150
|
+
linker->hashValue = 0;
|
151
|
+
|
152
|
+
for (i = 0; i < linker->bcount; i++) linker->binds[i] = list->binds[i];
|
153
|
+
|
154
|
+
return(linker);
|
155
|
+
}
|
156
|
+
|
157
|
+
/****************************/
|
158
|
+
/* CreateEmptyPartialMatch: */
|
159
|
+
/****************************/
|
160
|
+
struct partialMatch *CreateEmptyPartialMatch(
|
161
|
+
Environment *theEnv)
|
162
|
+
{
|
163
|
+
struct partialMatch *linker;
|
164
|
+
|
165
|
+
linker = get_struct(theEnv,partialMatch);
|
166
|
+
|
167
|
+
InitializePMLinks(linker);
|
168
|
+
linker->betaMemory = true;
|
169
|
+
linker->busy = false;
|
170
|
+
linker->rhsMemory = false;
|
171
|
+
linker->deleting = false;
|
172
|
+
linker->bcount = 1;
|
173
|
+
linker->hashValue = 0;
|
174
|
+
linker->binds[0].gm.theValue = NULL;
|
175
|
+
|
176
|
+
return(linker);
|
177
|
+
}
|
178
|
+
|
179
|
+
/**********************/
|
180
|
+
/* InitializePMLinks: */
|
181
|
+
/**********************/
|
182
|
+
static void InitializePMLinks(
|
183
|
+
struct partialMatch *theMatch)
|
184
|
+
{
|
185
|
+
theMatch->nextInMemory = NULL;
|
186
|
+
theMatch->prevInMemory = NULL;
|
187
|
+
theMatch->nextRightChild = NULL;
|
188
|
+
theMatch->prevRightChild = NULL;
|
189
|
+
theMatch->nextLeftChild = NULL;
|
190
|
+
theMatch->prevLeftChild = NULL;
|
191
|
+
theMatch->children = NULL;
|
192
|
+
theMatch->rightParent = NULL;
|
193
|
+
theMatch->leftParent = NULL;
|
194
|
+
theMatch->blockList = NULL;
|
195
|
+
theMatch->nextBlocked = NULL;
|
196
|
+
theMatch->prevBlocked = NULL;
|
197
|
+
theMatch->marker = NULL;
|
198
|
+
theMatch->dependents = NULL;
|
199
|
+
}
|
200
|
+
|
201
|
+
/**********************/
|
202
|
+
/* UpdateBetaPMLinks: */
|
203
|
+
/**********************/
|
204
|
+
void UpdateBetaPMLinks(
|
205
|
+
Environment *theEnv,
|
206
|
+
struct partialMatch *thePM,
|
207
|
+
struct partialMatch *lhsBinds,
|
208
|
+
struct partialMatch *rhsBinds,
|
209
|
+
struct joinNode *join,
|
210
|
+
unsigned long hashValue,
|
211
|
+
int side)
|
212
|
+
{
|
213
|
+
unsigned long betaLocation;
|
214
|
+
struct betaMemory *theMemory;
|
215
|
+
|
216
|
+
if (side == LHS)
|
217
|
+
{
|
218
|
+
theMemory = join->leftMemory;
|
219
|
+
thePM->rhsMemory = false;
|
220
|
+
}
|
221
|
+
else
|
222
|
+
{
|
223
|
+
theMemory = join->rightMemory;
|
224
|
+
thePM->rhsMemory = true;
|
225
|
+
}
|
226
|
+
|
227
|
+
thePM->hashValue = hashValue;
|
228
|
+
|
229
|
+
/*================================*/
|
230
|
+
/* Update the node's linked list. */
|
231
|
+
/*================================*/
|
232
|
+
|
233
|
+
betaLocation = hashValue % theMemory->size;
|
234
|
+
|
235
|
+
if (side == LHS)
|
236
|
+
{
|
237
|
+
thePM->nextInMemory = theMemory->beta[betaLocation];
|
238
|
+
if (theMemory->beta[betaLocation] != NULL)
|
239
|
+
{ theMemory->beta[betaLocation]->prevInMemory = thePM; }
|
240
|
+
theMemory->beta[betaLocation] = thePM;
|
241
|
+
}
|
242
|
+
else
|
243
|
+
{
|
244
|
+
if (theMemory->last[betaLocation] != NULL)
|
245
|
+
{
|
246
|
+
theMemory->last[betaLocation]->nextInMemory = thePM;
|
247
|
+
thePM->prevInMemory = theMemory->last[betaLocation];
|
248
|
+
}
|
249
|
+
else
|
250
|
+
{ theMemory->beta[betaLocation] = thePM; }
|
251
|
+
|
252
|
+
theMemory->last[betaLocation] = thePM;
|
253
|
+
}
|
254
|
+
|
255
|
+
theMemory->count++;
|
256
|
+
if (side == LHS)
|
257
|
+
{ join->memoryLeftAdds++; }
|
258
|
+
else
|
259
|
+
{ join->memoryRightAdds++; }
|
260
|
+
|
261
|
+
thePM->owner = join;
|
262
|
+
|
263
|
+
/*======================================*/
|
264
|
+
/* Update the alpha memory linked list. */
|
265
|
+
/*======================================*/
|
266
|
+
|
267
|
+
if (rhsBinds != NULL)
|
268
|
+
{
|
269
|
+
thePM->nextRightChild = rhsBinds->children;
|
270
|
+
if (rhsBinds->children != NULL)
|
271
|
+
{ rhsBinds->children->prevRightChild = thePM; }
|
272
|
+
rhsBinds->children = thePM;
|
273
|
+
thePM->rightParent = rhsBinds;
|
274
|
+
}
|
275
|
+
|
276
|
+
/*=====================================*/
|
277
|
+
/* Update the beta memory linked list. */
|
278
|
+
/*=====================================*/
|
279
|
+
|
280
|
+
if (lhsBinds != NULL)
|
281
|
+
{
|
282
|
+
thePM->nextLeftChild = lhsBinds->children;
|
283
|
+
if (lhsBinds->children != NULL)
|
284
|
+
{ lhsBinds->children->prevLeftChild = thePM; }
|
285
|
+
lhsBinds->children = thePM;
|
286
|
+
thePM->leftParent = lhsBinds;
|
287
|
+
}
|
288
|
+
|
289
|
+
if (! DefruleData(theEnv)->BetaMemoryResizingFlag)
|
290
|
+
{ return; }
|
291
|
+
|
292
|
+
if ((theMemory->size > 1) &&
|
293
|
+
(theMemory->count > (theMemory->size * 11)))
|
294
|
+
{ ResizeBetaMemory(theEnv,theMemory); }
|
295
|
+
}
|
296
|
+
|
297
|
+
/**********************************************************/
|
298
|
+
/* AddBlockedLink: Adds a link between a partial match in */
|
299
|
+
/* the beta memory of a join (with a negated RHS) and a */
|
300
|
+
/* partial match in its right memory that prevents the */
|
301
|
+
/* partial match from being satisfied and propagated to */
|
302
|
+
/* the next join in the rule. */
|
303
|
+
/**********************************************************/
|
304
|
+
void AddBlockedLink(
|
305
|
+
struct partialMatch *thePM,
|
306
|
+
struct partialMatch *rhsBinds)
|
307
|
+
{
|
308
|
+
thePM->marker = rhsBinds;
|
309
|
+
thePM->nextBlocked = rhsBinds->blockList;
|
310
|
+
if (rhsBinds->blockList != NULL)
|
311
|
+
{ rhsBinds->blockList->prevBlocked = thePM; }
|
312
|
+
rhsBinds->blockList = thePM;
|
313
|
+
}
|
314
|
+
|
315
|
+
/*************************************************************/
|
316
|
+
/* RemoveBlockedLink: Removes a link between a partial match */
|
317
|
+
/* in the beta memory of a join (with a negated RHS) and a */
|
318
|
+
/* partial match in its right memory that prevents the */
|
319
|
+
/* partial match from being satisfied and propagated to */
|
320
|
+
/* the next join in the rule. */
|
321
|
+
/*************************************************************/
|
322
|
+
void RemoveBlockedLink(
|
323
|
+
struct partialMatch *thePM)
|
324
|
+
{
|
325
|
+
struct partialMatch *blocker;
|
326
|
+
|
327
|
+
if (thePM->prevBlocked == NULL)
|
328
|
+
{
|
329
|
+
blocker = (struct partialMatch *) thePM->marker;
|
330
|
+
blocker->blockList = thePM->nextBlocked;
|
331
|
+
}
|
332
|
+
else
|
333
|
+
{ thePM->prevBlocked->nextBlocked = thePM->nextBlocked; }
|
334
|
+
|
335
|
+
if (thePM->nextBlocked != NULL)
|
336
|
+
{ thePM->nextBlocked->prevBlocked = thePM->prevBlocked; }
|
337
|
+
|
338
|
+
thePM->nextBlocked = NULL;
|
339
|
+
thePM->prevBlocked = NULL;
|
340
|
+
thePM->marker = NULL;
|
341
|
+
}
|
342
|
+
|
343
|
+
/***********************************/
|
344
|
+
/* UnlinkBetaPMFromNodeAndLineage: */
|
345
|
+
/***********************************/
|
346
|
+
void UnlinkBetaPMFromNodeAndLineage(
|
347
|
+
Environment *theEnv,
|
348
|
+
struct joinNode *join,
|
349
|
+
struct partialMatch *thePM,
|
350
|
+
int side)
|
351
|
+
{
|
352
|
+
unsigned long betaLocation;
|
353
|
+
struct betaMemory *theMemory;
|
354
|
+
|
355
|
+
if (side == LHS)
|
356
|
+
{ theMemory = join->leftMemory; }
|
357
|
+
else
|
358
|
+
{ theMemory = join->rightMemory; }
|
359
|
+
|
360
|
+
/*=============================================*/
|
361
|
+
/* Update the nextInMemory/prevInMemory links. */
|
362
|
+
/*=============================================*/
|
363
|
+
|
364
|
+
theMemory->count--;
|
365
|
+
|
366
|
+
if (side == LHS)
|
367
|
+
{ join->memoryLeftDeletes++; }
|
368
|
+
else
|
369
|
+
{ join->memoryRightDeletes++; }
|
370
|
+
|
371
|
+
betaLocation = thePM->hashValue % theMemory->size;
|
372
|
+
|
373
|
+
if ((side == RHS) &&
|
374
|
+
(theMemory->last[betaLocation] == thePM))
|
375
|
+
{ theMemory->last[betaLocation] = thePM->prevInMemory; }
|
376
|
+
|
377
|
+
if (thePM->prevInMemory == NULL)
|
378
|
+
{
|
379
|
+
betaLocation = thePM->hashValue % theMemory->size;
|
380
|
+
theMemory->beta[betaLocation] = thePM->nextInMemory;
|
381
|
+
}
|
382
|
+
else
|
383
|
+
{ thePM->prevInMemory->nextInMemory = thePM->nextInMemory; }
|
384
|
+
|
385
|
+
if (thePM->nextInMemory != NULL)
|
386
|
+
{ thePM->nextInMemory->prevInMemory = thePM->prevInMemory; }
|
387
|
+
|
388
|
+
thePM->nextInMemory = NULL;
|
389
|
+
thePM->prevInMemory = NULL;
|
390
|
+
|
391
|
+
UnlinkBetaPartialMatchfromAlphaAndBetaLineage(thePM);
|
392
|
+
|
393
|
+
if (! DefruleData(theEnv)->BetaMemoryResizingFlag)
|
394
|
+
{ return; }
|
395
|
+
|
396
|
+
if ((theMemory->count == 0) && (theMemory->size > 1))
|
397
|
+
{ ResetBetaMemory(theEnv,theMemory); }
|
398
|
+
}
|
399
|
+
|
400
|
+
/*************************/
|
401
|
+
/* UnlinkNonLeftLineage: */
|
402
|
+
/*************************/
|
403
|
+
void UnlinkNonLeftLineage(
|
404
|
+
Environment *theEnv,
|
405
|
+
struct joinNode *join,
|
406
|
+
struct partialMatch *thePM,
|
407
|
+
int side)
|
408
|
+
{
|
409
|
+
unsigned long betaLocation;
|
410
|
+
struct betaMemory *theMemory;
|
411
|
+
struct partialMatch *tempPM;
|
412
|
+
|
413
|
+
if (side == LHS)
|
414
|
+
{ theMemory = join->leftMemory; }
|
415
|
+
else
|
416
|
+
{ theMemory = join->rightMemory; }
|
417
|
+
|
418
|
+
/*=============================================*/
|
419
|
+
/* Update the nextInMemory/prevInMemory links. */
|
420
|
+
/*=============================================*/
|
421
|
+
|
422
|
+
theMemory->count--;
|
423
|
+
|
424
|
+
if (side == LHS)
|
425
|
+
{ join->memoryLeftDeletes++; }
|
426
|
+
else
|
427
|
+
{ join->memoryRightDeletes++; }
|
428
|
+
|
429
|
+
betaLocation = thePM->hashValue % theMemory->size;
|
430
|
+
|
431
|
+
if ((side == RHS) &&
|
432
|
+
(theMemory->last[betaLocation] == thePM))
|
433
|
+
{ theMemory->last[betaLocation] = thePM->prevInMemory; }
|
434
|
+
|
435
|
+
if (thePM->prevInMemory == NULL)
|
436
|
+
{
|
437
|
+
betaLocation = thePM->hashValue % theMemory->size;
|
438
|
+
theMemory->beta[betaLocation] = thePM->nextInMemory;
|
439
|
+
}
|
440
|
+
else
|
441
|
+
{ thePM->prevInMemory->nextInMemory = thePM->nextInMemory; }
|
442
|
+
|
443
|
+
if (thePM->nextInMemory != NULL)
|
444
|
+
{ thePM->nextInMemory->prevInMemory = thePM->prevInMemory; }
|
445
|
+
|
446
|
+
/*=========================*/
|
447
|
+
/* Update the alpha lists. */
|
448
|
+
/*=========================*/
|
449
|
+
|
450
|
+
if (thePM->prevRightChild == NULL)
|
451
|
+
{
|
452
|
+
if (thePM->rightParent != NULL)
|
453
|
+
{
|
454
|
+
thePM->rightParent->children = thePM->nextRightChild;
|
455
|
+
if (thePM->nextRightChild != NULL)
|
456
|
+
{
|
457
|
+
thePM->rightParent->children = thePM->nextRightChild;
|
458
|
+
thePM->nextRightChild->rightParent = thePM->rightParent;
|
459
|
+
}
|
460
|
+
}
|
461
|
+
}
|
462
|
+
else
|
463
|
+
{ thePM->prevRightChild->nextRightChild = thePM->nextRightChild; }
|
464
|
+
|
465
|
+
if (thePM->nextRightChild != NULL)
|
466
|
+
{ thePM->nextRightChild->prevRightChild = thePM->prevRightChild; }
|
467
|
+
|
468
|
+
/*===========================*/
|
469
|
+
/* Update the blocked lists. */
|
470
|
+
/*===========================*/
|
471
|
+
|
472
|
+
if (thePM->prevBlocked == NULL)
|
473
|
+
{
|
474
|
+
tempPM = (struct partialMatch *) thePM->marker;
|
475
|
+
|
476
|
+
if (tempPM != NULL)
|
477
|
+
{ tempPM->blockList = thePM->nextBlocked; }
|
478
|
+
}
|
479
|
+
else
|
480
|
+
{ thePM->prevBlocked->nextBlocked = thePM->nextBlocked; }
|
481
|
+
|
482
|
+
if (thePM->nextBlocked != NULL)
|
483
|
+
{ thePM->nextBlocked->prevBlocked = thePM->prevBlocked; }
|
484
|
+
|
485
|
+
if (! DefruleData(theEnv)->BetaMemoryResizingFlag)
|
486
|
+
{ return; }
|
487
|
+
|
488
|
+
if ((theMemory->count == 0) && (theMemory->size > 1))
|
489
|
+
{ ResetBetaMemory(theEnv,theMemory); }
|
490
|
+
}
|
491
|
+
|
492
|
+
/*******************************************************************/
|
493
|
+
/* UnlinkBetaPartialMatchfromAlphaAndBetaLineage: Removes the */
|
494
|
+
/* lineage links from a beta memory partial match. This removes */
|
495
|
+
/* the links between this partial match and its left and right */
|
496
|
+
/* memory parents. It also removes the links between this */
|
497
|
+
/* partial match and any of its children in other beta memories. */
|
498
|
+
/*******************************************************************/
|
499
|
+
static void UnlinkBetaPartialMatchfromAlphaAndBetaLineage(
|
500
|
+
struct partialMatch *thePM)
|
501
|
+
{
|
502
|
+
struct partialMatch *tempPM;
|
503
|
+
|
504
|
+
/*=========================*/
|
505
|
+
/* Update the alpha lists. */
|
506
|
+
/*=========================*/
|
507
|
+
|
508
|
+
if (thePM->prevRightChild == NULL)
|
509
|
+
{
|
510
|
+
if (thePM->rightParent != NULL)
|
511
|
+
{ thePM->rightParent->children = thePM->nextRightChild; }
|
512
|
+
}
|
513
|
+
else
|
514
|
+
{ thePM->prevRightChild->nextRightChild = thePM->nextRightChild; }
|
515
|
+
|
516
|
+
if (thePM->nextRightChild != NULL)
|
517
|
+
{ thePM->nextRightChild->prevRightChild = thePM->prevRightChild; }
|
518
|
+
|
519
|
+
thePM->rightParent = NULL;
|
520
|
+
thePM->nextRightChild = NULL;
|
521
|
+
thePM->prevRightChild = NULL;
|
522
|
+
|
523
|
+
/*========================*/
|
524
|
+
/* Update the beta lists. */
|
525
|
+
/*========================*/
|
526
|
+
|
527
|
+
if (thePM->prevLeftChild == NULL)
|
528
|
+
{
|
529
|
+
if (thePM->leftParent != NULL)
|
530
|
+
{ thePM->leftParent->children = thePM->nextLeftChild; }
|
531
|
+
}
|
532
|
+
else
|
533
|
+
{ thePM->prevLeftChild->nextLeftChild = thePM->nextLeftChild; }
|
534
|
+
|
535
|
+
if (thePM->nextLeftChild != NULL)
|
536
|
+
{ thePM->nextLeftChild->prevLeftChild = thePM->prevLeftChild; }
|
537
|
+
|
538
|
+
thePM->leftParent = NULL;
|
539
|
+
thePM->nextLeftChild = NULL;
|
540
|
+
thePM->prevLeftChild = NULL;
|
541
|
+
|
542
|
+
/*===========================*/
|
543
|
+
/* Update the blocked lists. */
|
544
|
+
/*===========================*/
|
545
|
+
|
546
|
+
if (thePM->prevBlocked == NULL)
|
547
|
+
{
|
548
|
+
tempPM = (struct partialMatch *) thePM->marker;
|
549
|
+
|
550
|
+
if (tempPM != NULL)
|
551
|
+
{ tempPM->blockList = thePM->nextBlocked; }
|
552
|
+
}
|
553
|
+
else
|
554
|
+
{ thePM->prevBlocked->nextBlocked = thePM->nextBlocked; }
|
555
|
+
|
556
|
+
if (thePM->nextBlocked != NULL)
|
557
|
+
{ thePM->nextBlocked->prevBlocked = thePM->prevBlocked; }
|
558
|
+
|
559
|
+
thePM->marker = NULL;
|
560
|
+
thePM->nextBlocked = NULL;
|
561
|
+
thePM->prevBlocked = NULL;
|
562
|
+
|
563
|
+
/*===============================================*/
|
564
|
+
/* Remove parent reference from the child links. */
|
565
|
+
/*===============================================*/
|
566
|
+
|
567
|
+
if (thePM->children != NULL)
|
568
|
+
{
|
569
|
+
if (thePM->rhsMemory)
|
570
|
+
{
|
571
|
+
for (tempPM = thePM->children; tempPM != NULL; tempPM = tempPM->nextRightChild)
|
572
|
+
{ tempPM->rightParent = NULL; }
|
573
|
+
}
|
574
|
+
else
|
575
|
+
{
|
576
|
+
for (tempPM = thePM->children; tempPM != NULL; tempPM = tempPM->nextLeftChild)
|
577
|
+
{ tempPM->leftParent = NULL; }
|
578
|
+
}
|
579
|
+
|
580
|
+
thePM->children = NULL;
|
581
|
+
}
|
582
|
+
}
|
583
|
+
|
584
|
+
/********************************************************/
|
585
|
+
/* MergePartialMatches: Merges two partial matches. The */
|
586
|
+
/* second match should either be NULL (indicating a */
|
587
|
+
/* negated CE) or contain a single match. */
|
588
|
+
/********************************************************/
|
589
|
+
struct partialMatch *MergePartialMatches(
|
590
|
+
Environment *theEnv,
|
591
|
+
struct partialMatch *lhsBind,
|
592
|
+
struct partialMatch *rhsBind)
|
593
|
+
{
|
594
|
+
struct partialMatch *linker;
|
595
|
+
static struct partialMatch mergeTemplate = { 1 }; /* betaMemory is true, remainder are 0 or NULL */
|
596
|
+
|
597
|
+
/*=================================*/
|
598
|
+
/* Allocate the new partial match. */
|
599
|
+
/*=================================*/
|
600
|
+
|
601
|
+
linker = get_var_struct(theEnv,partialMatch,sizeof(struct genericMatch) * lhsBind->bcount);
|
602
|
+
|
603
|
+
/*============================================*/
|
604
|
+
/* Set the flags to their appropriate values. */
|
605
|
+
/*============================================*/
|
606
|
+
|
607
|
+
memcpy(linker,&mergeTemplate,sizeof(struct partialMatch) - sizeof(struct genericMatch));
|
608
|
+
|
609
|
+
linker->deleting = false;
|
610
|
+
linker->bcount = lhsBind->bcount + 1;
|
611
|
+
|
612
|
+
/*========================================================*/
|
613
|
+
/* Copy the bindings of the partial match being extended. */
|
614
|
+
/*========================================================*/
|
615
|
+
|
616
|
+
memcpy(linker->binds,lhsBind->binds,sizeof(struct genericMatch) * lhsBind->bcount);
|
617
|
+
|
618
|
+
/*===================================*/
|
619
|
+
/* Add the binding of the rhs match. */
|
620
|
+
/*===================================*/
|
621
|
+
|
622
|
+
if (rhsBind == NULL)
|
623
|
+
{ linker->binds[lhsBind->bcount].gm.theValue = NULL; }
|
624
|
+
else
|
625
|
+
{ linker->binds[lhsBind->bcount].gm.theValue = rhsBind->binds[0].gm.theValue; }
|
626
|
+
|
627
|
+
return linker;
|
628
|
+
}
|
629
|
+
|
630
|
+
/*******************************************************************/
|
631
|
+
/* InitializePatternHeader: Initializes a pattern header structure */
|
632
|
+
/* (used by the fact and instance pattern matchers). */
|
633
|
+
/*******************************************************************/
|
634
|
+
void InitializePatternHeader(
|
635
|
+
Environment *theEnv,
|
636
|
+
struct patternNodeHeader *theHeader)
|
637
|
+
{
|
638
|
+
#if MAC_XCD
|
639
|
+
#pragma unused(theEnv)
|
640
|
+
#endif
|
641
|
+
theHeader->firstHash = NULL;
|
642
|
+
theHeader->lastHash = NULL;
|
643
|
+
theHeader->entryJoin = NULL;
|
644
|
+
theHeader->rightHash = NULL;
|
645
|
+
theHeader->singlefieldNode = false;
|
646
|
+
theHeader->multifieldNode = false;
|
647
|
+
theHeader->stopNode = false;
|
648
|
+
#if (! RUN_TIME)
|
649
|
+
theHeader->initialize = true;
|
650
|
+
#else
|
651
|
+
theHeader->initialize = false;
|
652
|
+
#endif
|
653
|
+
theHeader->marked = false;
|
654
|
+
theHeader->beginSlot = false;
|
655
|
+
theHeader->endSlot = false;
|
656
|
+
theHeader->selector = false;
|
657
|
+
}
|
658
|
+
|
659
|
+
/******************************************************************/
|
660
|
+
/* CreateAlphaMatch: Given a pointer to an entity (such as a fact */
|
661
|
+
/* or instance) which matched a pattern, this function creates */
|
662
|
+
/* a partial match suitable for storing in the alpha memory of */
|
663
|
+
/* the pattern network. Note that the multifield markers which */
|
664
|
+
/* are passed as a calling argument are copied (thus the caller */
|
665
|
+
/* is still responsible for freeing these data structures). */
|
666
|
+
/******************************************************************/
|
667
|
+
struct partialMatch *CreateAlphaMatch(
|
668
|
+
Environment *theEnv,
|
669
|
+
void *theEntity,
|
670
|
+
struct multifieldMarker *markers,
|
671
|
+
struct patternNodeHeader *theHeader,
|
672
|
+
unsigned long hashOffset)
|
673
|
+
{
|
674
|
+
struct partialMatch *theMatch;
|
675
|
+
struct alphaMatch *afbtemp;
|
676
|
+
unsigned long hashValue;
|
677
|
+
struct alphaMemoryHash *theAlphaMemory;
|
678
|
+
|
679
|
+
/*==================================================*/
|
680
|
+
/* Create the alpha match and intialize its values. */
|
681
|
+
/*==================================================*/
|
682
|
+
|
683
|
+
theMatch = get_struct(theEnv,partialMatch);
|
684
|
+
InitializePMLinks(theMatch);
|
685
|
+
theMatch->betaMemory = false;
|
686
|
+
theMatch->busy = false;
|
687
|
+
theMatch->deleting = false;
|
688
|
+
theMatch->bcount = 1;
|
689
|
+
theMatch->hashValue = hashOffset;
|
690
|
+
|
691
|
+
afbtemp = get_struct(theEnv,alphaMatch);
|
692
|
+
afbtemp->next = NULL;
|
693
|
+
afbtemp->matchingItem = (struct patternEntity *) theEntity;
|
694
|
+
|
695
|
+
if (markers != NULL)
|
696
|
+
{ afbtemp->markers = CopyMultifieldMarkers(theEnv,markers); }
|
697
|
+
else
|
698
|
+
{ afbtemp->markers = NULL; }
|
699
|
+
|
700
|
+
theMatch->binds[0].gm.theMatch = afbtemp;
|
701
|
+
|
702
|
+
/*============================================*/
|
703
|
+
/* Find the alpha memory of the pattern node. */
|
704
|
+
/*============================================*/
|
705
|
+
|
706
|
+
hashValue = AlphaMemoryHashValue(theHeader,hashOffset);
|
707
|
+
theAlphaMemory = FindAlphaMemory(theEnv,theHeader,hashValue);
|
708
|
+
afbtemp->bucket = hashValue;
|
709
|
+
|
710
|
+
/*============================================*/
|
711
|
+
/* Create an alpha memory if it wasn't found. */
|
712
|
+
/*============================================*/
|
713
|
+
|
714
|
+
if (theAlphaMemory == NULL)
|
715
|
+
{
|
716
|
+
theAlphaMemory = get_struct(theEnv,alphaMemoryHash);
|
717
|
+
theAlphaMemory->bucket = hashValue;
|
718
|
+
theAlphaMemory->owner = theHeader;
|
719
|
+
theAlphaMemory->alphaMemory = NULL;
|
720
|
+
theAlphaMemory->endOfQueue = NULL;
|
721
|
+
theAlphaMemory->nextHash = NULL;
|
722
|
+
|
723
|
+
theAlphaMemory->next = DefruleData(theEnv)->AlphaMemoryTable[hashValue];
|
724
|
+
if (theAlphaMemory->next != NULL)
|
725
|
+
{ theAlphaMemory->next->prev = theAlphaMemory; }
|
726
|
+
|
727
|
+
theAlphaMemory->prev = NULL;
|
728
|
+
DefruleData(theEnv)->AlphaMemoryTable[hashValue] = theAlphaMemory;
|
729
|
+
|
730
|
+
if (theHeader->firstHash == NULL)
|
731
|
+
{
|
732
|
+
theHeader->firstHash = theAlphaMemory;
|
733
|
+
theHeader->lastHash = theAlphaMemory;
|
734
|
+
theAlphaMemory->prevHash = NULL;
|
735
|
+
}
|
736
|
+
else
|
737
|
+
{
|
738
|
+
theHeader->lastHash->nextHash = theAlphaMemory;
|
739
|
+
theAlphaMemory->prevHash = theHeader->lastHash;
|
740
|
+
theHeader->lastHash = theAlphaMemory;
|
741
|
+
}
|
742
|
+
}
|
743
|
+
|
744
|
+
/*====================================*/
|
745
|
+
/* Store the alpha match in the alpha */
|
746
|
+
/* memory of the pattern node. */
|
747
|
+
/*====================================*/
|
748
|
+
|
749
|
+
theMatch->prevInMemory = theAlphaMemory->endOfQueue;
|
750
|
+
if (theAlphaMemory->endOfQueue == NULL)
|
751
|
+
{
|
752
|
+
theAlphaMemory->alphaMemory = theMatch;
|
753
|
+
theAlphaMemory->endOfQueue = theMatch;
|
754
|
+
}
|
755
|
+
else
|
756
|
+
{
|
757
|
+
theAlphaMemory->endOfQueue->nextInMemory = theMatch;
|
758
|
+
theAlphaMemory->endOfQueue = theMatch;
|
759
|
+
}
|
760
|
+
|
761
|
+
/*===================================================*/
|
762
|
+
/* Return a pointer to the newly create alpha match. */
|
763
|
+
/*===================================================*/
|
764
|
+
|
765
|
+
return(theMatch);
|
766
|
+
}
|
767
|
+
|
768
|
+
/*******************************************/
|
769
|
+
/* CopyMultifieldMarkers: Copies a list of */
|
770
|
+
/* multifieldMarker data structures. */
|
771
|
+
/*******************************************/
|
772
|
+
struct multifieldMarker *CopyMultifieldMarkers(
|
773
|
+
Environment *theEnv,
|
774
|
+
struct multifieldMarker *theMarkers)
|
775
|
+
{
|
776
|
+
struct multifieldMarker *head = NULL, *lastMark = NULL, *newMark;
|
777
|
+
|
778
|
+
while (theMarkers != NULL)
|
779
|
+
{
|
780
|
+
newMark = get_struct(theEnv,multifieldMarker);
|
781
|
+
newMark->next = NULL;
|
782
|
+
newMark->whichField = theMarkers->whichField;
|
783
|
+
newMark->where = theMarkers->where;
|
784
|
+
newMark->startPosition = theMarkers->startPosition;
|
785
|
+
newMark->range = theMarkers->range;
|
786
|
+
|
787
|
+
if (lastMark == NULL)
|
788
|
+
{ head = newMark; }
|
789
|
+
else
|
790
|
+
{ lastMark->next = newMark; }
|
791
|
+
lastMark = newMark;
|
792
|
+
|
793
|
+
theMarkers = theMarkers->next;
|
794
|
+
}
|
795
|
+
|
796
|
+
return(head);
|
797
|
+
}
|
798
|
+
|
799
|
+
/***************************************************************/
|
800
|
+
/* FlushAlphaBetaMemory: Returns all partial matches in a list */
|
801
|
+
/* of partial matches either directly to the pool of free */
|
802
|
+
/* memory or to the list of GarbagePartialMatches. Partial */
|
803
|
+
/* matches stored in alpha memories must be placed on the */
|
804
|
+
/* list of GarbagePartialMatches. */
|
805
|
+
/***************************************************************/
|
806
|
+
void FlushAlphaBetaMemory(
|
807
|
+
Environment *theEnv,
|
808
|
+
struct partialMatch *pfl)
|
809
|
+
{
|
810
|
+
struct partialMatch *pfltemp;
|
811
|
+
|
812
|
+
while (pfl != NULL)
|
813
|
+
{
|
814
|
+
pfltemp = pfl->nextInMemory;
|
815
|
+
|
816
|
+
UnlinkBetaPartialMatchfromAlphaAndBetaLineage(pfl);
|
817
|
+
ReturnPartialMatch(theEnv,pfl);
|
818
|
+
|
819
|
+
pfl = pfltemp;
|
820
|
+
}
|
821
|
+
}
|
822
|
+
|
823
|
+
/*****************************************************************/
|
824
|
+
/* DestroyAlphaBetaMemory: Returns all partial matches in a list */
|
825
|
+
/* of partial matches directly to the pool of free memory. */
|
826
|
+
/*****************************************************************/
|
827
|
+
void DestroyAlphaBetaMemory(
|
828
|
+
Environment *theEnv,
|
829
|
+
struct partialMatch *pfl)
|
830
|
+
{
|
831
|
+
struct partialMatch *pfltemp;
|
832
|
+
|
833
|
+
while (pfl != NULL)
|
834
|
+
{
|
835
|
+
pfltemp = pfl->nextInMemory;
|
836
|
+
DestroyPartialMatch(theEnv,pfl);
|
837
|
+
pfl = pfltemp;
|
838
|
+
}
|
839
|
+
}
|
840
|
+
|
841
|
+
/******************************************************/
|
842
|
+
/* FindEntityInPartialMatch: Searches for a specified */
|
843
|
+
/* data entity in a partial match. */
|
844
|
+
/******************************************************/
|
845
|
+
bool FindEntityInPartialMatch(
|
846
|
+
struct patternEntity *theEntity,
|
847
|
+
struct partialMatch *thePartialMatch)
|
848
|
+
{
|
849
|
+
unsigned short i;
|
850
|
+
|
851
|
+
for (i = 0 ; i < thePartialMatch->bcount; i++)
|
852
|
+
{
|
853
|
+
if (thePartialMatch->binds[i].gm.theMatch == NULL) continue;
|
854
|
+
if (thePartialMatch->binds[i].gm.theMatch->matchingItem == theEntity)
|
855
|
+
{ return true; }
|
856
|
+
}
|
857
|
+
|
858
|
+
return false;
|
859
|
+
}
|
860
|
+
|
861
|
+
/***********************************************************************/
|
862
|
+
/* GetPatternNumberFromJoin: Given a pointer to a join associated with */
|
863
|
+
/* a pattern CE, returns an integer representing the position of the */
|
864
|
+
/* pattern CE in the rule (e.g. first, second, third). */
|
865
|
+
/***********************************************************************/
|
866
|
+
int GetPatternNumberFromJoin(
|
867
|
+
struct joinNode *joinPtr)
|
868
|
+
{
|
869
|
+
int whichOne = 0;
|
870
|
+
|
871
|
+
while (joinPtr != NULL)
|
872
|
+
{
|
873
|
+
if (joinPtr->joinFromTheRight)
|
874
|
+
{ joinPtr = (struct joinNode *) joinPtr->rightSideEntryStructure; }
|
875
|
+
else
|
876
|
+
{
|
877
|
+
whichOne++;
|
878
|
+
joinPtr = joinPtr->lastLevel;
|
879
|
+
}
|
880
|
+
}
|
881
|
+
|
882
|
+
return(whichOne);
|
883
|
+
}
|
884
|
+
|
885
|
+
/************************************************************************/
|
886
|
+
/* TraceErrorToRule: Prints an error message when a error occurs as the */
|
887
|
+
/* result of evaluating an expression in the pattern network. Used to */
|
888
|
+
/* indicate which rule caused the problem. */
|
889
|
+
/************************************************************************/
|
890
|
+
void TraceErrorToRule(
|
891
|
+
Environment *theEnv,
|
892
|
+
struct joinNode *joinPtr,
|
893
|
+
const char *indentSpaces)
|
894
|
+
{
|
895
|
+
int patternCount;
|
896
|
+
|
897
|
+
MarkRuleNetwork(theEnv,0);
|
898
|
+
|
899
|
+
patternCount = CountPriorPatterns(joinPtr->lastLevel) + 1;
|
900
|
+
|
901
|
+
TraceErrorToRuleDriver(theEnv,joinPtr,indentSpaces,patternCount,false);
|
902
|
+
|
903
|
+
MarkRuleNetwork(theEnv,0);
|
904
|
+
}
|
905
|
+
|
906
|
+
/**************************************************************/
|
907
|
+
/* TraceErrorToRuleDriver: Driver code for printing out which */
|
908
|
+
/* rule caused a pattern or join network error. */
|
909
|
+
/**************************************************************/
|
910
|
+
static void TraceErrorToRuleDriver(
|
911
|
+
Environment *theEnv,
|
912
|
+
struct joinNode *joinPtr,
|
913
|
+
const char *indentSpaces,
|
914
|
+
int priorRightJoinPatterns,
|
915
|
+
bool enteredJoinFromRight)
|
916
|
+
{
|
917
|
+
const char *name;
|
918
|
+
int priorPatternCount;
|
919
|
+
struct joinLink *theLinks;
|
920
|
+
|
921
|
+
if ((joinPtr->joinFromTheRight) && enteredJoinFromRight)
|
922
|
+
{ priorPatternCount = CountPriorPatterns(joinPtr->lastLevel); }
|
923
|
+
else
|
924
|
+
{ priorPatternCount = 0; }
|
925
|
+
|
926
|
+
if (joinPtr->marked)
|
927
|
+
{ /* Do Nothing */ }
|
928
|
+
else if (joinPtr->ruleToActivate != NULL)
|
929
|
+
{
|
930
|
+
joinPtr->marked = 1;
|
931
|
+
name = DefruleName(joinPtr->ruleToActivate);
|
932
|
+
WriteString(theEnv,STDERR,indentSpaces);
|
933
|
+
|
934
|
+
WriteString(theEnv,STDERR,"Of pattern #");
|
935
|
+
WriteInteger(theEnv,STDERR,priorRightJoinPatterns+priorPatternCount);
|
936
|
+
WriteString(theEnv,STDERR," in rule ");
|
937
|
+
WriteString(theEnv,STDERR,name);
|
938
|
+
WriteString(theEnv,STDERR,"\n");
|
939
|
+
}
|
940
|
+
else
|
941
|
+
{
|
942
|
+
joinPtr->marked = 1;
|
943
|
+
|
944
|
+
theLinks = joinPtr->nextLinks;
|
945
|
+
while (theLinks != NULL)
|
946
|
+
{
|
947
|
+
TraceErrorToRuleDriver(theEnv,theLinks->join,indentSpaces,
|
948
|
+
priorRightJoinPatterns+priorPatternCount,
|
949
|
+
(theLinks->enterDirection == RHS));
|
950
|
+
theLinks = theLinks->next;
|
951
|
+
}
|
952
|
+
}
|
953
|
+
}
|
954
|
+
|
955
|
+
/***********************/
|
956
|
+
/* CountPriorPatterns: */
|
957
|
+
/***********************/
|
958
|
+
static int CountPriorPatterns(
|
959
|
+
struct joinNode *joinPtr)
|
960
|
+
{
|
961
|
+
int count = 0;
|
962
|
+
|
963
|
+
while (joinPtr != NULL)
|
964
|
+
{
|
965
|
+
if (joinPtr->joinFromTheRight)
|
966
|
+
{ count += CountPriorPatterns((struct joinNode *) joinPtr->rightSideEntryStructure); }
|
967
|
+
else
|
968
|
+
{ count++; }
|
969
|
+
|
970
|
+
joinPtr = joinPtr->lastLevel;
|
971
|
+
}
|
972
|
+
|
973
|
+
return(count);
|
974
|
+
}
|
975
|
+
|
976
|
+
/********************************************************/
|
977
|
+
/* MarkRuleNetwork: Sets the marked flag in each of the */
|
978
|
+
/* joins in the join network to the specified value. */
|
979
|
+
/********************************************************/
|
980
|
+
void MarkRuleNetwork(
|
981
|
+
Environment *theEnv,
|
982
|
+
bool value)
|
983
|
+
{
|
984
|
+
Defrule *rulePtr, *disjunctPtr;
|
985
|
+
struct joinNode *joinPtr;
|
986
|
+
Defmodule *modulePtr;
|
987
|
+
|
988
|
+
/*===========================*/
|
989
|
+
/* Loop through each module. */
|
990
|
+
/*===========================*/
|
991
|
+
|
992
|
+
SaveCurrentModule(theEnv);
|
993
|
+
for (modulePtr = GetNextDefmodule(theEnv,NULL);
|
994
|
+
modulePtr != NULL;
|
995
|
+
modulePtr = GetNextDefmodule(theEnv,modulePtr))
|
996
|
+
{
|
997
|
+
SetCurrentModule(theEnv,modulePtr);
|
998
|
+
|
999
|
+
/*=========================*/
|
1000
|
+
/* Loop through each rule. */
|
1001
|
+
/*=========================*/
|
1002
|
+
|
1003
|
+
rulePtr = GetNextDefrule(theEnv,NULL);
|
1004
|
+
while (rulePtr != NULL)
|
1005
|
+
{
|
1006
|
+
/*=============================*/
|
1007
|
+
/* Mark each join for the rule */
|
1008
|
+
/* with the specified value. */
|
1009
|
+
/*=============================*/
|
1010
|
+
|
1011
|
+
for (disjunctPtr = rulePtr; disjunctPtr != NULL; disjunctPtr = disjunctPtr->disjunct)
|
1012
|
+
{
|
1013
|
+
joinPtr = disjunctPtr->lastJoin;
|
1014
|
+
MarkRuleJoins(joinPtr,value);
|
1015
|
+
}
|
1016
|
+
|
1017
|
+
/*===========================*/
|
1018
|
+
/* Move on to the next rule. */
|
1019
|
+
/*===========================*/
|
1020
|
+
|
1021
|
+
rulePtr = GetNextDefrule(theEnv,rulePtr);
|
1022
|
+
}
|
1023
|
+
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
RestoreCurrentModule(theEnv);
|
1027
|
+
}
|
1028
|
+
|
1029
|
+
/******************/
|
1030
|
+
/* MarkRuleJoins: */
|
1031
|
+
/******************/
|
1032
|
+
void MarkRuleJoins(
|
1033
|
+
struct joinNode *joinPtr,
|
1034
|
+
bool value)
|
1035
|
+
{
|
1036
|
+
while (joinPtr != NULL)
|
1037
|
+
{
|
1038
|
+
if (joinPtr->joinFromTheRight)
|
1039
|
+
{ MarkRuleJoins((struct joinNode *) joinPtr->rightSideEntryStructure,value); }
|
1040
|
+
|
1041
|
+
joinPtr->marked = value;
|
1042
|
+
joinPtr = joinPtr->lastLevel;
|
1043
|
+
}
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
/*****************************************/
|
1047
|
+
/* GetAlphaMemory: Retrieves the list of */
|
1048
|
+
/* matches from an alpha memory. */
|
1049
|
+
/*****************************************/
|
1050
|
+
struct partialMatch *GetAlphaMemory(
|
1051
|
+
Environment *theEnv,
|
1052
|
+
struct patternNodeHeader *theHeader,
|
1053
|
+
unsigned long hashOffset)
|
1054
|
+
{
|
1055
|
+
struct alphaMemoryHash *theAlphaMemory;
|
1056
|
+
unsigned long hashValue;
|
1057
|
+
|
1058
|
+
hashValue = AlphaMemoryHashValue(theHeader,hashOffset);
|
1059
|
+
theAlphaMemory = FindAlphaMemory(theEnv,theHeader,hashValue);
|
1060
|
+
|
1061
|
+
if (theAlphaMemory == NULL)
|
1062
|
+
{ return NULL; }
|
1063
|
+
|
1064
|
+
return theAlphaMemory->alphaMemory;
|
1065
|
+
}
|
1066
|
+
|
1067
|
+
/*****************************************/
|
1068
|
+
/* GetLeftBetaMemory: Retrieves the list */
|
1069
|
+
/* of matches from a beta memory. */
|
1070
|
+
/*****************************************/
|
1071
|
+
struct partialMatch *GetLeftBetaMemory(
|
1072
|
+
struct joinNode *theJoin,
|
1073
|
+
unsigned long hashValue)
|
1074
|
+
{
|
1075
|
+
unsigned long betaLocation;
|
1076
|
+
|
1077
|
+
betaLocation = hashValue % theJoin->leftMemory->size;
|
1078
|
+
|
1079
|
+
return theJoin->leftMemory->beta[betaLocation];
|
1080
|
+
}
|
1081
|
+
|
1082
|
+
/******************************************/
|
1083
|
+
/* GetRightBetaMemory: Retrieves the list */
|
1084
|
+
/* of matches from a beta memory. */
|
1085
|
+
/******************************************/
|
1086
|
+
struct partialMatch *GetRightBetaMemory(
|
1087
|
+
struct joinNode *theJoin,
|
1088
|
+
unsigned long hashValue)
|
1089
|
+
{
|
1090
|
+
unsigned long betaLocation;
|
1091
|
+
|
1092
|
+
betaLocation = hashValue % theJoin->rightMemory->size;
|
1093
|
+
|
1094
|
+
return theJoin->rightMemory->beta[betaLocation];
|
1095
|
+
}
|
1096
|
+
|
1097
|
+
/***************************************/
|
1098
|
+
/* ReturnLeftMemory: Sets the contents */
|
1099
|
+
/* of a beta memory to NULL. */
|
1100
|
+
/***************************************/
|
1101
|
+
void ReturnLeftMemory(
|
1102
|
+
Environment *theEnv,
|
1103
|
+
struct joinNode *theJoin)
|
1104
|
+
{
|
1105
|
+
if (theJoin->leftMemory == NULL) return;
|
1106
|
+
genfree(theEnv,theJoin->leftMemory->beta,sizeof(struct partialMatch *) * theJoin->leftMemory->size);
|
1107
|
+
rtn_struct(theEnv,betaMemory,theJoin->leftMemory);
|
1108
|
+
theJoin->leftMemory = NULL;
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
/***************************************/
|
1112
|
+
/* ReturnRightMemory: Sets the contents */
|
1113
|
+
/* of a beta memory to NULL. */
|
1114
|
+
/***************************************/
|
1115
|
+
void ReturnRightMemory(
|
1116
|
+
Environment *theEnv,
|
1117
|
+
struct joinNode *theJoin)
|
1118
|
+
{
|
1119
|
+
if (theJoin->rightMemory == NULL) return;
|
1120
|
+
genfree(theEnv,theJoin->rightMemory->beta,sizeof(struct partialMatch *) * theJoin->rightMemory->size);
|
1121
|
+
genfree(theEnv,theJoin->rightMemory->last,sizeof(struct partialMatch *) * theJoin->rightMemory->size);
|
1122
|
+
rtn_struct(theEnv,betaMemory,theJoin->rightMemory);
|
1123
|
+
theJoin->rightMemory = NULL;
|
1124
|
+
}
|
1125
|
+
|
1126
|
+
/****************************************************************/
|
1127
|
+
/* DestroyBetaMemory: Destroys the contents of a beta memory in */
|
1128
|
+
/* preperation for the deallocation of a join. Destroying is */
|
1129
|
+
/* performed when the environment is being deallocated and it */
|
1130
|
+
/* is not necessary to leave the environment in a consistent */
|
1131
|
+
/* state (as it would be if just a single rule were being */
|
1132
|
+
/* deleted). */
|
1133
|
+
/****************************************************************/
|
1134
|
+
void DestroyBetaMemory(
|
1135
|
+
Environment *theEnv,
|
1136
|
+
struct joinNode *theJoin,
|
1137
|
+
int side)
|
1138
|
+
{
|
1139
|
+
unsigned long i;
|
1140
|
+
|
1141
|
+
if (side == LHS)
|
1142
|
+
{
|
1143
|
+
if (theJoin->leftMemory == NULL) return;
|
1144
|
+
|
1145
|
+
for (i = 0; i < theJoin->leftMemory->size; i++)
|
1146
|
+
{ DestroyAlphaBetaMemory(theEnv,theJoin->leftMemory->beta[i]); }
|
1147
|
+
}
|
1148
|
+
else
|
1149
|
+
{
|
1150
|
+
if (theJoin->rightMemory == NULL) return;
|
1151
|
+
|
1152
|
+
for (i = 0; i < theJoin->rightMemory->size; i++)
|
1153
|
+
{ DestroyAlphaBetaMemory(theEnv,theJoin->rightMemory->beta[i]); }
|
1154
|
+
}
|
1155
|
+
}
|
1156
|
+
|
1157
|
+
/*************************************************************/
|
1158
|
+
/* FlushBetaMemory: Flushes the contents of a beta memory in */
|
1159
|
+
/* preperation for the deallocation of a join. Flushing */
|
1160
|
+
/* is performed when the partial matches in the beta */
|
1161
|
+
/* memory may still be in use because the environment will */
|
1162
|
+
/* remain active. */
|
1163
|
+
/*************************************************************/
|
1164
|
+
void FlushBetaMemory(
|
1165
|
+
Environment *theEnv,
|
1166
|
+
struct joinNode *theJoin,
|
1167
|
+
int side)
|
1168
|
+
{
|
1169
|
+
unsigned long i;
|
1170
|
+
|
1171
|
+
if (side == LHS)
|
1172
|
+
{
|
1173
|
+
if (theJoin->leftMemory == NULL) return;
|
1174
|
+
|
1175
|
+
for (i = 0; i < theJoin->leftMemory->size; i++)
|
1176
|
+
{ FlushAlphaBetaMemory(theEnv,theJoin->leftMemory->beta[i]); }
|
1177
|
+
}
|
1178
|
+
else
|
1179
|
+
{
|
1180
|
+
if (theJoin->rightMemory == NULL) return;
|
1181
|
+
|
1182
|
+
for (i = 0; i < theJoin->rightMemory->size; i++)
|
1183
|
+
{ FlushAlphaBetaMemory(theEnv,theJoin->rightMemory->beta[i]); }
|
1184
|
+
}
|
1185
|
+
}
|
1186
|
+
|
1187
|
+
/***********************/
|
1188
|
+
/* BetaMemoryNotEmpty: */
|
1189
|
+
/***********************/
|
1190
|
+
bool BetaMemoryNotEmpty(
|
1191
|
+
struct joinNode *theJoin)
|
1192
|
+
{
|
1193
|
+
if (theJoin->leftMemory != NULL)
|
1194
|
+
{
|
1195
|
+
if (theJoin->leftMemory->count > 0)
|
1196
|
+
{ return true; }
|
1197
|
+
}
|
1198
|
+
|
1199
|
+
if (theJoin->rightMemory != NULL)
|
1200
|
+
{
|
1201
|
+
if (theJoin->rightMemory->count > 0)
|
1202
|
+
{ return true; }
|
1203
|
+
}
|
1204
|
+
|
1205
|
+
return false;
|
1206
|
+
}
|
1207
|
+
|
1208
|
+
/*********************************************/
|
1209
|
+
/* RemoveAlphaMemoryMatches: Removes matches */
|
1210
|
+
/* from an alpha memory. */
|
1211
|
+
/*********************************************/
|
1212
|
+
void RemoveAlphaMemoryMatches(
|
1213
|
+
Environment *theEnv,
|
1214
|
+
struct patternNodeHeader *theHeader,
|
1215
|
+
struct partialMatch *theMatch,
|
1216
|
+
struct alphaMatch *theAlphaMatch)
|
1217
|
+
{
|
1218
|
+
struct alphaMemoryHash *theAlphaMemory = NULL;
|
1219
|
+
unsigned long hashValue;
|
1220
|
+
|
1221
|
+
if ((theMatch->prevInMemory == NULL) || (theMatch->nextInMemory == NULL))
|
1222
|
+
{
|
1223
|
+
hashValue = theAlphaMatch->bucket;
|
1224
|
+
theAlphaMemory = FindAlphaMemory(theEnv,theHeader,hashValue);
|
1225
|
+
}
|
1226
|
+
|
1227
|
+
if (theMatch->prevInMemory != NULL)
|
1228
|
+
{ theMatch->prevInMemory->nextInMemory = theMatch->nextInMemory; }
|
1229
|
+
else
|
1230
|
+
{ theAlphaMemory->alphaMemory = theMatch->nextInMemory; }
|
1231
|
+
|
1232
|
+
if (theMatch->nextInMemory != NULL)
|
1233
|
+
{ theMatch->nextInMemory->prevInMemory = theMatch->prevInMemory; }
|
1234
|
+
else
|
1235
|
+
{ theAlphaMemory->endOfQueue = theMatch->prevInMemory; }
|
1236
|
+
|
1237
|
+
/*====================================*/
|
1238
|
+
/* Add the match to the garbage list. */
|
1239
|
+
/*====================================*/
|
1240
|
+
|
1241
|
+
theMatch->nextInMemory = EngineData(theEnv)->GarbagePartialMatches;
|
1242
|
+
EngineData(theEnv)->GarbagePartialMatches = theMatch;
|
1243
|
+
|
1244
|
+
if ((theAlphaMemory != NULL) && (theAlphaMemory->alphaMemory == NULL))
|
1245
|
+
{ UnlinkAlphaMemory(theEnv,theHeader,theAlphaMemory); }
|
1246
|
+
}
|
1247
|
+
|
1248
|
+
/***********************/
|
1249
|
+
/* DestroyAlphaMemory: */
|
1250
|
+
/***********************/
|
1251
|
+
void DestroyAlphaMemory(
|
1252
|
+
Environment *theEnv,
|
1253
|
+
struct patternNodeHeader *theHeader,
|
1254
|
+
bool unlink)
|
1255
|
+
{
|
1256
|
+
struct alphaMemoryHash *theAlphaMemory, *tempMemory;
|
1257
|
+
|
1258
|
+
theAlphaMemory = theHeader->firstHash;
|
1259
|
+
|
1260
|
+
while (theAlphaMemory != NULL)
|
1261
|
+
{
|
1262
|
+
tempMemory = theAlphaMemory->nextHash;
|
1263
|
+
DestroyAlphaBetaMemory(theEnv,theAlphaMemory->alphaMemory);
|
1264
|
+
if (unlink)
|
1265
|
+
{ UnlinkAlphaMemoryBucketSiblings(theEnv,theAlphaMemory); }
|
1266
|
+
rtn_struct(theEnv,alphaMemoryHash,theAlphaMemory);
|
1267
|
+
theAlphaMemory = tempMemory;
|
1268
|
+
}
|
1269
|
+
|
1270
|
+
theHeader->firstHash = NULL;
|
1271
|
+
theHeader->lastHash = NULL;
|
1272
|
+
}
|
1273
|
+
|
1274
|
+
/*********************/
|
1275
|
+
/* FlushAlphaMemory: */
|
1276
|
+
/*********************/
|
1277
|
+
void FlushAlphaMemory(
|
1278
|
+
Environment *theEnv,
|
1279
|
+
struct patternNodeHeader *theHeader)
|
1280
|
+
{
|
1281
|
+
struct alphaMemoryHash *theAlphaMemory, *tempMemory;
|
1282
|
+
|
1283
|
+
theAlphaMemory = theHeader->firstHash;
|
1284
|
+
|
1285
|
+
while (theAlphaMemory != NULL)
|
1286
|
+
{
|
1287
|
+
tempMemory = theAlphaMemory->nextHash;
|
1288
|
+
FlushAlphaBetaMemory(theEnv,theAlphaMemory->alphaMemory);
|
1289
|
+
UnlinkAlphaMemoryBucketSiblings(theEnv,theAlphaMemory);
|
1290
|
+
rtn_struct(theEnv,alphaMemoryHash,theAlphaMemory);
|
1291
|
+
theAlphaMemory = tempMemory;
|
1292
|
+
}
|
1293
|
+
|
1294
|
+
theHeader->firstHash = NULL;
|
1295
|
+
theHeader->lastHash = NULL;
|
1296
|
+
}
|
1297
|
+
|
1298
|
+
/********************/
|
1299
|
+
/* FindAlphaMemory: */
|
1300
|
+
/********************/
|
1301
|
+
static struct alphaMemoryHash *FindAlphaMemory(
|
1302
|
+
Environment *theEnv,
|
1303
|
+
struct patternNodeHeader *theHeader,
|
1304
|
+
unsigned long hashValue)
|
1305
|
+
{
|
1306
|
+
struct alphaMemoryHash *theAlphaMemory;
|
1307
|
+
|
1308
|
+
theAlphaMemory = DefruleData(theEnv)->AlphaMemoryTable[hashValue];
|
1309
|
+
|
1310
|
+
if (theAlphaMemory != NULL)
|
1311
|
+
{
|
1312
|
+
while ((theAlphaMemory != NULL) && (theAlphaMemory->owner != theHeader))
|
1313
|
+
{ theAlphaMemory = theAlphaMemory->next; }
|
1314
|
+
}
|
1315
|
+
|
1316
|
+
return theAlphaMemory;
|
1317
|
+
}
|
1318
|
+
|
1319
|
+
/*************************/
|
1320
|
+
/* AlphaMemoryHashValue: */
|
1321
|
+
/*************************/
|
1322
|
+
static unsigned long AlphaMemoryHashValue(
|
1323
|
+
struct patternNodeHeader *theHeader,
|
1324
|
+
unsigned long hashOffset)
|
1325
|
+
{
|
1326
|
+
unsigned long hashValue;
|
1327
|
+
union
|
1328
|
+
{
|
1329
|
+
void *vv;
|
1330
|
+
unsigned uv;
|
1331
|
+
} fis;
|
1332
|
+
|
1333
|
+
fis.uv = 0;
|
1334
|
+
fis.vv = theHeader;
|
1335
|
+
|
1336
|
+
hashValue = fis.uv + hashOffset;
|
1337
|
+
hashValue = hashValue % ALPHA_MEMORY_HASH_SIZE;
|
1338
|
+
|
1339
|
+
return hashValue;
|
1340
|
+
}
|
1341
|
+
|
1342
|
+
/**********************/
|
1343
|
+
/* UnlinkAlphaMemory: */
|
1344
|
+
/**********************/
|
1345
|
+
static void UnlinkAlphaMemory(
|
1346
|
+
Environment *theEnv,
|
1347
|
+
struct patternNodeHeader *theHeader,
|
1348
|
+
struct alphaMemoryHash *theAlphaMemory)
|
1349
|
+
{
|
1350
|
+
/*======================*/
|
1351
|
+
/* Unlink the siblings. */
|
1352
|
+
/*======================*/
|
1353
|
+
|
1354
|
+
UnlinkAlphaMemoryBucketSiblings(theEnv,theAlphaMemory);
|
1355
|
+
|
1356
|
+
/*================================*/
|
1357
|
+
/* Update firstHash and lastHash. */
|
1358
|
+
/*================================*/
|
1359
|
+
|
1360
|
+
if (theAlphaMemory == theHeader->firstHash)
|
1361
|
+
{ theHeader->firstHash = theAlphaMemory->nextHash; }
|
1362
|
+
|
1363
|
+
if (theAlphaMemory == theHeader->lastHash)
|
1364
|
+
{ theHeader->lastHash = theAlphaMemory->prevHash; }
|
1365
|
+
|
1366
|
+
/*===============================*/
|
1367
|
+
/* Update nextHash and prevHash. */
|
1368
|
+
/*===============================*/
|
1369
|
+
|
1370
|
+
if (theAlphaMemory->prevHash != NULL)
|
1371
|
+
{ theAlphaMemory->prevHash->nextHash = theAlphaMemory->nextHash; }
|
1372
|
+
|
1373
|
+
if (theAlphaMemory->nextHash != NULL)
|
1374
|
+
{ theAlphaMemory->nextHash->prevHash = theAlphaMemory->prevHash; }
|
1375
|
+
|
1376
|
+
rtn_struct(theEnv,alphaMemoryHash,theAlphaMemory);
|
1377
|
+
}
|
1378
|
+
|
1379
|
+
/************************************/
|
1380
|
+
/* UnlinkAlphaMemoryBucketSiblings: */
|
1381
|
+
/************************************/
|
1382
|
+
static void UnlinkAlphaMemoryBucketSiblings(
|
1383
|
+
Environment *theEnv,
|
1384
|
+
struct alphaMemoryHash *theAlphaMemory)
|
1385
|
+
{
|
1386
|
+
if (theAlphaMemory->prev == NULL)
|
1387
|
+
{ DefruleData(theEnv)->AlphaMemoryTable[theAlphaMemory->bucket] = theAlphaMemory->next; }
|
1388
|
+
else
|
1389
|
+
{ theAlphaMemory->prev->next = theAlphaMemory->next; }
|
1390
|
+
|
1391
|
+
if (theAlphaMemory->next != NULL)
|
1392
|
+
{ theAlphaMemory->next->prev = theAlphaMemory->prev; }
|
1393
|
+
}
|
1394
|
+
|
1395
|
+
/**************************/
|
1396
|
+
/* ComputeRightHashValue: */
|
1397
|
+
/**************************/
|
1398
|
+
unsigned long ComputeRightHashValue(
|
1399
|
+
Environment *theEnv,
|
1400
|
+
struct patternNodeHeader *theHeader)
|
1401
|
+
{
|
1402
|
+
struct expr *tempExpr;
|
1403
|
+
unsigned long hashValue = 0;
|
1404
|
+
unsigned long multiplier = 1;
|
1405
|
+
union
|
1406
|
+
{
|
1407
|
+
void *vv;
|
1408
|
+
unsigned long liv;
|
1409
|
+
} fis;
|
1410
|
+
|
1411
|
+
if (theHeader->rightHash == NULL)
|
1412
|
+
{ return hashValue; }
|
1413
|
+
|
1414
|
+
for (tempExpr = theHeader->rightHash;
|
1415
|
+
tempExpr != NULL;
|
1416
|
+
tempExpr = tempExpr->nextArg, multiplier = multiplier * 509)
|
1417
|
+
{
|
1418
|
+
UDFValue theResult;
|
1419
|
+
struct expr *oldArgument;
|
1420
|
+
|
1421
|
+
oldArgument = EvaluationData(theEnv)->CurrentExpression;
|
1422
|
+
EvaluationData(theEnv)->CurrentExpression = tempExpr;
|
1423
|
+
(*EvaluationData(theEnv)->PrimitivesArray[tempExpr->type]->evaluateFunction)(theEnv,tempExpr->value,&theResult);
|
1424
|
+
EvaluationData(theEnv)->CurrentExpression = oldArgument;
|
1425
|
+
|
1426
|
+
switch (theResult.header->type)
|
1427
|
+
{
|
1428
|
+
case STRING_TYPE:
|
1429
|
+
case SYMBOL_TYPE:
|
1430
|
+
case INSTANCE_NAME_TYPE:
|
1431
|
+
hashValue += (theResult.lexemeValue->bucket * multiplier);
|
1432
|
+
break;
|
1433
|
+
|
1434
|
+
case INTEGER_TYPE:
|
1435
|
+
hashValue += (theResult.integerValue->bucket * multiplier);
|
1436
|
+
break;
|
1437
|
+
|
1438
|
+
case FLOAT_TYPE:
|
1439
|
+
hashValue += (theResult.floatValue->bucket * multiplier);
|
1440
|
+
break;
|
1441
|
+
|
1442
|
+
case FACT_ADDRESS_TYPE:
|
1443
|
+
#if OBJECT_SYSTEM
|
1444
|
+
case INSTANCE_ADDRESS_TYPE:
|
1445
|
+
#endif
|
1446
|
+
fis.liv = 0;
|
1447
|
+
fis.vv = theResult.value;
|
1448
|
+
hashValue += fis.liv * multiplier;
|
1449
|
+
break;
|
1450
|
+
|
1451
|
+
case EXTERNAL_ADDRESS_TYPE:
|
1452
|
+
fis.liv = 0;
|
1453
|
+
fis.vv = theResult.externalAddressValue->contents;
|
1454
|
+
hashValue += fis.liv * multiplier;
|
1455
|
+
break;
|
1456
|
+
}
|
1457
|
+
}
|
1458
|
+
|
1459
|
+
return hashValue;
|
1460
|
+
}
|
1461
|
+
|
1462
|
+
/*********************/
|
1463
|
+
/* ResizeBetaMemory: */
|
1464
|
+
/*********************/
|
1465
|
+
void ResizeBetaMemory(
|
1466
|
+
Environment *theEnv,
|
1467
|
+
struct betaMemory *theMemory)
|
1468
|
+
{
|
1469
|
+
struct partialMatch **oldArray, **lastAdd, *thePM, *nextPM;
|
1470
|
+
unsigned long i, oldSize, betaLocation;
|
1471
|
+
|
1472
|
+
oldSize = theMemory->size;
|
1473
|
+
oldArray = theMemory->beta;
|
1474
|
+
|
1475
|
+
theMemory->size = oldSize * 11;
|
1476
|
+
theMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * theMemory->size);
|
1477
|
+
|
1478
|
+
lastAdd = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * theMemory->size);
|
1479
|
+
memset(theMemory->beta,0,sizeof(struct partialMatch *) * theMemory->size);
|
1480
|
+
memset(lastAdd,0,sizeof(struct partialMatch *) * theMemory->size);
|
1481
|
+
|
1482
|
+
for (i = 0; i < oldSize; i++)
|
1483
|
+
{
|
1484
|
+
thePM = oldArray[i];
|
1485
|
+
while (thePM != NULL)
|
1486
|
+
{
|
1487
|
+
nextPM = thePM->nextInMemory;
|
1488
|
+
|
1489
|
+
thePM->nextInMemory = NULL;
|
1490
|
+
|
1491
|
+
betaLocation = thePM->hashValue % theMemory->size;
|
1492
|
+
thePM->prevInMemory = lastAdd[betaLocation];
|
1493
|
+
|
1494
|
+
if (lastAdd[betaLocation] != NULL)
|
1495
|
+
{ lastAdd[betaLocation]->nextInMemory = thePM; }
|
1496
|
+
else
|
1497
|
+
{ theMemory->beta[betaLocation] = thePM; }
|
1498
|
+
|
1499
|
+
lastAdd[betaLocation] = thePM;
|
1500
|
+
|
1501
|
+
thePM = nextPM;
|
1502
|
+
}
|
1503
|
+
}
|
1504
|
+
|
1505
|
+
if (theMemory->last != NULL)
|
1506
|
+
{
|
1507
|
+
genfree(theEnv,theMemory->last,sizeof(struct partialMatch *) * oldSize);
|
1508
|
+
theMemory->last = lastAdd;
|
1509
|
+
}
|
1510
|
+
else
|
1511
|
+
{ genfree(theEnv,lastAdd,sizeof(struct partialMatch *) * theMemory->size); }
|
1512
|
+
|
1513
|
+
genfree(theEnv,oldArray,sizeof(struct partialMatch *) * oldSize);
|
1514
|
+
}
|
1515
|
+
|
1516
|
+
/********************/
|
1517
|
+
/* ResetBetaMemory: */
|
1518
|
+
/********************/
|
1519
|
+
static void ResetBetaMemory(
|
1520
|
+
Environment *theEnv,
|
1521
|
+
struct betaMemory *theMemory)
|
1522
|
+
{
|
1523
|
+
struct partialMatch **oldArray, **lastAdd;
|
1524
|
+
unsigned long oldSize;
|
1525
|
+
|
1526
|
+
if ((theMemory->size == 1) ||
|
1527
|
+
(theMemory->size == INITIAL_BETA_HASH_SIZE))
|
1528
|
+
{ return; }
|
1529
|
+
|
1530
|
+
oldSize = theMemory->size;
|
1531
|
+
oldArray = theMemory->beta;
|
1532
|
+
|
1533
|
+
theMemory->size = INITIAL_BETA_HASH_SIZE;
|
1534
|
+
theMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * theMemory->size);
|
1535
|
+
memset(theMemory->beta,0,sizeof(struct partialMatch *) * theMemory->size);
|
1536
|
+
genfree(theEnv,oldArray,sizeof(struct partialMatch *) * oldSize);
|
1537
|
+
|
1538
|
+
if (theMemory->last != NULL)
|
1539
|
+
{
|
1540
|
+
lastAdd = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * theMemory->size);
|
1541
|
+
memset(lastAdd,0,sizeof(struct partialMatch *) * theMemory->size);
|
1542
|
+
genfree(theEnv,theMemory->last,sizeof(struct partialMatch *) * oldSize);
|
1543
|
+
theMemory->last = lastAdd;
|
1544
|
+
}
|
1545
|
+
}
|
1546
|
+
|
1547
|
+
/********************/
|
1548
|
+
/* PrintBetaMemory: */
|
1549
|
+
/********************/
|
1550
|
+
unsigned long PrintBetaMemory(
|
1551
|
+
Environment *theEnv,
|
1552
|
+
const char *logName,
|
1553
|
+
struct betaMemory *theMemory,
|
1554
|
+
bool indentFirst,
|
1555
|
+
const char *indentString,
|
1556
|
+
Verbosity output)
|
1557
|
+
{
|
1558
|
+
struct partialMatch *listOfMatches;
|
1559
|
+
unsigned long b, count = 0;
|
1560
|
+
|
1561
|
+
if (GetHaltExecution(theEnv) == true)
|
1562
|
+
{ return count; }
|
1563
|
+
|
1564
|
+
for (b = 0; b < theMemory->size; b++)
|
1565
|
+
{
|
1566
|
+
listOfMatches = theMemory->beta[b];
|
1567
|
+
|
1568
|
+
while (listOfMatches != NULL)
|
1569
|
+
{
|
1570
|
+
/*=========================================*/
|
1571
|
+
/* Check to see if the user is attempting */
|
1572
|
+
/* to stop the display of partial matches. */
|
1573
|
+
/*=========================================*/
|
1574
|
+
|
1575
|
+
if (GetHaltExecution(theEnv) == true)
|
1576
|
+
{ return count; }
|
1577
|
+
|
1578
|
+
/*=========================================================*/
|
1579
|
+
/* The first partial match may have already been indented. */
|
1580
|
+
/* Subsequent partial matches will always be indented with */
|
1581
|
+
/* the indentation string. */
|
1582
|
+
/*=========================================================*/
|
1583
|
+
|
1584
|
+
if (output == VERBOSE)
|
1585
|
+
{
|
1586
|
+
if (indentFirst)
|
1587
|
+
{ WriteString(theEnv,logName,indentString); }
|
1588
|
+
else
|
1589
|
+
{ indentFirst = true; }
|
1590
|
+
}
|
1591
|
+
|
1592
|
+
/*==========================*/
|
1593
|
+
/* Print the partial match. */
|
1594
|
+
/*==========================*/
|
1595
|
+
|
1596
|
+
if (output == VERBOSE)
|
1597
|
+
{
|
1598
|
+
PrintPartialMatch(theEnv,logName,listOfMatches);
|
1599
|
+
WriteString(theEnv,logName,"\n");
|
1600
|
+
}
|
1601
|
+
|
1602
|
+
count++;
|
1603
|
+
|
1604
|
+
/*============================*/
|
1605
|
+
/* Move on to the next match. */
|
1606
|
+
/*============================*/
|
1607
|
+
|
1608
|
+
listOfMatches = listOfMatches->nextInMemory;
|
1609
|
+
}
|
1610
|
+
}
|
1611
|
+
|
1612
|
+
return count;
|
1613
|
+
}
|
1614
|
+
|
1615
|
+
#if (CONSTRUCT_COMPILER || BLOAD_AND_BSAVE) && (! RUN_TIME)
|
1616
|
+
|
1617
|
+
/*************************************************************/
|
1618
|
+
/* TagRuleNetwork: Assigns each join in the join network and */
|
1619
|
+
/* each defrule data structure with a unique integer ID. */
|
1620
|
+
/* Also counts the number of defrule and joinNode data */
|
1621
|
+
/* structures currently in use. */
|
1622
|
+
/*************************************************************/
|
1623
|
+
void TagRuleNetwork(
|
1624
|
+
Environment *theEnv,
|
1625
|
+
unsigned long *moduleCount,
|
1626
|
+
unsigned long *ruleCount,
|
1627
|
+
unsigned long *joinCount,
|
1628
|
+
unsigned long *linkCount)
|
1629
|
+
{
|
1630
|
+
Defmodule *modulePtr;
|
1631
|
+
Defrule *rulePtr, *disjunctPtr;
|
1632
|
+
struct joinLink *theLink;
|
1633
|
+
|
1634
|
+
*moduleCount = 0;
|
1635
|
+
*ruleCount = 0;
|
1636
|
+
*joinCount = 0;
|
1637
|
+
*linkCount = 0;
|
1638
|
+
|
1639
|
+
MarkRuleNetwork(theEnv,0);
|
1640
|
+
|
1641
|
+
for (theLink = DefruleData(theEnv)->LeftPrimeJoins;
|
1642
|
+
theLink != NULL;
|
1643
|
+
theLink = theLink->next)
|
1644
|
+
{
|
1645
|
+
theLink->bsaveID = *linkCount;
|
1646
|
+
(*linkCount)++;
|
1647
|
+
}
|
1648
|
+
|
1649
|
+
for (theLink = DefruleData(theEnv)->RightPrimeJoins;
|
1650
|
+
theLink != NULL;
|
1651
|
+
theLink = theLink->next)
|
1652
|
+
{
|
1653
|
+
theLink->bsaveID = *linkCount;
|
1654
|
+
(*linkCount)++;
|
1655
|
+
}
|
1656
|
+
|
1657
|
+
/*===========================*/
|
1658
|
+
/* Loop through each module. */
|
1659
|
+
/*===========================*/
|
1660
|
+
|
1661
|
+
for (modulePtr = GetNextDefmodule(theEnv,NULL);
|
1662
|
+
modulePtr != NULL;
|
1663
|
+
modulePtr = GetNextDefmodule(theEnv,modulePtr))
|
1664
|
+
{
|
1665
|
+
(*moduleCount)++;
|
1666
|
+
SetCurrentModule(theEnv,modulePtr);
|
1667
|
+
|
1668
|
+
/*=========================*/
|
1669
|
+
/* Loop through each rule. */
|
1670
|
+
/*=========================*/
|
1671
|
+
|
1672
|
+
rulePtr = GetNextDefrule(theEnv,NULL);
|
1673
|
+
|
1674
|
+
while (rulePtr != NULL)
|
1675
|
+
{
|
1676
|
+
/*=============================*/
|
1677
|
+
/* Loop through each disjunct. */
|
1678
|
+
/*=============================*/
|
1679
|
+
|
1680
|
+
for (disjunctPtr = rulePtr; disjunctPtr != NULL; disjunctPtr = disjunctPtr->disjunct)
|
1681
|
+
{
|
1682
|
+
disjunctPtr->header.bsaveID = *ruleCount;
|
1683
|
+
(*ruleCount)++;
|
1684
|
+
TagNetworkTraverseJoins(theEnv,joinCount,linkCount,disjunctPtr->lastJoin);
|
1685
|
+
}
|
1686
|
+
|
1687
|
+
rulePtr = GetNextDefrule(theEnv,rulePtr);
|
1688
|
+
}
|
1689
|
+
}
|
1690
|
+
}
|
1691
|
+
|
1692
|
+
/*******************************************************************/
|
1693
|
+
/* TagNetworkTraverseJoins: Traverses the join network for a rule. */
|
1694
|
+
/*******************************************************************/
|
1695
|
+
static void TagNetworkTraverseJoins(
|
1696
|
+
Environment *theEnv,
|
1697
|
+
unsigned long *joinCount,
|
1698
|
+
unsigned long *linkCount,
|
1699
|
+
struct joinNode *joinPtr)
|
1700
|
+
{
|
1701
|
+
struct joinLink *theLink;
|
1702
|
+
for (;
|
1703
|
+
joinPtr != NULL;
|
1704
|
+
joinPtr = joinPtr->lastLevel)
|
1705
|
+
{
|
1706
|
+
if (joinPtr->marked == 0)
|
1707
|
+
{
|
1708
|
+
joinPtr->marked = 1;
|
1709
|
+
joinPtr->bsaveID = *joinCount;
|
1710
|
+
(*joinCount)++;
|
1711
|
+
for (theLink = joinPtr->nextLinks;
|
1712
|
+
theLink != NULL;
|
1713
|
+
theLink = theLink->next)
|
1714
|
+
{
|
1715
|
+
theLink->bsaveID = *linkCount;
|
1716
|
+
(*linkCount)++;
|
1717
|
+
}
|
1718
|
+
}
|
1719
|
+
|
1720
|
+
if (joinPtr->joinFromTheRight)
|
1721
|
+
{ TagNetworkTraverseJoins(theEnv,joinCount,linkCount,(struct joinNode *) joinPtr->rightSideEntryStructure); }
|
1722
|
+
}
|
1723
|
+
}
|
1724
|
+
|
1725
|
+
#endif /* (CONSTRUCT_COMPILER || BLOAD_AND_BSAVE) && (! RUN_TIME) */
|
1726
|
+
|
1727
|
+
#endif /* DEFRULE_CONSTRUCT */
|
1728
|
+
|
1729
|
+
|
1730
|
+
|
1731
|
+
|
1732
|
+
|