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