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