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.
Files changed (346) hide show
  1. checksums.yaml +7 -0
  2. data/ext/clipsruby/agenda.c +1373 -0
  3. data/ext/clipsruby/agenda.h +169 -0
  4. data/ext/clipsruby/analysis.c +1142 -0
  5. data/ext/clipsruby/analysis.h +61 -0
  6. data/ext/clipsruby/argacces.c +526 -0
  7. data/ext/clipsruby/argacces.h +77 -0
  8. data/ext/clipsruby/bload.c +884 -0
  9. data/ext/clipsruby/bload.h +94 -0
  10. data/ext/clipsruby/bmathfun.c +557 -0
  11. data/ext/clipsruby/bmathfun.h +66 -0
  12. data/ext/clipsruby/bsave.c +634 -0
  13. data/ext/clipsruby/bsave.h +130 -0
  14. data/ext/clipsruby/classcom.c +976 -0
  15. data/ext/clipsruby/classcom.h +115 -0
  16. data/ext/clipsruby/classexm.c +1376 -0
  17. data/ext/clipsruby/classexm.h +97 -0
  18. data/ext/clipsruby/classfun.c +1392 -0
  19. data/ext/clipsruby/classfun.h +164 -0
  20. data/ext/clipsruby/classinf.c +1245 -0
  21. data/ext/clipsruby/classinf.h +94 -0
  22. data/ext/clipsruby/classini.c +843 -0
  23. data/ext/clipsruby/classini.h +75 -0
  24. data/ext/clipsruby/classpsr.c +957 -0
  25. data/ext/clipsruby/classpsr.h +73 -0
  26. data/ext/clipsruby/clips.h +133 -0
  27. data/ext/clipsruby/clipsruby.c +619 -0
  28. data/ext/clipsruby/clsltpsr.c +931 -0
  29. data/ext/clipsruby/clsltpsr.h +72 -0
  30. data/ext/clipsruby/commline.c +1217 -0
  31. data/ext/clipsruby/commline.h +131 -0
  32. data/ext/clipsruby/conscomp.c +1593 -0
  33. data/ext/clipsruby/conscomp.h +150 -0
  34. data/ext/clipsruby/constant.h +264 -0
  35. data/ext/clipsruby/constrct.c +1090 -0
  36. data/ext/clipsruby/constrct.h +216 -0
  37. data/ext/clipsruby/constrnt.c +554 -0
  38. data/ext/clipsruby/constrnt.h +132 -0
  39. data/ext/clipsruby/crstrtgy.c +1088 -0
  40. data/ext/clipsruby/crstrtgy.h +85 -0
  41. data/ext/clipsruby/cstrcbin.c +185 -0
  42. data/ext/clipsruby/cstrcbin.h +61 -0
  43. data/ext/clipsruby/cstrccmp.h +43 -0
  44. data/ext/clipsruby/cstrccom.c +1791 -0
  45. data/ext/clipsruby/cstrccom.h +115 -0
  46. data/ext/clipsruby/cstrcpsr.c +835 -0
  47. data/ext/clipsruby/cstrcpsr.h +97 -0
  48. data/ext/clipsruby/cstrnbin.c +282 -0
  49. data/ext/clipsruby/cstrnbin.h +55 -0
  50. data/ext/clipsruby/cstrnchk.c +826 -0
  51. data/ext/clipsruby/cstrnchk.h +91 -0
  52. data/ext/clipsruby/cstrncmp.c +238 -0
  53. data/ext/clipsruby/cstrncmp.h +57 -0
  54. data/ext/clipsruby/cstrnops.c +1176 -0
  55. data/ext/clipsruby/cstrnops.h +47 -0
  56. data/ext/clipsruby/cstrnpsr.c +1394 -0
  57. data/ext/clipsruby/cstrnpsr.h +88 -0
  58. data/ext/clipsruby/cstrnutl.c +564 -0
  59. data/ext/clipsruby/cstrnutl.h +54 -0
  60. data/ext/clipsruby/default.c +454 -0
  61. data/ext/clipsruby/default.h +57 -0
  62. data/ext/clipsruby/defins.c +971 -0
  63. data/ext/clipsruby/defins.h +127 -0
  64. data/ext/clipsruby/developr.c +677 -0
  65. data/ext/clipsruby/developr.h +69 -0
  66. data/ext/clipsruby/dffctbin.c +477 -0
  67. data/ext/clipsruby/dffctbin.h +76 -0
  68. data/ext/clipsruby/dffctbsc.c +308 -0
  69. data/ext/clipsruby/dffctbsc.h +72 -0
  70. data/ext/clipsruby/dffctcmp.c +297 -0
  71. data/ext/clipsruby/dffctcmp.h +44 -0
  72. data/ext/clipsruby/dffctdef.c +364 -0
  73. data/ext/clipsruby/dffctdef.h +104 -0
  74. data/ext/clipsruby/dffctpsr.c +179 -0
  75. data/ext/clipsruby/dffctpsr.h +49 -0
  76. data/ext/clipsruby/dffnxbin.c +520 -0
  77. data/ext/clipsruby/dffnxbin.h +67 -0
  78. data/ext/clipsruby/dffnxcmp.c +378 -0
  79. data/ext/clipsruby/dffnxcmp.h +54 -0
  80. data/ext/clipsruby/dffnxexe.c +241 -0
  81. data/ext/clipsruby/dffnxexe.h +58 -0
  82. data/ext/clipsruby/dffnxfun.c +1192 -0
  83. data/ext/clipsruby/dffnxfun.h +155 -0
  84. data/ext/clipsruby/dffnxpsr.c +514 -0
  85. data/ext/clipsruby/dffnxpsr.h +57 -0
  86. data/ext/clipsruby/dfinsbin.c +509 -0
  87. data/ext/clipsruby/dfinsbin.h +66 -0
  88. data/ext/clipsruby/dfinscmp.c +345 -0
  89. data/ext/clipsruby/dfinscmp.h +48 -0
  90. data/ext/clipsruby/drive.c +1191 -0
  91. data/ext/clipsruby/drive.h +65 -0
  92. data/ext/clipsruby/emathfun.c +1213 -0
  93. data/ext/clipsruby/emathfun.h +99 -0
  94. data/ext/clipsruby/engine.c +1568 -0
  95. data/ext/clipsruby/engine.h +203 -0
  96. data/ext/clipsruby/entities.h +276 -0
  97. data/ext/clipsruby/envrnbld.c +514 -0
  98. data/ext/clipsruby/envrnbld.h +40 -0
  99. data/ext/clipsruby/envrnmnt.c +257 -0
  100. data/ext/clipsruby/envrnmnt.h +112 -0
  101. data/ext/clipsruby/evaluatn.c +1736 -0
  102. data/ext/clipsruby/evaluatn.h +211 -0
  103. data/ext/clipsruby/expressn.c +494 -0
  104. data/ext/clipsruby/expressn.h +154 -0
  105. data/ext/clipsruby/exprnbin.c +538 -0
  106. data/ext/clipsruby/exprnbin.h +60 -0
  107. data/ext/clipsruby/exprnops.c +564 -0
  108. data/ext/clipsruby/exprnops.h +67 -0
  109. data/ext/clipsruby/exprnpsr.c +1112 -0
  110. data/ext/clipsruby/exprnpsr.h +98 -0
  111. data/ext/clipsruby/extconf.rb +2 -0
  112. data/ext/clipsruby/extnfunc.c +1015 -0
  113. data/ext/clipsruby/extnfunc.h +157 -0
  114. data/ext/clipsruby/factbin.c +447 -0
  115. data/ext/clipsruby/factbin.h +56 -0
  116. data/ext/clipsruby/factbld.c +1035 -0
  117. data/ext/clipsruby/factbld.h +63 -0
  118. data/ext/clipsruby/factcmp.c +386 -0
  119. data/ext/clipsruby/factcmp.h +46 -0
  120. data/ext/clipsruby/factcom.c +759 -0
  121. data/ext/clipsruby/factcom.h +80 -0
  122. data/ext/clipsruby/factfile.c +1761 -0
  123. data/ext/clipsruby/factfile.h +54 -0
  124. data/ext/clipsruby/factfun.c +682 -0
  125. data/ext/clipsruby/factfun.h +77 -0
  126. data/ext/clipsruby/factgen.c +1305 -0
  127. data/ext/clipsruby/factgen.h +229 -0
  128. data/ext/clipsruby/facthsh.c +438 -0
  129. data/ext/clipsruby/facthsh.h +81 -0
  130. data/ext/clipsruby/factlhs.c +250 -0
  131. data/ext/clipsruby/factlhs.h +54 -0
  132. data/ext/clipsruby/factmch.c +905 -0
  133. data/ext/clipsruby/factmch.h +68 -0
  134. data/ext/clipsruby/factmngr.c +3373 -0
  135. data/ext/clipsruby/factmngr.h +325 -0
  136. data/ext/clipsruby/factprt.c +498 -0
  137. data/ext/clipsruby/factprt.h +60 -0
  138. data/ext/clipsruby/factqpsr.c +796 -0
  139. data/ext/clipsruby/factqpsr.h +61 -0
  140. data/ext/clipsruby/factqury.c +1267 -0
  141. data/ext/clipsruby/factqury.h +112 -0
  142. data/ext/clipsruby/factrete.c +978 -0
  143. data/ext/clipsruby/factrete.h +70 -0
  144. data/ext/clipsruby/factrhs.c +667 -0
  145. data/ext/clipsruby/factrhs.h +55 -0
  146. data/ext/clipsruby/filecom.c +353 -0
  147. data/ext/clipsruby/filecom.h +137 -0
  148. data/ext/clipsruby/filertr.c +481 -0
  149. data/ext/clipsruby/filertr.h +94 -0
  150. data/ext/clipsruby/fileutil.c +1020 -0
  151. data/ext/clipsruby/fileutil.h +50 -0
  152. data/ext/clipsruby/generate.c +1079 -0
  153. data/ext/clipsruby/generate.h +57 -0
  154. data/ext/clipsruby/genrcbin.c +902 -0
  155. data/ext/clipsruby/genrcbin.h +69 -0
  156. data/ext/clipsruby/genrccmp.c +640 -0
  157. data/ext/clipsruby/genrccmp.h +59 -0
  158. data/ext/clipsruby/genrccom.c +2017 -0
  159. data/ext/clipsruby/genrccom.h +119 -0
  160. data/ext/clipsruby/genrcexe.c +737 -0
  161. data/ext/clipsruby/genrcexe.h +73 -0
  162. data/ext/clipsruby/genrcfun.c +890 -0
  163. data/ext/clipsruby/genrcfun.h +185 -0
  164. data/ext/clipsruby/genrcpsr.c +1618 -0
  165. data/ext/clipsruby/genrcpsr.h +80 -0
  166. data/ext/clipsruby/globlbin.c +458 -0
  167. data/ext/clipsruby/globlbin.h +71 -0
  168. data/ext/clipsruby/globlbsc.c +361 -0
  169. data/ext/clipsruby/globlbsc.h +83 -0
  170. data/ext/clipsruby/globlcmp.c +330 -0
  171. data/ext/clipsruby/globlcmp.h +52 -0
  172. data/ext/clipsruby/globlcom.c +289 -0
  173. data/ext/clipsruby/globlcom.h +63 -0
  174. data/ext/clipsruby/globldef.c +1087 -0
  175. data/ext/clipsruby/globldef.h +151 -0
  176. data/ext/clipsruby/globlpsr.c +530 -0
  177. data/ext/clipsruby/globlpsr.h +59 -0
  178. data/ext/clipsruby/immthpsr.c +431 -0
  179. data/ext/clipsruby/immthpsr.h +55 -0
  180. data/ext/clipsruby/incrrset.c +530 -0
  181. data/ext/clipsruby/incrrset.h +73 -0
  182. data/ext/clipsruby/inherpsr.c +850 -0
  183. data/ext/clipsruby/inherpsr.h +52 -0
  184. data/ext/clipsruby/inscom.c +2076 -0
  185. data/ext/clipsruby/inscom.h +182 -0
  186. data/ext/clipsruby/insfile.c +1764 -0
  187. data/ext/clipsruby/insfile.h +96 -0
  188. data/ext/clipsruby/insfun.c +1451 -0
  189. data/ext/clipsruby/insfun.h +134 -0
  190. data/ext/clipsruby/insmngr.c +2550 -0
  191. data/ext/clipsruby/insmngr.h +125 -0
  192. data/ext/clipsruby/insmoddp.c +1041 -0
  193. data/ext/clipsruby/insmoddp.h +91 -0
  194. data/ext/clipsruby/insmult.c +804 -0
  195. data/ext/clipsruby/insmult.h +62 -0
  196. data/ext/clipsruby/inspsr.c +602 -0
  197. data/ext/clipsruby/inspsr.h +60 -0
  198. data/ext/clipsruby/insquery.c +1278 -0
  199. data/ext/clipsruby/insquery.h +115 -0
  200. data/ext/clipsruby/insqypsr.c +729 -0
  201. data/ext/clipsruby/insqypsr.h +63 -0
  202. data/ext/clipsruby/iofun.c +2045 -0
  203. data/ext/clipsruby/iofun.h +116 -0
  204. data/ext/clipsruby/lgcldpnd.c +644 -0
  205. data/ext/clipsruby/lgcldpnd.h +75 -0
  206. data/ext/clipsruby/main.c +112 -0
  207. data/ext/clipsruby/match.h +142 -0
  208. data/ext/clipsruby/memalloc.c +481 -0
  209. data/ext/clipsruby/memalloc.h +197 -0
  210. data/ext/clipsruby/miscfun.c +1801 -0
  211. data/ext/clipsruby/miscfun.h +132 -0
  212. data/ext/clipsruby/modulbin.c +607 -0
  213. data/ext/clipsruby/modulbin.h +84 -0
  214. data/ext/clipsruby/modulbsc.c +347 -0
  215. data/ext/clipsruby/modulbsc.h +67 -0
  216. data/ext/clipsruby/modulcmp.c +499 -0
  217. data/ext/clipsruby/modulcmp.h +54 -0
  218. data/ext/clipsruby/moduldef.c +817 -0
  219. data/ext/clipsruby/moduldef.h +271 -0
  220. data/ext/clipsruby/modulpsr.c +1150 -0
  221. data/ext/clipsruby/modulpsr.h +69 -0
  222. data/ext/clipsruby/modulutl.c +1036 -0
  223. data/ext/clipsruby/modulutl.h +84 -0
  224. data/ext/clipsruby/msgcom.c +1221 -0
  225. data/ext/clipsruby/msgcom.h +125 -0
  226. data/ext/clipsruby/msgfun.c +1076 -0
  227. data/ext/clipsruby/msgfun.h +118 -0
  228. data/ext/clipsruby/msgpass.c +1441 -0
  229. data/ext/clipsruby/msgpass.h +103 -0
  230. data/ext/clipsruby/msgpsr.c +698 -0
  231. data/ext/clipsruby/msgpsr.h +73 -0
  232. data/ext/clipsruby/multifld.c +1404 -0
  233. data/ext/clipsruby/multifld.h +130 -0
  234. data/ext/clipsruby/multifun.c +2182 -0
  235. data/ext/clipsruby/multifun.h +102 -0
  236. data/ext/clipsruby/network.h +142 -0
  237. data/ext/clipsruby/objbin.c +1522 -0
  238. data/ext/clipsruby/objbin.h +79 -0
  239. data/ext/clipsruby/objcmp.c +1507 -0
  240. data/ext/clipsruby/objcmp.h +71 -0
  241. data/ext/clipsruby/object.h +260 -0
  242. data/ext/clipsruby/objrtbin.c +701 -0
  243. data/ext/clipsruby/objrtbin.h +79 -0
  244. data/ext/clipsruby/objrtbld.c +2393 -0
  245. data/ext/clipsruby/objrtbld.h +66 -0
  246. data/ext/clipsruby/objrtcmp.c +734 -0
  247. data/ext/clipsruby/objrtcmp.h +66 -0
  248. data/ext/clipsruby/objrtfnx.c +1330 -0
  249. data/ext/clipsruby/objrtfnx.h +222 -0
  250. data/ext/clipsruby/objrtgen.c +736 -0
  251. data/ext/clipsruby/objrtgen.h +63 -0
  252. data/ext/clipsruby/objrtmch.c +1524 -0
  253. data/ext/clipsruby/objrtmch.h +160 -0
  254. data/ext/clipsruby/parsefun.c +415 -0
  255. data/ext/clipsruby/parsefun.h +67 -0
  256. data/ext/clipsruby/pattern.c +1265 -0
  257. data/ext/clipsruby/pattern.h +163 -0
  258. data/ext/clipsruby/pprint.c +328 -0
  259. data/ext/clipsruby/pprint.h +79 -0
  260. data/ext/clipsruby/prccode.c +1478 -0
  261. data/ext/clipsruby/prccode.h +145 -0
  262. data/ext/clipsruby/prcdrfun.c +640 -0
  263. data/ext/clipsruby/prcdrfun.h +95 -0
  264. data/ext/clipsruby/prcdrpsr.c +1068 -0
  265. data/ext/clipsruby/prcdrpsr.h +79 -0
  266. data/ext/clipsruby/prdctfun.c +869 -0
  267. data/ext/clipsruby/prdctfun.h +77 -0
  268. data/ext/clipsruby/prntutil.c +878 -0
  269. data/ext/clipsruby/prntutil.h +125 -0
  270. data/ext/clipsruby/proflfun.c +827 -0
  271. data/ext/clipsruby/proflfun.h +118 -0
  272. data/ext/clipsruby/reorder.c +2082 -0
  273. data/ext/clipsruby/reorder.h +172 -0
  274. data/ext/clipsruby/reteutil.c +1732 -0
  275. data/ext/clipsruby/reteutil.h +111 -0
  276. data/ext/clipsruby/retract.c +710 -0
  277. data/ext/clipsruby/retract.h +74 -0
  278. data/ext/clipsruby/router.c +737 -0
  279. data/ext/clipsruby/router.h +147 -0
  280. data/ext/clipsruby/rulebin.c +1136 -0
  281. data/ext/clipsruby/rulebin.h +153 -0
  282. data/ext/clipsruby/rulebld.c +1328 -0
  283. data/ext/clipsruby/rulebld.h +62 -0
  284. data/ext/clipsruby/rulebsc.c +517 -0
  285. data/ext/clipsruby/rulebsc.h +91 -0
  286. data/ext/clipsruby/rulecmp.c +733 -0
  287. data/ext/clipsruby/rulecmp.h +63 -0
  288. data/ext/clipsruby/rulecom.c +1583 -0
  289. data/ext/clipsruby/rulecom.h +116 -0
  290. data/ext/clipsruby/rulecstr.c +892 -0
  291. data/ext/clipsruby/rulecstr.h +53 -0
  292. data/ext/clipsruby/ruledef.c +559 -0
  293. data/ext/clipsruby/ruledef.h +179 -0
  294. data/ext/clipsruby/ruledlt.c +599 -0
  295. data/ext/clipsruby/ruledlt.h +58 -0
  296. data/ext/clipsruby/rulelhs.c +1216 -0
  297. data/ext/clipsruby/rulelhs.h +52 -0
  298. data/ext/clipsruby/rulepsr.c +1073 -0
  299. data/ext/clipsruby/rulepsr.h +61 -0
  300. data/ext/clipsruby/scanner.c +856 -0
  301. data/ext/clipsruby/scanner.h +112 -0
  302. data/ext/clipsruby/setup.h +488 -0
  303. data/ext/clipsruby/sortfun.c +433 -0
  304. data/ext/clipsruby/sortfun.h +55 -0
  305. data/ext/clipsruby/strngfun.c +1173 -0
  306. data/ext/clipsruby/strngfun.h +96 -0
  307. data/ext/clipsruby/strngrtr.c +523 -0
  308. data/ext/clipsruby/strngrtr.h +97 -0
  309. data/ext/clipsruby/symblbin.c +648 -0
  310. data/ext/clipsruby/symblbin.h +64 -0
  311. data/ext/clipsruby/symblcmp.c +893 -0
  312. data/ext/clipsruby/symblcmp.h +61 -0
  313. data/ext/clipsruby/symbol.c +1961 -0
  314. data/ext/clipsruby/symbol.h +243 -0
  315. data/ext/clipsruby/sysdep.c +894 -0
  316. data/ext/clipsruby/sysdep.h +164 -0
  317. data/ext/clipsruby/textpro.c +1388 -0
  318. data/ext/clipsruby/textpro.h +77 -0
  319. data/ext/clipsruby/tmpltbin.c +609 -0
  320. data/ext/clipsruby/tmpltbin.h +108 -0
  321. data/ext/clipsruby/tmpltbsc.c +327 -0
  322. data/ext/clipsruby/tmpltbsc.h +87 -0
  323. data/ext/clipsruby/tmpltcmp.c +450 -0
  324. data/ext/clipsruby/tmpltcmp.h +57 -0
  325. data/ext/clipsruby/tmpltdef.c +584 -0
  326. data/ext/clipsruby/tmpltdef.h +155 -0
  327. data/ext/clipsruby/tmpltfun.c +2477 -0
  328. data/ext/clipsruby/tmpltfun.h +122 -0
  329. data/ext/clipsruby/tmpltlhs.c +379 -0
  330. data/ext/clipsruby/tmpltlhs.h +50 -0
  331. data/ext/clipsruby/tmpltpsr.c +819 -0
  332. data/ext/clipsruby/tmpltpsr.h +59 -0
  333. data/ext/clipsruby/tmpltrhs.c +595 -0
  334. data/ext/clipsruby/tmpltrhs.h +55 -0
  335. data/ext/clipsruby/tmpltutl.c +637 -0
  336. data/ext/clipsruby/tmpltutl.h +82 -0
  337. data/ext/clipsruby/userdata.c +156 -0
  338. data/ext/clipsruby/userdata.h +72 -0
  339. data/ext/clipsruby/userfunctions.c +70 -0
  340. data/ext/clipsruby/usrsetup.h +7 -0
  341. data/ext/clipsruby/utility.c +1594 -0
  342. data/ext/clipsruby/utility.h +250 -0
  343. data/ext/clipsruby/watch.c +865 -0
  344. data/ext/clipsruby/watch.h +124 -0
  345. data/lib/clipsruby.rb +1 -0
  346. 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
+