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,1267 @@
1
+ /*******************************************************/
2
+ /* "C" Language Integrated Production System */
3
+ /* */
4
+ /* CLIPS Version 6.41 01/09/23 */
5
+ /* */
6
+ /* FACT QUERY MODULE */
7
+ /*******************************************************/
8
+
9
+ /*************************************************************/
10
+ /* Purpose: Query Functions for Objects */
11
+ /* */
12
+ /* Principal Programmer(s): */
13
+ /* Brian L. Dantes */
14
+ /* */
15
+ /* Contributing Programmer(s): */
16
+ /* Gary D. Riley */
17
+ /* */
18
+ /* Revision History: */
19
+ /* */
20
+ /* 6.23: Added fact-set queries. */
21
+ /* */
22
+ /* 6.24: Corrected errors when compiling as a C++ file. */
23
+ /* DR0868 */
24
+ /* */
25
+ /* Renamed BOOLEAN macro type to intBool. */
26
+ /* */
27
+ /* 6.30: Changed garbage collection algorithm. */
28
+ /* */
29
+ /* Fixes for run-time use of query functions. */
30
+ /* Added const qualifiers to remove C++ */
31
+ /* deprecation warnings. */
32
+ /* */
33
+ /* 6.31: Retrieval for fact query slot function */
34
+ /* generates an error if the fact has been */
35
+ /* retracted. */
36
+ /* */
37
+ /* Functions delayed-do-for-all-facts and */
38
+ /* do-for-fact increment the busy count of */
39
+ /* matching fact sets so that actions can */
40
+ /* detect retracted facts. */
41
+ /* */
42
+ /* Matching fact sets containing retracted facts */
43
+ /* are pruned. */
44
+ /* */
45
+ /* 6.32: Fixed garbage collection issue with return */
46
+ /* value of delayed-do-for-all-facts. */
47
+ /* */
48
+ /* 6.40: Added Env prefix to GetEvaluationError and */
49
+ /* SetEvaluationError 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
+ /* UDF redesign. */
59
+ /* */
60
+ /* Added GCBlockStart and GCBlockEnd functions */
61
+ /* for garbage collection blocks. */
62
+ /* */
63
+ /* Eval support for run time and bload only. */
64
+ /* */
65
+ /* 6.41: Changed the name of fact query structures to */
66
+ /* be distinct from instance structures. */
67
+ /* */
68
+ /*************************************************************/
69
+
70
+ /* =========================================
71
+ *****************************************
72
+ EXTERNAL DEFINITIONS
73
+ =========================================
74
+ ***************************************** */
75
+ #include "setup.h"
76
+
77
+ #if FACT_SET_QUERIES
78
+
79
+ #include "argacces.h"
80
+ #include "envrnmnt.h"
81
+ #include "memalloc.h"
82
+ #include "exprnpsr.h"
83
+ #include "modulutl.h"
84
+ #include "tmpltutl.h"
85
+ #include "insfun.h"
86
+ #include "factqpsr.h"
87
+ #include "prcdrfun.h"
88
+ #include "prntutil.h"
89
+ #include "router.h"
90
+ #include "utility.h"
91
+
92
+ #include "factqury.h"
93
+
94
+ /***************************************/
95
+ /* LOCAL INTERNAL FUNCTION DEFINITIONS */
96
+ /***************************************/
97
+
98
+ static void PushQueryCore(Environment *);
99
+ static void PopQueryCore(Environment *);
100
+ static FACT_QUERY_CORE *FindQueryCore(Environment *,long long);
101
+ static FACT_QUERY_TEMPLATE *DetermineQueryTemplates(Environment *,Expression *,const char *,unsigned *);
102
+ static FACT_QUERY_TEMPLATE *FormChain(Environment *,const char *,Deftemplate *,UDFValue *);
103
+ static void DeleteQueryTemplates(Environment *,FACT_QUERY_TEMPLATE *);
104
+ static bool TestForFirstInChain(Environment *,FACT_QUERY_TEMPLATE *,unsigned);
105
+ static bool TestForFirstFactInTemplate(Environment *,Deftemplate *,FACT_QUERY_TEMPLATE *,unsigned);
106
+ static void TestEntireChain(Environment *,FACT_QUERY_TEMPLATE *,unsigned);
107
+ static void TestEntireTemplate(Environment *,Deftemplate *,FACT_QUERY_TEMPLATE *,unsigned);
108
+ static void AddSolution(Environment *);
109
+ static void PopQuerySoln(Environment *);
110
+
111
+ /****************************************************
112
+ NAME : SetupFactQuery
113
+ DESCRIPTION : Initializes fact query H/L
114
+ functions and parsers
115
+ INPUTS : None
116
+ RETURNS : Nothing useful
117
+ SIDE EFFECTS : Sets up kernel functions and parsers
118
+ NOTES : None
119
+ ****************************************************/
120
+ void SetupFactQuery(
121
+ Environment *theEnv)
122
+ {
123
+ AllocateEnvironmentData(theEnv,FACT_QUERY_DATA,sizeof(struct factQueryData),NULL);
124
+
125
+ #if RUN_TIME
126
+ FactQueryData(theEnv)->QUERY_DELIMITER_SYMBOL = FindSymbolHN(theEnv,QUERY_DELIMITER_STRING,SYMBOL_BIT);
127
+ #endif
128
+
129
+ #if ! RUN_TIME
130
+ FactQueryData(theEnv)->QUERY_DELIMITER_SYMBOL = CreateSymbol(theEnv,QUERY_DELIMITER_STRING);
131
+ IncrementLexemeCount(FactQueryData(theEnv)->QUERY_DELIMITER_SYMBOL);
132
+
133
+ AddUDF(theEnv,"(query-fact)","f",0,UNBOUNDED,NULL,GetQueryFact,"GetQueryFact",NULL);
134
+
135
+ AddUDF(theEnv,"(query-fact-slot)","*",0,UNBOUNDED,NULL,GetQueryFactSlot,"GetQueryFactSlot",NULL);
136
+
137
+ AddUDF(theEnv,"any-factp","b",0,UNBOUNDED,NULL,AnyFacts,"AnyFacts",NULL);
138
+
139
+ AddUDF(theEnv,"find-fact","m",0,UNBOUNDED,NULL,QueryFindFact,"QueryFindFact",NULL);
140
+
141
+ AddUDF(theEnv,"find-all-facts","m",0,UNBOUNDED,NULL,QueryFindAllFacts,"QueryFindAllFacts",NULL);
142
+
143
+ AddUDF(theEnv,"do-for-fact","*",0,UNBOUNDED,NULL,QueryDoForFact,"QueryDoForFact",NULL);
144
+
145
+ AddUDF(theEnv,"do-for-all-facts","*",0,UNBOUNDED,NULL,QueryDoForAllFacts,"QueryDoForAllFacts",NULL);
146
+
147
+ AddUDF(theEnv,"delayed-do-for-all-facts","*",0,UNBOUNDED,NULL,DelayedQueryDoForAllFacts,"DelayedQueryDoForAllFacts",NULL);
148
+ #endif
149
+
150
+ AddFunctionParser(theEnv,"any-factp",FactParseQueryNoAction);
151
+ AddFunctionParser(theEnv,"find-fact",FactParseQueryNoAction);
152
+ AddFunctionParser(theEnv,"find-all-facts",FactParseQueryNoAction);
153
+ AddFunctionParser(theEnv,"do-for-fact",FactParseQueryAction);
154
+ AddFunctionParser(theEnv,"do-for-all-facts",FactParseQueryAction);
155
+ AddFunctionParser(theEnv,"delayed-do-for-all-facts",FactParseQueryAction);
156
+ }
157
+
158
+ /*************************************************************
159
+ NAME : GetQueryFact
160
+ DESCRIPTION : Internal function for referring to fact
161
+ array on fact-queries
162
+ INPUTS : None
163
+ RETURNS : The name of the specified fact-set member
164
+ SIDE EFFECTS : None
165
+ NOTES : H/L Syntax : ((query-fact) <index>)
166
+ *************************************************************/
167
+ void GetQueryFact(
168
+ Environment *theEnv,
169
+ UDFContext *context,
170
+ UDFValue *returnValue)
171
+ {
172
+ FACT_QUERY_CORE *core;
173
+
174
+ core = FindQueryCore(theEnv,GetFirstArgument()->integerValue->contents);
175
+
176
+ returnValue->factValue = core->solns[GetFirstArgument()->nextArg->integerValue->contents];
177
+ }
178
+
179
+ /***************************************************************************
180
+ NAME : GetQueryFactSlot
181
+ DESCRIPTION : Internal function for referring to slots of fact in
182
+ fact array on fact-queries
183
+ INPUTS : The caller's result buffer
184
+ RETURNS : Nothing useful
185
+ SIDE EFFECTS : Caller's result buffer set appropriately
186
+ NOTES : H/L Syntax : ((query-fact-slot) <index> <slot-name>)
187
+ **************************************************************************/
188
+ void GetQueryFactSlot(
189
+ Environment *theEnv,
190
+ UDFContext *context,
191
+ UDFValue *returnValue)
192
+ {
193
+ Fact *theFact;
194
+ UDFValue temp;
195
+ FACT_QUERY_CORE *core;
196
+ unsigned short position;
197
+ const char *varSlot;
198
+
199
+ returnValue->lexemeValue = FalseSymbol(theEnv);
200
+
201
+ core = FindQueryCore(theEnv,GetFirstArgument()->integerValue->contents);
202
+ theFact = core->solns[GetFirstArgument()->nextArg->integerValue->contents];
203
+ varSlot = GetFirstArgument()->nextArg->nextArg->nextArg->lexemeValue->contents;
204
+
205
+ /*=========================================*/
206
+ /* Accessing the slot value of a retracted */
207
+ /* fact generates an error. */
208
+ /*=========================================*/
209
+
210
+ if (theFact->garbage)
211
+ {
212
+ FactVarSlotErrorMessage1(theEnv,theFact,varSlot);
213
+ SetEvaluationError(theEnv,true);
214
+ return;
215
+ }
216
+
217
+ /*=========================*/
218
+ /* Retrieve the slot name. */
219
+ /*=========================*/
220
+
221
+ EvaluateExpression(theEnv,GetFirstArgument()->nextArg->nextArg,&temp);
222
+ if (temp.header->type != SYMBOL_TYPE)
223
+ {
224
+ InvalidVarSlotErrorMessage(theEnv,varSlot);
225
+ SetEvaluationError(theEnv,true);
226
+ return;
227
+ }
228
+
229
+ /*==================================================*/
230
+ /* Make sure the slot exists (the symbol implied is */
231
+ /* used for the implied slot of an ordered fact). */
232
+ /*==================================================*/
233
+
234
+ if (theFact->whichDeftemplate->implied)
235
+ {
236
+ if (strcmp(temp.lexemeValue->contents,"implied") != 0)
237
+ {
238
+ FactVarSlotErrorMessage2(theEnv,theFact,varSlot);
239
+ SetEvaluationError(theEnv,true);
240
+ return;
241
+ }
242
+ position = 0;
243
+ }
244
+
245
+ else if (FindSlot(theFact->whichDeftemplate,
246
+ (CLIPSLexeme *) temp.value,&position) == NULL)
247
+ {
248
+ FactVarSlotErrorMessage2(theEnv,theFact,varSlot);
249
+ SetEvaluationError(theEnv,true);
250
+ return;
251
+ }
252
+
253
+ returnValue->value = theFact->theProposition.contents[position].value;
254
+ if (returnValue->header->type == MULTIFIELD_TYPE)
255
+ {
256
+ returnValue->begin = 0;
257
+ returnValue->range = returnValue->multifieldValue->length;
258
+ }
259
+ }
260
+
261
+ /* =============================================================================
262
+ =============================================================================
263
+ Following are the instance query functions :
264
+
265
+ any-factp : Determines if any facts satisfy the query
266
+ find-fact : Finds first (set of) fact(s) which satisfies
267
+ the query and stores it in a multi-field
268
+ find-all-facts : Finds all (sets of) facts which satisfy the
269
+ the query and stores them in a multi-field
270
+ do-for-fact : Executes a given action for the first (set of)
271
+ fact(s) which satisfy the query
272
+ do-for-all-facts : Executes an action for all facts which satisfy
273
+ the query as they are found
274
+ delayed-do-for-all-facts : Same as above - except that the list of facts
275
+ which satisfy the query is formed before any
276
+ actions are executed
277
+
278
+ Fact candidate search algorithm :
279
+
280
+ All permutations of first restriction template facts with other
281
+ restriction template facts (Rightmost are varied first)
282
+
283
+ For any one template, fact are examined in the order they were defined
284
+
285
+ Example :
286
+ (deftemplate a (slot v))
287
+ (deftemplate b (slot v))
288
+ (deftemplate c (slot v))
289
+ (assert (a (v a1)))
290
+ (assert (a (v a2)))
291
+ (assert (b (v b1)))
292
+ (assert (b (v b2)))
293
+ (assert (c (v c1)))
294
+ (assert (c (v c2)))
295
+ (assert (d (v d1)))
296
+ (assert (d (v d2)))
297
+
298
+ (any-factp ((?a a b) (?b c)) <query>)
299
+
300
+ The permutations (?a ?b) would be examined in the following order :
301
+
302
+ (a1 c1),(a1 c2),(a2 c1),(a2 c2),
303
+ (b1 c1),(b1 c2),(b2 c1),(b2 c2)
304
+
305
+ =============================================================================
306
+ ============================================================================= */
307
+
308
+ /******************************************************************************
309
+ NAME : AnyFacts
310
+ DESCRIPTION : Determines if there any existing facts which satisfy
311
+ the query
312
+ INPUTS : None
313
+ RETURNS : True if the query is satisfied, false otherwise
314
+ SIDE EFFECTS : The query template-expressions are evaluated once,
315
+ and the query boolean-expression is evaluated
316
+ zero or more times (depending on fact restrictions
317
+ and how early the expression evaluates to true - if at all).
318
+ NOTES : H/L Syntax : See FactParseQueryNoAction()
319
+ ******************************************************************************/
320
+ void AnyFacts(
321
+ Environment *theEnv,
322
+ UDFContext *context,
323
+ UDFValue *returnValue)
324
+ {
325
+ FACT_QUERY_TEMPLATE *qtemplates;
326
+ unsigned rcnt;
327
+ bool testResult;
328
+
329
+ qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg,
330
+ "any-factp",&rcnt);
331
+ if (qtemplates == NULL)
332
+ {
333
+ returnValue->lexemeValue = FalseSymbol(theEnv);
334
+ return;
335
+ }
336
+
337
+ PushQueryCore(theEnv);
338
+ FactQueryData(theEnv)->QueryCore = get_struct(theEnv,fact_query_core);
339
+ FactQueryData(theEnv)->QueryCore->solns = (Fact **) gm2(theEnv,(sizeof(Fact *) * rcnt));
340
+ FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
341
+ testResult = TestForFirstInChain(theEnv,qtemplates,0);
342
+ FactQueryData(theEnv)->AbortQuery = false;
343
+ rm(theEnv,FactQueryData(theEnv)->QueryCore->solns,(sizeof(Fact *) * rcnt));
344
+ rtn_struct(theEnv,fact_query_core,FactQueryData(theEnv)->QueryCore);
345
+ PopQueryCore(theEnv);
346
+ DeleteQueryTemplates(theEnv,qtemplates);
347
+ returnValue->lexemeValue = CreateBoolean(theEnv,testResult);
348
+ }
349
+
350
+ /******************************************************************************
351
+ NAME : QueryFindFact
352
+ DESCRIPTION : Finds the first set of facts which satisfy the query and
353
+ stores their addresses in the user's multi-field variable
354
+ INPUTS : Caller's result buffer
355
+ RETURNS : True if the query is satisfied, false otherwise
356
+ SIDE EFFECTS : The query template-expressions are evaluated once,
357
+ and the query boolean-expression is evaluated
358
+ zero or more times (depending on fact restrictions
359
+ and how early the expression evaulates to true - if at all).
360
+ NOTES : H/L Syntax : See ParseQueryNoAction()
361
+ ******************************************************************************/
362
+ void QueryFindFact(
363
+ Environment *theEnv,
364
+ UDFContext *context,
365
+ UDFValue *returnValue)
366
+ {
367
+ FACT_QUERY_TEMPLATE *qtemplates;
368
+ unsigned rcnt,i;
369
+
370
+ returnValue->begin = 0;
371
+ returnValue->range = 0;
372
+ qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg,
373
+ "find-fact",&rcnt);
374
+ if (qtemplates == NULL)
375
+ {
376
+ returnValue->value = CreateMultifield(theEnv,0L);
377
+ return;
378
+ }
379
+ PushQueryCore(theEnv);
380
+ FactQueryData(theEnv)->QueryCore = get_struct(theEnv,fact_query_core);
381
+ FactQueryData(theEnv)->QueryCore->solns = (Fact **)
382
+ gm2(theEnv,(sizeof(Fact *) * rcnt));
383
+ FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
384
+ if (TestForFirstInChain(theEnv,qtemplates,0) == true)
385
+ {
386
+ returnValue->value = CreateMultifield(theEnv,rcnt);
387
+ returnValue->range = rcnt;
388
+ for (i = 0 ; i < rcnt ; i++)
389
+ {
390
+ returnValue->multifieldValue->contents[i].value = FactQueryData(theEnv)->QueryCore->solns[i];
391
+ }
392
+ }
393
+ else
394
+ returnValue->value = CreateMultifield(theEnv,0L);
395
+ FactQueryData(theEnv)->AbortQuery = false;
396
+ rm(theEnv,FactQueryData(theEnv)->QueryCore->solns,(sizeof(Fact *) * rcnt));
397
+ rtn_struct(theEnv,fact_query_core,FactQueryData(theEnv)->QueryCore);
398
+ PopQueryCore(theEnv);
399
+ DeleteQueryTemplates(theEnv,qtemplates);
400
+ }
401
+
402
+ /******************************************************************************
403
+ NAME : QueryFindAllFacts
404
+ DESCRIPTION : Finds all sets of facts which satisfy the query and
405
+ stores their names in the user's multi-field variable
406
+
407
+ The sets are stored sequentially :
408
+
409
+ Number of sets = (Multi-field length) / (Set length)
410
+
411
+ The first set is if the first (set length) atoms of the
412
+ multi-field variable, and so on.
413
+ INPUTS : Caller's result buffer
414
+ RETURNS : Nothing useful
415
+ SIDE EFFECTS : The query template-expressions are evaluated once,
416
+ and the query boolean-expression is evaluated
417
+ once for every fact set.
418
+ NOTES : H/L Syntax : See ParseQueryNoAction()
419
+ ******************************************************************************/
420
+ void QueryFindAllFacts(
421
+ Environment *theEnv,
422
+ UDFContext *context,
423
+ UDFValue *returnValue)
424
+ {
425
+ FACT_QUERY_TEMPLATE *qtemplates;
426
+ unsigned rcnt;
427
+ size_t i, j;
428
+
429
+ returnValue->begin = 0;
430
+ returnValue->range = 0;
431
+ qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg,
432
+ "find-all-facts",&rcnt);
433
+ if (qtemplates == NULL)
434
+ {
435
+ returnValue->value = CreateMultifield(theEnv,0L);
436
+ return;
437
+ }
438
+ PushQueryCore(theEnv);
439
+ FactQueryData(theEnv)->QueryCore = get_struct(theEnv,fact_query_core);
440
+ FactQueryData(theEnv)->QueryCore->solns = (Fact **) gm2(theEnv,(sizeof(Fact *) * rcnt));
441
+ FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
442
+ FactQueryData(theEnv)->QueryCore->action = NULL;
443
+ FactQueryData(theEnv)->QueryCore->soln_set = NULL;
444
+ FactQueryData(theEnv)->QueryCore->soln_size = rcnt;
445
+ FactQueryData(theEnv)->QueryCore->soln_cnt = 0;
446
+ TestEntireChain(theEnv,qtemplates,0);
447
+ FactQueryData(theEnv)->AbortQuery = false;
448
+ returnValue->value = CreateMultifield(theEnv,FactQueryData(theEnv)->QueryCore->soln_cnt * rcnt);
449
+ while (FactQueryData(theEnv)->QueryCore->soln_set != NULL)
450
+ {
451
+ for (i = 0 , j = returnValue->range ; i < rcnt ; i++ , j++)
452
+ {
453
+ returnValue->multifieldValue->contents[j].value = FactQueryData(theEnv)->QueryCore->soln_set->soln[i];
454
+ }
455
+ returnValue->range = j;
456
+ PopQuerySoln(theEnv);
457
+ }
458
+ rm(theEnv,FactQueryData(theEnv)->QueryCore->solns,(sizeof(Fact *) * rcnt));
459
+ rtn_struct(theEnv,fact_query_core,FactQueryData(theEnv)->QueryCore);
460
+ PopQueryCore(theEnv);
461
+ DeleteQueryTemplates(theEnv,qtemplates);
462
+ }
463
+
464
+ /******************************************************************************
465
+ NAME : QueryDoForFact
466
+ DESCRIPTION : Finds the first set of facts which satisfy the query and
467
+ executes a user-action with that set
468
+ INPUTS : None
469
+ RETURNS : Caller's result buffer
470
+ SIDE EFFECTS : The query template-expressions are evaluated once,
471
+ and the query boolean-expression is evaluated
472
+ zero or more times (depending on fact restrictions
473
+ and how early the expression evaulates to true - if at all).
474
+ Also the action expression is executed zero or once.
475
+ Caller's result buffer holds result of user-action
476
+ NOTES : H/L Syntax : See ParseQueryAction()
477
+ ******************************************************************************/
478
+ void QueryDoForFact(
479
+ Environment *theEnv,
480
+ UDFContext *context,
481
+ UDFValue *returnValue)
482
+ {
483
+ FACT_QUERY_TEMPLATE *qtemplates;
484
+ unsigned i, rcnt;
485
+
486
+ returnValue->value = FalseSymbol(theEnv);
487
+ qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg->nextArg,
488
+ "do-for-fact",&rcnt);
489
+ if (qtemplates == NULL)
490
+ return;
491
+ PushQueryCore(theEnv);
492
+ FactQueryData(theEnv)->QueryCore = get_struct(theEnv,fact_query_core);
493
+ FactQueryData(theEnv)->QueryCore->solns = (Fact **) gm2(theEnv,(sizeof(Fact *) * rcnt));
494
+ FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
495
+ FactQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
496
+
497
+ if (TestForFirstInChain(theEnv,qtemplates,0) == true)
498
+ {
499
+ for (i = 0; i < rcnt; i++)
500
+ { FactQueryData(theEnv)->QueryCore->solns[i]->patternHeader.busyCount++; }
501
+
502
+ EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->action,returnValue);
503
+
504
+ for (i = 0; i < rcnt; i++)
505
+ { FactQueryData(theEnv)->QueryCore->solns[i]->patternHeader.busyCount--; }
506
+ }
507
+
508
+ FactQueryData(theEnv)->AbortQuery = false;
509
+ ProcedureFunctionData(theEnv)->BreakFlag = false;
510
+ rm(theEnv,FactQueryData(theEnv)->QueryCore->solns,(sizeof(Fact *) * rcnt));
511
+ rtn_struct(theEnv,fact_query_core,FactQueryData(theEnv)->QueryCore);
512
+ PopQueryCore(theEnv);
513
+ DeleteQueryTemplates(theEnv,qtemplates);
514
+ }
515
+
516
+ /******************************************************************************
517
+ NAME : QueryDoForAllFacts
518
+ DESCRIPTION : Finds all sets of facts which satisfy the query and
519
+ executes a user-function for each set as it is found
520
+ INPUTS : Caller's result buffer
521
+ RETURNS : Nothing useful
522
+ SIDE EFFECTS : The query template-expressions are evaluated once,
523
+ and the query boolean-expression is evaluated
524
+ once for every fact set. Also, the action is
525
+ executed for every fact set.
526
+ Caller's result buffer holds result of last action executed.
527
+ NOTES : H/L Syntax : See FactParseQueryAction()
528
+ ******************************************************************************/
529
+ void QueryDoForAllFacts(
530
+ Environment *theEnv,
531
+ UDFContext *context,
532
+ UDFValue *returnValue)
533
+ {
534
+ FACT_QUERY_TEMPLATE *qtemplates;
535
+ unsigned rcnt;
536
+
537
+ returnValue->lexemeValue = FalseSymbol(theEnv);
538
+
539
+ qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg->nextArg,
540
+ "do-for-all-facts",&rcnt);
541
+ if (qtemplates == NULL)
542
+ return;
543
+
544
+ PushQueryCore(theEnv);
545
+ FactQueryData(theEnv)->QueryCore = get_struct(theEnv,fact_query_core);
546
+ FactQueryData(theEnv)->QueryCore->solns = (Fact **) gm2(theEnv,(sizeof(Fact *) * rcnt));
547
+ FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
548
+ FactQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
549
+ FactQueryData(theEnv)->QueryCore->result = returnValue;
550
+ RetainUDFV(theEnv,FactQueryData(theEnv)->QueryCore->result);
551
+ TestEntireChain(theEnv,qtemplates,0);
552
+ ReleaseUDFV(theEnv,FactQueryData(theEnv)->QueryCore->result);
553
+
554
+ FactQueryData(theEnv)->AbortQuery = false;
555
+ ProcedureFunctionData(theEnv)->BreakFlag = false;
556
+ rm(theEnv,FactQueryData(theEnv)->QueryCore->solns,(sizeof(Fact *) * rcnt));
557
+ rtn_struct(theEnv,fact_query_core,FactQueryData(theEnv)->QueryCore);
558
+ PopQueryCore(theEnv);
559
+ DeleteQueryTemplates(theEnv,qtemplates);
560
+ }
561
+
562
+ /******************************************************************************
563
+ NAME : DelayedQueryDoForAllFacts
564
+ DESCRIPTION : Finds all sets of facts which satisfy the query and
565
+ and exceutes a user-action for each set
566
+
567
+ This function differs from QueryDoForAllFacts() in
568
+ that it forms the complete list of query satisfactions
569
+ BEFORE executing any actions.
570
+ INPUTS : Caller's result buffer
571
+ RETURNS : Nothing useful
572
+ SIDE EFFECTS : The query template-expressions are evaluated once,
573
+ and the query boolean-expression is evaluated
574
+ once for every fact set. The action is executed
575
+ for evry query satisfaction.
576
+ Caller's result buffer holds result of last action executed.
577
+ NOTES : H/L Syntax : See FactParseQueryNoAction()
578
+ ******************************************************************************/
579
+ void DelayedQueryDoForAllFacts(
580
+ Environment *theEnv,
581
+ UDFContext *context,
582
+ UDFValue *returnValue)
583
+ {
584
+ FACT_QUERY_TEMPLATE *qtemplates;
585
+ unsigned rcnt;
586
+ unsigned i;
587
+ GCBlock gcb;
588
+ FACT_QUERY_SOLN *theSet;
589
+
590
+ returnValue->value = FalseSymbol(theEnv);
591
+ qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg->nextArg,
592
+ "delayed-do-for-all-facts",&rcnt);
593
+ if (qtemplates == NULL)
594
+ return;
595
+
596
+ PushQueryCore(theEnv);
597
+ FactQueryData(theEnv)->QueryCore = get_struct(theEnv,fact_query_core);
598
+ FactQueryData(theEnv)->QueryCore->solns = (Fact **) gm2(theEnv,(sizeof(Fact *) * rcnt));
599
+ FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
600
+ FactQueryData(theEnv)->QueryCore->action = NULL;
601
+ FactQueryData(theEnv)->QueryCore->soln_set = NULL;
602
+ FactQueryData(theEnv)->QueryCore->soln_size = rcnt;
603
+ FactQueryData(theEnv)->QueryCore->soln_cnt = 0;
604
+ TestEntireChain(theEnv,qtemplates,0);
605
+ FactQueryData(theEnv)->AbortQuery = false;
606
+ FactQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
607
+
608
+ /*==============================================================*/
609
+ /* Increment the busy count for all facts in the solution sets. */
610
+ /*==============================================================*/
611
+
612
+ GCBlockStart(theEnv,&gcb);
613
+
614
+ for (theSet = FactQueryData(theEnv)->QueryCore->soln_set;
615
+ theSet != NULL;
616
+ theSet = theSet->nxt)
617
+ {
618
+ for (i = 0; i < rcnt; i++)
619
+ { theSet->soln[i]->patternHeader.busyCount++; }
620
+ }
621
+
622
+ /*=====================*/
623
+ /* Perform the action. */
624
+ /*=====================*/
625
+
626
+ for (theSet = FactQueryData(theEnv)->QueryCore->soln_set;
627
+ theSet != NULL; )
628
+ {
629
+ for (i = 0 ; i < rcnt ; i++)
630
+ {
631
+ if (theSet->soln[i]->garbage)
632
+ { goto nextSet; }
633
+ FactQueryData(theEnv)->QueryCore->solns[i] = theSet->soln[i];
634
+ }
635
+
636
+ EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->action,returnValue);
637
+
638
+ if (EvaluationData(theEnv)->HaltExecution || ProcedureFunctionData(theEnv)->BreakFlag || ProcedureFunctionData(theEnv)->ReturnFlag)
639
+ { break; }
640
+
641
+ CleanCurrentGarbageFrame(theEnv,returnValue);
642
+ CallPeriodicTasks(theEnv);
643
+
644
+ nextSet: theSet = theSet->nxt;
645
+ }
646
+
647
+ /*==============================================================*/
648
+ /* Decrement the busy count for all facts in the solution sets. */
649
+ /*==============================================================*/
650
+
651
+ for (theSet = FactQueryData(theEnv)->QueryCore->soln_set;
652
+ theSet != NULL;
653
+ theSet = theSet->nxt)
654
+ {
655
+ for (i = 0; i < rcnt; i++)
656
+ { theSet->soln[i]->patternHeader.busyCount--; }
657
+ }
658
+
659
+ GCBlockEndUDF(theEnv,&gcb,returnValue);
660
+ CallPeriodicTasks(theEnv);
661
+
662
+ /*==================================*/
663
+ /* Deallocate the query structures. */
664
+ /*==================================*/
665
+
666
+ while (FactQueryData(theEnv)->QueryCore->soln_set != NULL)
667
+ { PopQuerySoln(theEnv); }
668
+
669
+ ProcedureFunctionData(theEnv)->BreakFlag = false;
670
+ rm(theEnv,FactQueryData(theEnv)->QueryCore->solns,(sizeof(Fact *) * rcnt));
671
+ rtn_struct(theEnv,fact_query_core,FactQueryData(theEnv)->QueryCore);
672
+ PopQueryCore(theEnv);
673
+ DeleteQueryTemplates(theEnv,qtemplates);
674
+ }
675
+
676
+ /* =========================================
677
+ *****************************************
678
+ INTERNALLY VISIBLE FUNCTIONS
679
+ =========================================
680
+ ***************************************** */
681
+
682
+ /*******************************************************
683
+ NAME : PushQueryCore
684
+ DESCRIPTION : Pushes the current QueryCore onto stack
685
+ INPUTS : None
686
+ RETURNS : Nothing useful
687
+ SIDE EFFECTS : Allocates new stack node and changes
688
+ QueryCoreStack
689
+ NOTES : None
690
+ *******************************************************/
691
+ static void PushQueryCore(
692
+ Environment *theEnv)
693
+ {
694
+ FACT_QUERY_STACK *qptr;
695
+
696
+ qptr = get_struct(theEnv,fact_query_stack);
697
+ qptr->core = FactQueryData(theEnv)->QueryCore;
698
+ qptr->nxt = FactQueryData(theEnv)->QueryCoreStack;
699
+ FactQueryData(theEnv)->QueryCoreStack = qptr;
700
+ }
701
+
702
+ /******************************************************
703
+ NAME : PopQueryCore
704
+ DESCRIPTION : Pops top of QueryCore stack and
705
+ restores QueryCore to this core
706
+ INPUTS : None
707
+ RETURNS : Nothing useful
708
+ SIDE EFFECTS : Stack node deallocated, QueryCoreStack
709
+ changed and QueryCore reset
710
+ NOTES : Assumes stack is not empty
711
+ ******************************************************/
712
+ static void PopQueryCore(
713
+ Environment *theEnv)
714
+ {
715
+ FACT_QUERY_STACK *qptr;
716
+
717
+ FactQueryData(theEnv)->QueryCore = FactQueryData(theEnv)->QueryCoreStack->core;
718
+ qptr = FactQueryData(theEnv)->QueryCoreStack;
719
+ FactQueryData(theEnv)->QueryCoreStack = FactQueryData(theEnv)->QueryCoreStack->nxt;
720
+ rtn_struct(theEnv,fact_query_stack,qptr);
721
+ }
722
+
723
+ /***************************************************
724
+ NAME : FindQueryCore
725
+ DESCRIPTION : Looks up a QueryCore Stack Frame
726
+ Depth 0 is current frame
727
+ 1 is next deepest, etc.
728
+ INPUTS : Depth
729
+ RETURNS : Address of query core stack frame
730
+ SIDE EFFECTS : None
731
+ NOTES : None
732
+ ***************************************************/
733
+ static FACT_QUERY_CORE *FindQueryCore(
734
+ Environment *theEnv,
735
+ long long depth)
736
+ {
737
+ FACT_QUERY_STACK *qptr;
738
+
739
+ if (depth == 0)
740
+ return FactQueryData(theEnv)->QueryCore;
741
+
742
+ qptr = FactQueryData(theEnv)->QueryCoreStack;
743
+ while (depth > 1)
744
+ {
745
+ qptr = qptr->nxt;
746
+ depth--;
747
+ }
748
+
749
+ return qptr->core;
750
+ }
751
+
752
+ /**********************************************************
753
+ NAME : DetermineQueryTemplates
754
+ DESCRIPTION : Builds a list of templates to be used in
755
+ fact queries - uses parse form.
756
+ INPUTS : 1) The parse template expression chain
757
+ 2) The name of the function being executed
758
+ 3) Caller's buffer for restriction count
759
+ (# of separate lists)
760
+ RETURNS : The query list, or NULL on errors
761
+ SIDE EFFECTS : Memory allocated for list
762
+ Busy count incremented for all templates
763
+ NOTES : Each restriction is linked by nxt pointer,
764
+ multiple templates in a restriction are
765
+ linked by the chain pointer.
766
+ Rcnt caller's buffer is set to reflect the
767
+ total number of chains
768
+ Assumes templateExp is not NULL and that each
769
+ restriction chain is terminated with
770
+ the QUERY_DELIMITER_SYMBOL "(QDS)"
771
+ **********************************************************/
772
+ static FACT_QUERY_TEMPLATE *DetermineQueryTemplates(
773
+ Environment *theEnv,
774
+ Expression *templateExp,
775
+ const char *func,
776
+ unsigned *rcnt)
777
+ {
778
+ FACT_QUERY_TEMPLATE *clist = NULL, *cnxt = NULL, *cchain = NULL, *tmp;
779
+ bool new_list = false;
780
+ UDFValue temp;
781
+ Deftemplate *theDeftemplate;
782
+
783
+ *rcnt = 0;
784
+ while (templateExp != NULL)
785
+ {
786
+ theDeftemplate = NULL;
787
+
788
+ if (templateExp->type == DEFTEMPLATE_PTR)
789
+ { theDeftemplate = (Deftemplate *) templateExp->value; }
790
+ else if (EvaluateExpression(theEnv,templateExp,&temp))
791
+ {
792
+ DeleteQueryTemplates(theEnv,clist);
793
+ return NULL;
794
+ }
795
+
796
+ if ((theDeftemplate == NULL) &&
797
+ (temp.value == (void *) FactQueryData(theEnv)->QUERY_DELIMITER_SYMBOL))
798
+ {
799
+ new_list = true;
800
+ (*rcnt)++;
801
+ }
802
+ else if ((tmp = FormChain(theEnv,func,theDeftemplate,&temp)) != NULL)
803
+ {
804
+ if (clist == NULL)
805
+ { clist = cnxt = cchain = tmp; }
806
+ else if (new_list == true)
807
+ {
808
+ new_list = false;
809
+ cnxt->nxt = tmp;
810
+ cnxt = cchain = tmp;
811
+ }
812
+ else
813
+ { cchain->chain = tmp; }
814
+
815
+ while (cchain->chain != NULL)
816
+ { cchain = cchain->chain; }
817
+ }
818
+ else
819
+ {
820
+ SyntaxErrorMessage(theEnv,"fact-set query class restrictions");
821
+ DeleteQueryTemplates(theEnv,clist);
822
+ SetEvaluationError(theEnv,true);
823
+ return NULL;
824
+ }
825
+
826
+ templateExp = templateExp->nextArg;
827
+ }
828
+
829
+ return clist;
830
+ }
831
+
832
+ /*************************************************************
833
+ NAME : FormChain
834
+ DESCRIPTION : Builds a list of deftemplates to be used in
835
+ fact queries - uses parse form.
836
+ INPUTS : 1) Name of calling function for error msgs
837
+ 2) Data object - must be a symbol or a
838
+ multifield value containing all symbols
839
+ The symbols must be names of existing templates
840
+ RETURNS : The query chain, or NULL on errors
841
+ SIDE EFFECTS : Memory allocated for chain
842
+ Busy count incremented for all templates
843
+ NOTES : None
844
+ *************************************************************/
845
+ static FACT_QUERY_TEMPLATE *FormChain(
846
+ Environment *theEnv,
847
+ const char *func,
848
+ Deftemplate *theDeftemplate,
849
+ UDFValue *val)
850
+ {
851
+ Deftemplate *templatePtr;
852
+ FACT_QUERY_TEMPLATE *head, *bot, *tmp;
853
+ size_t i; /* 6.04 Bug Fix */
854
+ const char *templateName;
855
+ unsigned int count;
856
+
857
+ if (theDeftemplate != NULL)
858
+ {
859
+ IncrementDeftemplateBusyCount(theEnv,theDeftemplate);
860
+ head = get_struct(theEnv,fact_query_template);
861
+ head->templatePtr = theDeftemplate;
862
+
863
+ head->chain = NULL;
864
+ head->nxt = NULL;
865
+ return head;
866
+ }
867
+
868
+ if (val->header->type == SYMBOL_TYPE)
869
+ {
870
+ /*============================================*/
871
+ /* Allow instance-set query restrictions to */
872
+ /* have module specifier as part of the class */
873
+ /* name, but search imported defclasses too */
874
+ /* if a module specifier is not given. */
875
+ /*============================================*/
876
+
877
+ templatePtr = (Deftemplate *)
878
+ FindImportedConstruct(theEnv,"deftemplate",NULL,val->lexemeValue->contents,
879
+ &count,true,NULL);
880
+
881
+ if (templatePtr == NULL)
882
+ {
883
+ CantFindItemInFunctionErrorMessage(theEnv,"deftemplate",val->lexemeValue->contents,func,true);
884
+ return NULL;
885
+ }
886
+
887
+ IncrementDeftemplateBusyCount(theEnv,templatePtr);
888
+ head = get_struct(theEnv,fact_query_template);
889
+ head->templatePtr = templatePtr;
890
+
891
+ head->chain = NULL;
892
+ head->nxt = NULL;
893
+ return head;
894
+ }
895
+
896
+ if (val->header->type == MULTIFIELD_TYPE)
897
+ {
898
+ head = bot = NULL;
899
+
900
+ for (i = val->begin ; i < (val->begin + val->range) ; i++)
901
+ {
902
+ if (val->multifieldValue->contents[i].header->type == SYMBOL_TYPE)
903
+ {
904
+ templateName = val->multifieldValue->contents[i].lexemeValue->contents;
905
+
906
+ templatePtr = (Deftemplate *)
907
+ FindImportedConstruct(theEnv,"deftemplate",NULL,templateName,
908
+ &count,true,NULL);
909
+
910
+ if (templatePtr == NULL)
911
+ {
912
+ CantFindItemInFunctionErrorMessage(theEnv,"deftemplate",templateName,func,true);
913
+ DeleteQueryTemplates(theEnv,head);
914
+ return NULL;
915
+ }
916
+ }
917
+ else
918
+ {
919
+ DeleteQueryTemplates(theEnv,head);
920
+ return NULL;
921
+ }
922
+
923
+ IncrementDeftemplateBusyCount(theEnv,templatePtr);
924
+ tmp = get_struct(theEnv,fact_query_template);
925
+ tmp->templatePtr = templatePtr;
926
+
927
+ tmp->chain = NULL;
928
+ tmp->nxt = NULL;
929
+
930
+ if (head == NULL)
931
+ { head = tmp; }
932
+ else
933
+ { bot->chain = tmp; }
934
+
935
+ bot = tmp;
936
+ }
937
+
938
+ return head;
939
+ }
940
+ return NULL;
941
+ }
942
+
943
+ /******************************************************
944
+ NAME : DeleteQueryTemplates
945
+ DESCRIPTION : Deletes a query class-list
946
+ INPUTS : The query list address
947
+ RETURNS : Nothing useful
948
+ SIDE EFFECTS : Nodes deallocated
949
+ Busy count decremented for all templates
950
+ NOTES : None
951
+ ******************************************************/
952
+ static void DeleteQueryTemplates(
953
+ Environment *theEnv,
954
+ FACT_QUERY_TEMPLATE *qlist)
955
+ {
956
+ FACT_QUERY_TEMPLATE *tmp;
957
+
958
+ while (qlist != NULL)
959
+ {
960
+ while (qlist->chain != NULL)
961
+ {
962
+ tmp = qlist->chain;
963
+ qlist->chain = qlist->chain->chain;
964
+ DecrementDeftemplateBusyCount(theEnv,tmp->templatePtr);
965
+ rtn_struct(theEnv,fact_query_template,tmp);
966
+ }
967
+ tmp = qlist;
968
+ qlist = qlist->nxt;
969
+ DecrementDeftemplateBusyCount(theEnv,tmp->templatePtr);
970
+ rtn_struct(theEnv,fact_query_template,tmp);
971
+ }
972
+ }
973
+
974
+ /************************************************************
975
+ NAME : TestForFirstInChain
976
+ DESCRIPTION : Processes all templates in a restriction chain
977
+ until success or done
978
+ INPUTS : 1) The current chain
979
+ 2) The index of the chain restriction
980
+ (e.g. the 4th query-variable)
981
+ RETURNS : True if query succeeds, false otherwise
982
+ SIDE EFFECTS : Sets current restriction class
983
+ Fact variable values set
984
+ NOTES : None
985
+ ************************************************************/
986
+ static bool TestForFirstInChain(
987
+ Environment *theEnv,
988
+ FACT_QUERY_TEMPLATE *qchain,
989
+ unsigned indx)
990
+ {
991
+ FACT_QUERY_TEMPLATE *qptr;
992
+
993
+ FactQueryData(theEnv)->AbortQuery = true;
994
+ for (qptr = qchain ; qptr != NULL ; qptr = qptr->chain)
995
+ {
996
+ FactQueryData(theEnv)->AbortQuery = false;
997
+
998
+ if (TestForFirstFactInTemplate(theEnv,qptr->templatePtr,qchain,indx))
999
+ { return true; }
1000
+
1001
+ if ((EvaluationData(theEnv)->HaltExecution == true) || (FactQueryData(theEnv)->AbortQuery == true))
1002
+ return false;
1003
+ }
1004
+ return false;
1005
+ }
1006
+
1007
+ /*****************************************************************
1008
+ NAME : TestForFirstFactInTemplate
1009
+ DESCRIPTION : Processes all facts in a template
1010
+ INPUTS : 1) Visitation traversal id
1011
+ 2) The template
1012
+ 3) The current template restriction chain
1013
+ 4) The index of the current restriction
1014
+ RETURNS : True if query succeeds, false otherwise
1015
+ SIDE EFFECTS : Fact variable values set
1016
+ NOTES : None
1017
+ *****************************************************************/
1018
+ static bool TestForFirstFactInTemplate(
1019
+ Environment *theEnv,
1020
+ Deftemplate *templatePtr,
1021
+ FACT_QUERY_TEMPLATE *qchain,
1022
+ unsigned indx)
1023
+ {
1024
+ Fact *theFact;
1025
+ UDFValue temp;
1026
+ GCBlock gcb;
1027
+ unsigned j;
1028
+
1029
+ GCBlockStart(theEnv,&gcb);
1030
+
1031
+ theFact = templatePtr->factList;
1032
+ while (theFact != NULL)
1033
+ {
1034
+ FactQueryData(theEnv)->QueryCore->solns[indx] = theFact;
1035
+ if (qchain->nxt != NULL)
1036
+ {
1037
+ theFact->patternHeader.busyCount++;
1038
+ if (TestForFirstInChain(theEnv,qchain->nxt,indx+1) == true)
1039
+ {
1040
+ theFact->patternHeader.busyCount--;
1041
+ break;
1042
+ }
1043
+ theFact->patternHeader.busyCount--;
1044
+ if ((EvaluationData(theEnv)->HaltExecution == true) || (FactQueryData(theEnv)->AbortQuery == true))
1045
+ break;
1046
+ }
1047
+ else
1048
+ {
1049
+ for (j = 0; j < indx; j++)
1050
+ {
1051
+ if (FactQueryData(theEnv)->QueryCore->solns[j]->garbage)
1052
+ {
1053
+ theFact = NULL;
1054
+ goto endTest;
1055
+ }
1056
+ }
1057
+
1058
+ theFact->patternHeader.busyCount++;
1059
+
1060
+ EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->query,&temp);
1061
+
1062
+ CleanCurrentGarbageFrame(theEnv,NULL);
1063
+ CallPeriodicTasks(theEnv);
1064
+
1065
+ theFact->patternHeader.busyCount--;
1066
+
1067
+ if (EvaluationData(theEnv)->HaltExecution == true)
1068
+ { break; }
1069
+
1070
+ if (temp.value != FalseSymbol(theEnv))
1071
+ { break; }
1072
+ }
1073
+
1074
+ /*================================================*/
1075
+ /* Get the next fact that has not been retracted. */
1076
+ /*================================================*/
1077
+
1078
+ theFact = theFact->nextTemplateFact;
1079
+ while ((theFact != NULL) ? (theFact->garbage == 1) : false)
1080
+ { theFact = theFact->nextTemplateFact; }
1081
+ }
1082
+
1083
+ endTest:
1084
+
1085
+ GCBlockEnd(theEnv,&gcb);
1086
+ CallPeriodicTasks(theEnv);
1087
+
1088
+ if (theFact != NULL)
1089
+ return(((EvaluationData(theEnv)->HaltExecution == true) || (FactQueryData(theEnv)->AbortQuery == true))
1090
+ ? false : true);
1091
+
1092
+ return false;
1093
+ }
1094
+
1095
+ /************************************************************
1096
+ NAME : TestEntireChain
1097
+ DESCRIPTION : Processes all templates in a restriction chain
1098
+ until done
1099
+ INPUTS : 1) The current chain
1100
+ 2) The index of the chain restriction
1101
+ (i.e. the 4th query-variable)
1102
+ RETURNS : Nothing useful
1103
+ SIDE EFFECTS : Sets current restriction template
1104
+ Query fact variables set
1105
+ Solution sets stored in global list
1106
+ NOTES : None
1107
+ ************************************************************/
1108
+ static void TestEntireChain(
1109
+ Environment *theEnv,
1110
+ FACT_QUERY_TEMPLATE *qchain,
1111
+ unsigned indx)
1112
+ {
1113
+ FACT_QUERY_TEMPLATE *qptr;
1114
+
1115
+ FactQueryData(theEnv)->AbortQuery = true;
1116
+ for (qptr = qchain ; qptr != NULL ; qptr = qptr->chain)
1117
+ {
1118
+ FactQueryData(theEnv)->AbortQuery = false;
1119
+
1120
+ TestEntireTemplate(theEnv,qptr->templatePtr,qchain,indx);
1121
+
1122
+ if ((EvaluationData(theEnv)->HaltExecution == true) || (FactQueryData(theEnv)->AbortQuery == true))
1123
+ return;
1124
+ }
1125
+ }
1126
+
1127
+ /*****************************************************************
1128
+ NAME : TestEntireTemplate
1129
+ DESCRIPTION : Processes all facts in a template
1130
+ INPUTS : 1) The module for which templates tested must be
1131
+ in scope
1132
+ 3) The template
1133
+ 4) The current template restriction chain
1134
+ 5) The index of the current restriction
1135
+ RETURNS : Nothing useful
1136
+ SIDE EFFECTS : Instance variable values set
1137
+ Solution sets stored in global list
1138
+ NOTES : None
1139
+ *****************************************************************/
1140
+ static void TestEntireTemplate(
1141
+ Environment *theEnv,
1142
+ Deftemplate *templatePtr,
1143
+ FACT_QUERY_TEMPLATE *qchain,
1144
+ unsigned indx)
1145
+ {
1146
+ Fact *theFact;
1147
+ UDFValue temp;
1148
+ GCBlock gcb;
1149
+ unsigned j;
1150
+
1151
+ GCBlockStart(theEnv,&gcb);
1152
+
1153
+ theFact = templatePtr->factList;
1154
+ while (theFact != NULL)
1155
+ {
1156
+ FactQueryData(theEnv)->QueryCore->solns[indx] = theFact;
1157
+ if (qchain->nxt != NULL)
1158
+ {
1159
+ theFact->patternHeader.busyCount++;
1160
+ TestEntireChain(theEnv,qchain->nxt,indx+1);
1161
+ theFact->patternHeader.busyCount--;
1162
+ if ((EvaluationData(theEnv)->HaltExecution == true) || (FactQueryData(theEnv)->AbortQuery == true))
1163
+ break;
1164
+ }
1165
+ else
1166
+ {
1167
+ for (j = 0; j < indx; j++)
1168
+ {
1169
+ if (FactQueryData(theEnv)->QueryCore->solns[j]->garbage)
1170
+ { goto endTest; }
1171
+ }
1172
+
1173
+ theFact->patternHeader.busyCount++;
1174
+
1175
+ EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->query,&temp);
1176
+
1177
+ theFact->patternHeader.busyCount--;
1178
+ if (EvaluationData(theEnv)->HaltExecution == true)
1179
+ break;
1180
+ if (temp.value != FalseSymbol(theEnv))
1181
+ {
1182
+ if (FactQueryData(theEnv)->QueryCore->action != NULL)
1183
+ {
1184
+ theFact->patternHeader.busyCount++;
1185
+ ReleaseUDFV(theEnv,FactQueryData(theEnv)->QueryCore->result);
1186
+ EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->action,FactQueryData(theEnv)->QueryCore->result);
1187
+ RetainUDFV(theEnv,FactQueryData(theEnv)->QueryCore->result);
1188
+
1189
+ theFact->patternHeader.busyCount--;
1190
+ if (ProcedureFunctionData(theEnv)->BreakFlag || ProcedureFunctionData(theEnv)->ReturnFlag)
1191
+ {
1192
+ FactQueryData(theEnv)->AbortQuery = true;
1193
+ break;
1194
+ }
1195
+ if (EvaluationData(theEnv)->HaltExecution == true)
1196
+ break;
1197
+ }
1198
+ else
1199
+ AddSolution(theEnv);
1200
+ }
1201
+ }
1202
+
1203
+ theFact = theFact->nextTemplateFact;
1204
+ while ((theFact != NULL) ? (theFact->garbage == 1) : false)
1205
+ { theFact = theFact->nextTemplateFact; }
1206
+
1207
+ CleanCurrentGarbageFrame(theEnv,NULL);
1208
+ CallPeriodicTasks(theEnv);
1209
+ }
1210
+
1211
+ endTest:
1212
+
1213
+ GCBlockEnd(theEnv,&gcb);
1214
+ CallPeriodicTasks(theEnv);
1215
+ }
1216
+
1217
+ /***************************************************************************
1218
+ NAME : AddSolution
1219
+ DESCRIPTION : Adds the current fact set to a global list of
1220
+ solutions
1221
+ INPUTS : None
1222
+ RETURNS : Nothing useful
1223
+ SIDE EFFECTS : Global list and count updated
1224
+ NOTES : Solutions are stored as sequential arrays of Fact *
1225
+ ***************************************************************************/
1226
+ static void AddSolution(
1227
+ Environment *theEnv)
1228
+ {
1229
+ FACT_QUERY_SOLN *new_soln;
1230
+ unsigned i;
1231
+
1232
+ new_soln = (FACT_QUERY_SOLN *) gm2(theEnv,sizeof(FACT_QUERY_SOLN));
1233
+ new_soln->soln = (Fact **)
1234
+ gm2(theEnv,(sizeof(Fact *) * (FactQueryData(theEnv)->QueryCore->soln_size)));
1235
+ for (i = 0 ; i < FactQueryData(theEnv)->QueryCore->soln_size ; i++)
1236
+ new_soln->soln[i] = FactQueryData(theEnv)->QueryCore->solns[i];
1237
+ new_soln->nxt = NULL;
1238
+ if (FactQueryData(theEnv)->QueryCore->soln_set == NULL)
1239
+ FactQueryData(theEnv)->QueryCore->soln_set = new_soln;
1240
+ else
1241
+ FactQueryData(theEnv)->QueryCore->soln_bottom->nxt = new_soln;
1242
+ FactQueryData(theEnv)->QueryCore->soln_bottom = new_soln;
1243
+ FactQueryData(theEnv)->QueryCore->soln_cnt++;
1244
+ }
1245
+
1246
+ /***************************************************
1247
+ NAME : PopQuerySoln
1248
+ DESCRIPTION : Deallocates the topmost solution
1249
+ set for an fact-set query
1250
+ INPUTS : None
1251
+ RETURNS : Nothing useful
1252
+ SIDE EFFECTS : Solution set deallocated
1253
+ NOTES : Assumes QueryCore->soln_set != 0
1254
+ ***************************************************/
1255
+ static void PopQuerySoln(
1256
+ Environment *theEnv)
1257
+ {
1258
+ FactQueryData(theEnv)->QueryCore->soln_bottom = FactQueryData(theEnv)->QueryCore->soln_set;
1259
+ FactQueryData(theEnv)->QueryCore->soln_set = FactQueryData(theEnv)->QueryCore->soln_set->nxt;
1260
+ rm(theEnv,FactQueryData(theEnv)->QueryCore->soln_bottom->soln,
1261
+ (sizeof(Fact *) * FactQueryData(theEnv)->QueryCore->soln_size));
1262
+ rm(theEnv,FactQueryData(theEnv)->QueryCore->soln_bottom,sizeof(FACT_QUERY_SOLN));
1263
+ }
1264
+
1265
+ #endif
1266
+
1267
+