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,826 @@
1
+ /*******************************************************/
2
+ /* "C" Language Integrated Production System */
3
+ /* */
4
+ /* CLIPS Version 6.40 10/03/19 */
5
+ /* */
6
+ /* CONSTRAINT CHECKING MODULE */
7
+ /*******************************************************/
8
+
9
+ /*************************************************************/
10
+ /* Purpose: Provides functions for constraint checking of */
11
+ /* data types. */
12
+ /* */
13
+ /* Principal Programmer(s): */
14
+ /* Gary D. Riley */
15
+ /* */
16
+ /* Contributing Programmer(s): */
17
+ /* Brian Dantes */
18
+ /* */
19
+ /* Revision History: */
20
+ /* */
21
+ /* 6.23: Changed name of variable exp to theExp */
22
+ /* because of Unix compiler warnings of shadowed */
23
+ /* definitions. */
24
+ /* */
25
+ /* 6.24: Added allowed-classes slot facet. */
26
+ /* */
27
+ /* Renamed BOOLEAN macro type to intBool. */
28
+ /* */
29
+ /* 6.30: Removed conditional code for unsupported */
30
+ /* compilers/operating systems (IBM_MCW and */
31
+ /* MAC_MCW). */
32
+ /* */
33
+ /* Support for long long integers. */
34
+ /* */
35
+ /* Added const qualifiers to remove C++ */
36
+ /* deprecation warnings. */
37
+ /* */
38
+ /* Dynamic constraint checking for the */
39
+ /* allowed-classes constraint now searches */
40
+ /* imported modules. */
41
+ /* */
42
+ /* 6.40: Pragma once and other inclusion changes. */
43
+ /* */
44
+ /* Added support for booleans with <stdbool.h>. */
45
+ /* */
46
+ /* Removed use of void pointers for specific */
47
+ /* data structures. */
48
+ /* */
49
+ /* UDF redesign. */
50
+ /* */
51
+ /* Eval support for run time and bload only. */
52
+ /* */
53
+ /*************************************************************/
54
+
55
+ #include <stdio.h>
56
+ #include <stdlib.h>
57
+
58
+ #include "setup.h"
59
+
60
+ #include "cstrnutl.h"
61
+ #include "envrnmnt.h"
62
+ #include "extnfunc.h"
63
+ #include "multifld.h"
64
+ #include "prntutil.h"
65
+ #include "router.h"
66
+
67
+ #if OBJECT_SYSTEM
68
+ #include "classcom.h"
69
+ #include "classexm.h"
70
+ #include "inscom.h"
71
+ #include "insfun.h"
72
+ #endif
73
+
74
+ #include "cstrnchk.h"
75
+
76
+ /***************************************/
77
+ /* LOCAL INTERNAL FUNCTION DEFINITIONS */
78
+ /***************************************/
79
+
80
+ static bool CheckRangeAgainstCardinalityConstraint(Environment *,int,int,CONSTRAINT_RECORD *);
81
+ static bool CheckFunctionReturnType(unsigned,CONSTRAINT_RECORD *);
82
+ static bool CheckTypeConstraint(int,CONSTRAINT_RECORD *);
83
+ static bool CheckRangeConstraint(Environment *,int,void *,CONSTRAINT_RECORD *);
84
+ static void PrintRange(Environment *,const char *,CONSTRAINT_RECORD *);
85
+
86
+ /******************************************************/
87
+ /* CheckFunctionReturnType: Checks a functions return */
88
+ /* type against a set of permissable return values. */
89
+ /* Returns true if the return type is included */
90
+ /* among the permissible values, otherwise false. */
91
+ /******************************************************/
92
+ static bool CheckFunctionReturnType(
93
+ unsigned functionReturnType,
94
+ CONSTRAINT_RECORD *constraints)
95
+ {
96
+ if (constraints == NULL) return true;
97
+
98
+ if (constraints->anyAllowed) return true;
99
+
100
+ if (constraints->voidAllowed)
101
+ { if (functionReturnType & VOID_BIT) return true; }
102
+
103
+ if (constraints->symbolsAllowed)
104
+ { if (functionReturnType & (SYMBOL_BIT | BOOLEAN_BIT)) return true; }
105
+
106
+ if (constraints->stringsAllowed)
107
+ { if (functionReturnType & STRING_BIT) return true; }
108
+
109
+ if (constraints->instanceNamesAllowed)
110
+ { if (functionReturnType & INSTANCE_NAME_BIT) return true; }
111
+
112
+ if (constraints->floatsAllowed)
113
+ { if (functionReturnType & FLOAT_BIT) return true; }
114
+
115
+ if (constraints->integersAllowed)
116
+ { if (functionReturnType & INTEGER_BIT) return true; }
117
+
118
+ if (constraints->multifieldsAllowed)
119
+ { if (functionReturnType & MULTIFIELD_BIT) return true; }
120
+
121
+ if (constraints->externalAddressesAllowed)
122
+ { if (functionReturnType & EXTERNAL_ADDRESS_BIT) return true; }
123
+
124
+ if (constraints->factAddressesAllowed)
125
+ { if (functionReturnType & FACT_ADDRESS_BIT) return true; }
126
+
127
+ if (constraints->instanceAddressesAllowed)
128
+ { if (functionReturnType & INSTANCE_ADDRESS_BIT) return true; }
129
+
130
+ return false;
131
+ }
132
+
133
+ /****************************************************/
134
+ /* CheckTypeConstraint: Determines if a primitive */
135
+ /* data type satisfies the type constraint fields */
136
+ /* of aconstraint record. */
137
+ /****************************************************/
138
+ static bool CheckTypeConstraint(
139
+ int type,
140
+ CONSTRAINT_RECORD *constraints)
141
+ {
142
+ if (type == VOID_TYPE) return false;
143
+
144
+ if (constraints == NULL) return true;
145
+
146
+ if (constraints->anyAllowed == true) return true;
147
+
148
+ if ((type == SYMBOL_TYPE) && (constraints->symbolsAllowed != true))
149
+ { return false; }
150
+
151
+ if ((type == STRING_TYPE) && (constraints->stringsAllowed != true))
152
+ { return false; }
153
+
154
+ if ((type == FLOAT_TYPE) && (constraints->floatsAllowed != true))
155
+ { return false; }
156
+
157
+ if ((type == INTEGER_TYPE) && (constraints->integersAllowed != true))
158
+ { return false; }
159
+
160
+ #if OBJECT_SYSTEM
161
+ if ((type == INSTANCE_NAME_TYPE) && (constraints->instanceNamesAllowed != true))
162
+ { return false; }
163
+
164
+ if ((type == INSTANCE_ADDRESS_TYPE) && (constraints->instanceAddressesAllowed != true))
165
+ { return false; }
166
+ #endif
167
+
168
+ if ((type == EXTERNAL_ADDRESS_TYPE) && (constraints->externalAddressesAllowed != true))
169
+ { return false; }
170
+
171
+ if ((type == VOID_TYPE) && (constraints->voidAllowed != true))
172
+ { return false; }
173
+
174
+ if ((type == FACT_ADDRESS_TYPE) && (constraints->factAddressesAllowed != true))
175
+ { return false; }
176
+
177
+ return true;
178
+ }
179
+
180
+ /********************************************************/
181
+ /* CheckCardinalityConstraint: Determines if an integer */
182
+ /* falls within the range of allowed cardinalities */
183
+ /* for a constraint record. */
184
+ /********************************************************/
185
+ bool CheckCardinalityConstraint(
186
+ Environment *theEnv,
187
+ size_t number,
188
+ CONSTRAINT_RECORD *constraints)
189
+ {
190
+ /*=========================================*/
191
+ /* If the constraint record is NULL, there */
192
+ /* are no cardinality restrictions. */
193
+ /*=========================================*/
194
+
195
+ if (constraints == NULL) return true;
196
+
197
+ /*==================================*/
198
+ /* Determine if the integer is less */
199
+ /* than the minimum cardinality. */
200
+ /*==================================*/
201
+
202
+ if (constraints->minFields != NULL)
203
+ {
204
+ if (constraints->minFields->value != SymbolData(theEnv)->NegativeInfinity)
205
+ {
206
+ if (number < (size_t) constraints->minFields->integerValue->contents)
207
+ { return false; }
208
+ }
209
+ }
210
+
211
+ /*=====================================*/
212
+ /* Determine if the integer is greater */
213
+ /* than the maximum cardinality. */
214
+ /*=====================================*/
215
+
216
+ if (constraints->maxFields != NULL)
217
+ {
218
+ if (constraints->maxFields->value != SymbolData(theEnv)->PositiveInfinity)
219
+ {
220
+ if (number > (size_t) constraints->maxFields->integerValue->contents)
221
+ { return false; }
222
+ }
223
+ }
224
+
225
+ /*=========================================================*/
226
+ /* The integer falls within the allowed cardinality range. */
227
+ /*=========================================================*/
228
+
229
+ return true;
230
+ }
231
+
232
+ /*****************************************************************/
233
+ /* CheckRangeAgainstCardinalityConstraint: Determines if a range */
234
+ /* of numbers could possibly fall within the range of allowed */
235
+ /* cardinalities for a constraint record. Returns true if at */
236
+ /* least one of the numbers in the range is within the allowed */
237
+ /* cardinality, otherwise false is returned. */
238
+ /*****************************************************************/
239
+ static bool CheckRangeAgainstCardinalityConstraint(
240
+ Environment *theEnv,
241
+ int min,
242
+ int max,
243
+ CONSTRAINT_RECORD *constraints)
244
+ {
245
+ /*=========================================*/
246
+ /* If the constraint record is NULL, there */
247
+ /* are no cardinality restrictions. */
248
+ /*=========================================*/
249
+
250
+ if (constraints == NULL) return true;
251
+
252
+ /*===============================================================*/
253
+ /* If the minimum value of the range is greater than the maximum */
254
+ /* value of the cardinality, then there are no numbers in the */
255
+ /* range which could fall within the cardinality range, and so */
256
+ /* false is returned. */
257
+ /*===============================================================*/
258
+
259
+ if (constraints->maxFields != NULL)
260
+ {
261
+ if (constraints->maxFields->value != SymbolData(theEnv)->PositiveInfinity)
262
+ {
263
+ if (min > constraints->maxFields->integerValue->contents)
264
+ { return false; }
265
+ }
266
+ }
267
+
268
+ /*===============================================================*/
269
+ /* If the maximum value of the range is less than the minimum */
270
+ /* value of the cardinality, then there are no numbers in the */
271
+ /* range which could fall within the cardinality range, and so */
272
+ /* false is returned. A maximum range value of -1 indicates that */
273
+ /* the maximum possible value of the range is positive infinity. */
274
+ /*===============================================================*/
275
+
276
+ if ((constraints->minFields != NULL) && (max != -1))
277
+ {
278
+ if (constraints->minFields->value != SymbolData(theEnv)->NegativeInfinity)
279
+ {
280
+ if (max < constraints->minFields->integerValue->contents)
281
+ { return false; }
282
+ }
283
+ }
284
+
285
+ /*=============================================*/
286
+ /* At least one number in the specified range */
287
+ /* falls within the allowed cardinality range. */
288
+ /*=============================================*/
289
+
290
+ return true;
291
+ }
292
+
293
+ /**********************************************************************/
294
+ /* CheckAllowedValuesConstraint: Determines if a primitive data type */
295
+ /* satisfies the allowed-... constraint fields of a constraint */
296
+ /* record. Returns true if the constraints are satisfied, otherwise */
297
+ /* false is returned. */
298
+ /**********************************************************************/
299
+ bool CheckAllowedValuesConstraint(
300
+ int type,
301
+ void *vPtr,
302
+ CONSTRAINT_RECORD *constraints)
303
+ {
304
+ struct expr *tmpPtr;
305
+
306
+ /*=========================================*/
307
+ /* If the constraint record is NULL, there */
308
+ /* are no allowed-... restrictions. */
309
+ /*=========================================*/
310
+
311
+ if (constraints == NULL) return true;
312
+
313
+ /*=====================================================*/
314
+ /* Determine if there are any allowed-... restrictions */
315
+ /* for the type of the value being checked. */
316
+ /*=====================================================*/
317
+
318
+ switch (type)
319
+ {
320
+ case SYMBOL_TYPE:
321
+ if ((constraints->symbolRestriction == false) &&
322
+ (constraints->anyRestriction == false))
323
+ { return true; }
324
+ break;
325
+
326
+ #if OBJECT_SYSTEM
327
+ case INSTANCE_NAME_TYPE:
328
+ if ((constraints->instanceNameRestriction == false) &&
329
+ (constraints->anyRestriction == false))
330
+ { return true; }
331
+ break;
332
+ #endif
333
+
334
+ case STRING_TYPE:
335
+ if ((constraints->stringRestriction == false) &&
336
+ (constraints->anyRestriction == false))
337
+ { return true; }
338
+ break;
339
+
340
+ case INTEGER_TYPE:
341
+ if ((constraints->integerRestriction == false) &&
342
+ (constraints->anyRestriction == false))
343
+ { return true; }
344
+ break;
345
+
346
+ case FLOAT_TYPE:
347
+ if ((constraints->floatRestriction == false) &&
348
+ (constraints->anyRestriction == false))
349
+ { return true; }
350
+ break;
351
+
352
+ default:
353
+ return true;
354
+ }
355
+
356
+ /*=========================================================*/
357
+ /* Search through the restriction list to see if the value */
358
+ /* matches one of the allowed values in the list. */
359
+ /*=========================================================*/
360
+
361
+ for (tmpPtr = constraints->restrictionList;
362
+ tmpPtr != NULL;
363
+ tmpPtr = tmpPtr->nextArg)
364
+ {
365
+ if ((tmpPtr->type == type) && (tmpPtr->value == vPtr)) return true;
366
+ }
367
+
368
+ /*====================================================*/
369
+ /* If the value wasn't found in the list, then return */
370
+ /* false because the constraint has been violated. */
371
+ /*====================================================*/
372
+
373
+ return false;
374
+ }
375
+
376
+ /**********************************************************************/
377
+ /* CheckAllowedClassesConstraint: Determines if a primitive data type */
378
+ /* satisfies the allowed-classes constraint fields of a constraint */
379
+ /* record. Returns true if the constraints are satisfied, otherwise */
380
+ /* false is returned. */
381
+ /**********************************************************************/
382
+ bool CheckAllowedClassesConstraint(
383
+ Environment *theEnv,
384
+ int type,
385
+ void *vPtr,
386
+ CONSTRAINT_RECORD *constraints)
387
+ {
388
+ #if OBJECT_SYSTEM
389
+ struct expr *tmpPtr;
390
+ Instance *ins;
391
+ Defclass *insClass, *cmpClass;
392
+
393
+ /*=========================================*/
394
+ /* If the constraint record is NULL, there */
395
+ /* is no allowed-classes restriction. */
396
+ /*=========================================*/
397
+
398
+ if (constraints == NULL) return true;
399
+
400
+ /*======================================*/
401
+ /* The constraint is satisfied if there */
402
+ /* aren't any class restrictions. */
403
+ /*======================================*/
404
+
405
+ if (constraints->classList == NULL)
406
+ { return true; }
407
+
408
+ /*==================================*/
409
+ /* Class restrictions only apply to */
410
+ /* instances and instance names. */
411
+ /*==================================*/
412
+
413
+ if ((type != INSTANCE_ADDRESS_TYPE) && (type != INSTANCE_NAME_TYPE))
414
+ { return true; }
415
+
416
+ /*=============================================*/
417
+ /* If an instance name is specified, determine */
418
+ /* whether the instance exists. */
419
+ /*=============================================*/
420
+
421
+ if (type == INSTANCE_ADDRESS_TYPE)
422
+ { ins = (Instance *) vPtr; }
423
+ else
424
+ { ins = FindInstanceBySymbol(theEnv,(CLIPSLexeme *) vPtr); }
425
+
426
+ if (ins == NULL)
427
+ { return false; }
428
+
429
+ /*======================================================*/
430
+ /* Search through the class list to see if the instance */
431
+ /* belongs to one of the allowed classes in the list. */
432
+ /*======================================================*/
433
+
434
+ insClass = InstanceClass(ins);
435
+ for (tmpPtr = constraints->classList;
436
+ tmpPtr != NULL;
437
+ tmpPtr = tmpPtr->nextArg)
438
+ {
439
+ cmpClass = LookupDefclassByMdlOrScope(theEnv,tmpPtr->lexemeValue->contents);
440
+ if (cmpClass == NULL) continue;
441
+ if (cmpClass == insClass) return true;
442
+ if (SubclassP(insClass,cmpClass)) return true;
443
+ }
444
+
445
+ /*=========================================================*/
446
+ /* If a parent class wasn't found in the list, then return */
447
+ /* false because the constraint has been violated. */
448
+ /*=========================================================*/
449
+
450
+ return false;
451
+ #else
452
+
453
+ #if MAC_XCD
454
+ #pragma unused(theEnv)
455
+ #pragma unused(type)
456
+ #pragma unused(vPtr)
457
+ #pragma unused(constraints)
458
+ #endif
459
+
460
+ return true;
461
+ #endif
462
+ }
463
+
464
+ /*************************************************************/
465
+ /* CheckRangeConstraint: Determines if a primitive data type */
466
+ /* satisfies the range constraint of a constraint record. */
467
+ /*************************************************************/
468
+ static bool CheckRangeConstraint(
469
+ Environment *theEnv,
470
+ int type,
471
+ void *vPtr,
472
+ CONSTRAINT_RECORD *constraints)
473
+ {
474
+ struct expr *minList, *maxList;
475
+
476
+ /*===================================*/
477
+ /* If the constraint record is NULL, */
478
+ /* there are no range restrictions. */
479
+ /*===================================*/
480
+
481
+ if (constraints == NULL) return true;
482
+
483
+ /*============================================*/
484
+ /* If the value being checked isn't a number, */
485
+ /* then the range restrictions don't apply. */
486
+ /*============================================*/
487
+
488
+ if ((type != INTEGER_TYPE) && (type != FLOAT_TYPE)) return true;
489
+
490
+ /*=====================================================*/
491
+ /* Check each of the range restrictions to see if the */
492
+ /* number falls within at least one of the allowed */
493
+ /* ranges. If it falls within one of the ranges, then */
494
+ /* return true since the constraint is satisifed. */
495
+ /*=====================================================*/
496
+
497
+ minList = constraints->minValue;
498
+ maxList = constraints->maxValue;
499
+
500
+ while (minList != NULL)
501
+ {
502
+ if (CompareNumbers(theEnv,type,vPtr,minList->type,minList->value) == LESS_THAN)
503
+ {
504
+ minList = minList->nextArg;
505
+ maxList = maxList->nextArg;
506
+ }
507
+ else if (CompareNumbers(theEnv,type,vPtr,maxList->type,maxList->value) == GREATER_THAN)
508
+ {
509
+ minList = minList->nextArg;
510
+ maxList = maxList->nextArg;
511
+ }
512
+ else
513
+ { return true; }
514
+ }
515
+
516
+ /*===========================================*/
517
+ /* Return false since the number didn't fall */
518
+ /* within one of the allowed numeric ranges. */
519
+ /*===========================================*/
520
+
521
+ return false;
522
+ }
523
+
524
+ /************************************************/
525
+ /* ConstraintViolationErrorMessage: Generalized */
526
+ /* error message for constraint violations. */
527
+ /************************************************/
528
+ void ConstraintViolationErrorMessage(
529
+ Environment *theEnv,
530
+ const char *theWhat,
531
+ const char *thePlace,
532
+ bool command,
533
+ unsigned short thePattern,
534
+ CLIPSLexeme *theSlot,
535
+ unsigned short theField,
536
+ ConstraintViolationType violationType,
537
+ CONSTRAINT_RECORD *theConstraint,
538
+ bool printPrelude)
539
+ {
540
+ /*======================================================*/
541
+ /* Don't print anything other than the tail explanation */
542
+ /* of the error unless asked to do so. */
543
+ /*======================================================*/
544
+
545
+ if (printPrelude)
546
+ {
547
+ /*===================================*/
548
+ /* Print the name of the thing which */
549
+ /* caused the constraint violation. */
550
+ /*===================================*/
551
+
552
+ if (violationType == FUNCTION_RETURN_TYPE_VIOLATION)
553
+ {
554
+ PrintErrorID(theEnv,"CSTRNCHK",1,true);
555
+ WriteString(theEnv,STDERR,"The function return value");
556
+ }
557
+ else if (theWhat != NULL)
558
+ {
559
+ PrintErrorID(theEnv,"CSTRNCHK",1,true);
560
+ WriteString(theEnv,STDERR,theWhat);
561
+ }
562
+
563
+ /*=======================================*/
564
+ /* Print the location of the thing which */
565
+ /* caused the constraint violation. */
566
+ /*=======================================*/
567
+
568
+ if (thePlace != NULL)
569
+ {
570
+ WriteString(theEnv,STDERR," found in ");
571
+ if (command) WriteString(theEnv,STDERR,"the '");
572
+ WriteString(theEnv,STDERR,thePlace);
573
+ if (command) WriteString(theEnv,STDERR,"' command");
574
+ }
575
+
576
+ /*================================================*/
577
+ /* If the violation occured in the LHS of a rule, */
578
+ /* indicate which pattern was at fault. */
579
+ /*================================================*/
580
+
581
+ if (thePattern > 0)
582
+ {
583
+ WriteString(theEnv,STDERR," found in CE #");
584
+ WriteInteger(theEnv,STDERR,thePattern);
585
+ }
586
+ }
587
+
588
+ /*===============================================================*/
589
+ /* Indicate the type of constraint violation (type, range, etc). */
590
+ /*===============================================================*/
591
+
592
+ if ((violationType == TYPE_VIOLATION) ||
593
+ (violationType == FUNCTION_RETURN_TYPE_VIOLATION))
594
+ { WriteString(theEnv,STDERR," does not match the allowed types"); }
595
+ else if (violationType == RANGE_VIOLATION)
596
+ {
597
+ WriteString(theEnv,STDERR," does not fall in the allowed range ");
598
+ PrintRange(theEnv,STDERR,theConstraint);
599
+ }
600
+ else if (violationType == ALLOWED_VALUES_VIOLATION)
601
+ { WriteString(theEnv,STDERR," does not match the allowed values"); }
602
+ else if (violationType == CARDINALITY_VIOLATION)
603
+ { WriteString(theEnv,STDERR," does not satisfy the cardinality restrictions"); }
604
+ else if (violationType == ALLOWED_CLASSES_VIOLATION)
605
+ { WriteString(theEnv,STDERR," does not match the allowed classes"); }
606
+
607
+ /*==============================================*/
608
+ /* Print either the slot name or field position */
609
+ /* where the constraint violation occured. */
610
+ /*==============================================*/
611
+
612
+ if (theSlot != NULL)
613
+ {
614
+ WriteString(theEnv,STDERR," for slot '");
615
+ WriteString(theEnv,STDERR,theSlot->contents);
616
+ WriteString(theEnv,STDERR,"'");
617
+ }
618
+ else if (theField > 0)
619
+ {
620
+ WriteString(theEnv,STDERR," for field #");
621
+ WriteInteger(theEnv,STDERR,theField);
622
+ }
623
+
624
+ WriteString(theEnv,STDERR,".\n");
625
+ }
626
+
627
+ /********************************************************************/
628
+ /* PrintRange: Prints the range restriction of a constraint record. */
629
+ /* For example, 8 to +00 (eight to positive infinity). */
630
+ /********************************************************************/
631
+ static void PrintRange(
632
+ Environment *theEnv,
633
+ const char *logicalName,
634
+ CONSTRAINT_RECORD *theConstraint)
635
+ {
636
+ if (theConstraint->minValue->value == SymbolData(theEnv)->NegativeInfinity)
637
+ { WriteString(theEnv,logicalName,SymbolData(theEnv)->NegativeInfinity->contents); }
638
+ else PrintExpression(theEnv,logicalName,theConstraint->minValue);
639
+ WriteString(theEnv,logicalName," to ");
640
+ if (theConstraint->maxValue->value == SymbolData(theEnv)->PositiveInfinity)
641
+ { WriteString(theEnv,logicalName,SymbolData(theEnv)->PositiveInfinity->contents); }
642
+ else PrintExpression(theEnv,logicalName,theConstraint->maxValue);
643
+ }
644
+
645
+ /*************************************************************/
646
+ /* ConstraintCheckDataObject: Given a value stored in a data */
647
+ /* object structure and a constraint record, determines if */
648
+ /* the data object satisfies the constraint record. */
649
+ /*************************************************************/
650
+ ConstraintViolationType ConstraintCheckDataObject(
651
+ Environment *theEnv,
652
+ UDFValue *theData,
653
+ CONSTRAINT_RECORD *theConstraints)
654
+ {
655
+ size_t i; /* 6.04 Bug Fix */
656
+ ConstraintViolationType rv;
657
+ CLIPSValue *theMultifield;
658
+
659
+ if (theConstraints == NULL) return NO_VIOLATION;
660
+
661
+ if (theData->header->type == MULTIFIELD_TYPE)
662
+ {
663
+ if (CheckCardinalityConstraint(theEnv,theData->range,theConstraints) == false)
664
+ { return CARDINALITY_VIOLATION; }
665
+
666
+ theMultifield = theData->multifieldValue->contents;
667
+ for (i = theData->begin; i < theData->begin + theData->range; i++)
668
+ {
669
+ if ((rv = ConstraintCheckValue(theEnv,theMultifield[i].header->type,
670
+ theMultifield[i].value,
671
+ theConstraints)) != NO_VIOLATION)
672
+ { return rv; }
673
+ }
674
+
675
+ return NO_VIOLATION;
676
+ }
677
+
678
+ if (CheckCardinalityConstraint(theEnv,1,theConstraints) == false)
679
+ { return CARDINALITY_VIOLATION; }
680
+
681
+ return ConstraintCheckValue(theEnv,theData->header->type,theData->value,theConstraints);
682
+ }
683
+
684
+ /****************************************************************/
685
+ /* ConstraintCheckValue: Given a value and a constraint record, */
686
+ /* determines if the value satisfies the constraint record. */
687
+ /****************************************************************/
688
+ ConstraintViolationType ConstraintCheckValue(
689
+ Environment *theEnv,
690
+ int theType,
691
+ void *theValue,
692
+ CONSTRAINT_RECORD *theConstraints)
693
+ {
694
+ if (CheckTypeConstraint(theType,theConstraints) == false)
695
+ { return TYPE_VIOLATION; }
696
+
697
+ else if (CheckAllowedValuesConstraint(theType,theValue,theConstraints) == false)
698
+ { return ALLOWED_VALUES_VIOLATION; }
699
+
700
+ else if (CheckAllowedClassesConstraint(theEnv,theType,theValue,theConstraints) == false)
701
+ { return ALLOWED_CLASSES_VIOLATION; }
702
+
703
+ else if (CheckRangeConstraint(theEnv,theType,theValue,theConstraints) == false)
704
+ { return RANGE_VIOLATION; }
705
+
706
+ else if (theType == FCALL)
707
+ {
708
+ if (CheckFunctionReturnType(UnknownFunctionType(theValue),theConstraints) == false)
709
+ { return FUNCTION_RETURN_TYPE_VIOLATION; }
710
+ }
711
+
712
+ return NO_VIOLATION;
713
+ }
714
+
715
+ /********************************************************************/
716
+ /* ConstraintCheckExpressionChain: Checks an expression and nextArg */
717
+ /* links for constraint conflicts (argList is not followed). */
718
+ /********************************************************************/
719
+ ConstraintViolationType ConstraintCheckExpressionChain(
720
+ Environment *theEnv,
721
+ struct expr *theExpression,
722
+ CONSTRAINT_RECORD *theConstraints)
723
+ {
724
+ struct expr *theExp;
725
+ int min = 0, max = 0;
726
+ ConstraintViolationType vCode;
727
+
728
+ /*===========================================================*/
729
+ /* Determine the minimum and maximum number of value which */
730
+ /* can be derived from the expression chain (max of -1 means */
731
+ /* positive infinity). */
732
+ /*===========================================================*/
733
+
734
+ for (theExp = theExpression ; theExp != NULL ; theExp = theExp->nextArg)
735
+ {
736
+ if (ConstantType(theExp->type)) min++;
737
+ else if (theExp->type == FCALL)
738
+ {
739
+ unsigned restriction = ExpressionUnknownFunctionType(theExp);
740
+ if (restriction & MULTIFIELD_BIT)
741
+ { max = -1; }
742
+ else
743
+ { min++; }
744
+ }
745
+ else max = -1;
746
+ }
747
+
748
+ /*====================================*/
749
+ /* Check for a cardinality violation. */
750
+ /*====================================*/
751
+
752
+ if (max == 0) max = min;
753
+ if (CheckRangeAgainstCardinalityConstraint(theEnv,min,max,theConstraints) == false)
754
+ { return CARDINALITY_VIOLATION; }
755
+
756
+ /*========================================*/
757
+ /* Check for other constraint violations. */
758
+ /*========================================*/
759
+
760
+ for (theExp = theExpression ; theExp != NULL ; theExp = theExp->nextArg)
761
+ {
762
+ vCode = ConstraintCheckValue(theEnv,theExp->type,theExp->value,theConstraints);
763
+ if (vCode != NO_VIOLATION)
764
+ return vCode;
765
+ }
766
+
767
+ return NO_VIOLATION;
768
+ }
769
+
770
+ #if (! RUN_TIME) && (! BLOAD_ONLY)
771
+
772
+ /***************************************************/
773
+ /* ConstraintCheckExpression: Checks an expression */
774
+ /* for constraint conflicts. Returns zero if */
775
+ /* conflicts are found, otherwise non-zero. */
776
+ /***************************************************/
777
+ ConstraintViolationType ConstraintCheckExpression(
778
+ Environment *theEnv,
779
+ struct expr *theExpression,
780
+ CONSTRAINT_RECORD *theConstraints)
781
+ {
782
+ ConstraintViolationType rv = NO_VIOLATION;
783
+
784
+ if (theConstraints == NULL) return(rv);
785
+
786
+ while (theExpression != NULL)
787
+ {
788
+ rv = ConstraintCheckValue(theEnv,theExpression->type,
789
+ theExpression->value,
790
+ theConstraints);
791
+ if (rv != NO_VIOLATION) return rv;
792
+ rv = ConstraintCheckExpression(theEnv,theExpression->argList,theConstraints);
793
+ if (rv != NO_VIOLATION) return rv;
794
+ theExpression = theExpression->nextArg;
795
+ }
796
+
797
+ return rv;
798
+ }
799
+
800
+ #endif /* (! RUN_TIME) && (! BLOAD_ONLY) */
801
+
802
+ /*****************************************************/
803
+ /* UnmatchableConstraint: Determines if a constraint */
804
+ /* record can still be satisfied by some value. */
805
+ /*****************************************************/
806
+ bool UnmatchableConstraint(
807
+ CONSTRAINT_RECORD *theConstraint)
808
+ {
809
+ if (theConstraint == NULL) return false;
810
+
811
+ if ((! theConstraint->anyAllowed) &&
812
+ (! theConstraint->symbolsAllowed) &&
813
+ (! theConstraint->stringsAllowed) &&
814
+ (! theConstraint->floatsAllowed) &&
815
+ (! theConstraint->integersAllowed) &&
816
+ (! theConstraint->instanceNamesAllowed) &&
817
+ (! theConstraint->instanceAddressesAllowed) &&
818
+ (! theConstraint->multifieldsAllowed) &&
819
+ (! theConstraint->externalAddressesAllowed) &&
820
+ (! theConstraint->voidAllowed) &&
821
+ (! theConstraint->factAddressesAllowed))
822
+ { return true; }
823
+
824
+ return false;
825
+ }
826
+