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