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,1451 @@
|
|
1
|
+
/*******************************************************/
|
2
|
+
/* "C" Language Integrated Production System */
|
3
|
+
/* */
|
4
|
+
/* CLIPS Version 6.40 11/07/17 */
|
5
|
+
/* */
|
6
|
+
/* INSTANCE FUNCTIONS MODULE */
|
7
|
+
/*******************************************************/
|
8
|
+
|
9
|
+
/*************************************************************/
|
10
|
+
/* Purpose: Internal instance manipulation routines */
|
11
|
+
/* */
|
12
|
+
/* Principal Programmer(s): */
|
13
|
+
/* Brian L. Dantes */
|
14
|
+
/* */
|
15
|
+
/* Contributing Programmer(s): */
|
16
|
+
/* */
|
17
|
+
/* */
|
18
|
+
/* Revision History: */
|
19
|
+
/* */
|
20
|
+
/* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
|
21
|
+
/* */
|
22
|
+
/* Changed name of variable log to logName */
|
23
|
+
/* because of Unix compiler warnings of shadowed */
|
24
|
+
/* definitions. */
|
25
|
+
/* */
|
26
|
+
/* Changed name of variable exp to theExp */
|
27
|
+
/* because of Unix compiler warnings of shadowed */
|
28
|
+
/* definitions. */
|
29
|
+
/* */
|
30
|
+
/* 6.24: Link error occurs for the SlotExistError */
|
31
|
+
/* function when OBJECT_SYSTEM is set to 0 in */
|
32
|
+
/* setup.h. DR0865 */
|
33
|
+
/* */
|
34
|
+
/* Converted INSTANCE_PATTERN_MATCHING to */
|
35
|
+
/* DEFRULE_CONSTRUCT. */
|
36
|
+
/* */
|
37
|
+
/* Renamed BOOLEAN macro type to intBool. */
|
38
|
+
/* */
|
39
|
+
/* Moved EvaluateAndStoreInDataObject to */
|
40
|
+
/* evaluatn.c */
|
41
|
+
/* */
|
42
|
+
/* 6.30: Removed conditional code for unsupported */
|
43
|
+
/* compilers/operating systems (IBM_MCW, */
|
44
|
+
/* MAC_MCW, and IBM_TBC). */
|
45
|
+
/* */
|
46
|
+
/* Changed integer type/precision. */
|
47
|
+
/* */
|
48
|
+
/* Changed garbage collection algorithm. */
|
49
|
+
/* */
|
50
|
+
/* Support for long long integers. */
|
51
|
+
/* */
|
52
|
+
/* Added const qualifiers to remove C++ */
|
53
|
+
/* deprecation warnings. */
|
54
|
+
/* */
|
55
|
+
/* Converted API macros to function calls. */
|
56
|
+
/* */
|
57
|
+
/* Fixed slot override default ?NONE bug. */
|
58
|
+
/* */
|
59
|
+
/* Instances of the form [<name>] are now */
|
60
|
+
/* searched for in all modules. */
|
61
|
+
/* */
|
62
|
+
/* 6.40: Added Env prefix to GetEvaluationError and */
|
63
|
+
/* SetEvaluationError functions. */
|
64
|
+
/* */
|
65
|
+
/* Pragma once and other inclusion changes. */
|
66
|
+
/* */
|
67
|
+
/* Added support for booleans with <stdbool.h>. */
|
68
|
+
/* */
|
69
|
+
/* Removed use of void pointers for specific */
|
70
|
+
/* data structures. */
|
71
|
+
/* */
|
72
|
+
/* ALLOW_ENVIRONMENT_GLOBALS no longer supported. */
|
73
|
+
/* */
|
74
|
+
/* UDF redesign. */
|
75
|
+
/* */
|
76
|
+
/*************************************************************/
|
77
|
+
|
78
|
+
/* =========================================
|
79
|
+
*****************************************
|
80
|
+
EXTERNAL DEFINITIONS
|
81
|
+
=========================================
|
82
|
+
***************************************** */
|
83
|
+
|
84
|
+
#include <stdlib.h>
|
85
|
+
|
86
|
+
#include "setup.h"
|
87
|
+
|
88
|
+
#if OBJECT_SYSTEM
|
89
|
+
|
90
|
+
#include "argacces.h"
|
91
|
+
#include "classcom.h"
|
92
|
+
#include "classfun.h"
|
93
|
+
#include "cstrnchk.h"
|
94
|
+
#if DEFRULE_CONSTRUCT
|
95
|
+
#include "drive.h"
|
96
|
+
#include "objrtmch.h"
|
97
|
+
#endif
|
98
|
+
#include "engine.h"
|
99
|
+
#include "envrnmnt.h"
|
100
|
+
#include "inscom.h"
|
101
|
+
#include "insmngr.h"
|
102
|
+
#include "memalloc.h"
|
103
|
+
#include "modulutl.h"
|
104
|
+
#include "msgcom.h"
|
105
|
+
#include "msgfun.h"
|
106
|
+
#include "prccode.h"
|
107
|
+
#include "prntutil.h"
|
108
|
+
#include "router.h"
|
109
|
+
#include "utility.h"
|
110
|
+
|
111
|
+
#include "insfun.h"
|
112
|
+
|
113
|
+
/* =========================================
|
114
|
+
*****************************************
|
115
|
+
CONSTANTS
|
116
|
+
=========================================
|
117
|
+
***************************************** */
|
118
|
+
#define BIG_PRIME 11329
|
119
|
+
|
120
|
+
/***************************************/
|
121
|
+
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
|
122
|
+
/***************************************/
|
123
|
+
|
124
|
+
static Instance *FindImportedInstance(Environment *,Defmodule *,Defmodule *,Instance *);
|
125
|
+
|
126
|
+
#if DEFRULE_CONSTRUCT
|
127
|
+
static void NetworkModifyForSharedSlot(Environment *,int,Defclass *,SlotDescriptor *);
|
128
|
+
#endif
|
129
|
+
|
130
|
+
/* =========================================
|
131
|
+
*****************************************
|
132
|
+
EXTERNALLY VISIBLE FUNCTIONS
|
133
|
+
=========================================
|
134
|
+
***************************************** */
|
135
|
+
|
136
|
+
/***************************************************/
|
137
|
+
/* IncrementInstanceCallback: Increments the */
|
138
|
+
/* number of references to a specified instance. */
|
139
|
+
/***************************************************/
|
140
|
+
void IncrementInstanceCallback(
|
141
|
+
Environment *theEnv,
|
142
|
+
Instance *theInstance)
|
143
|
+
{
|
144
|
+
#if MAC_XCD
|
145
|
+
#pragma unused(theEnv)
|
146
|
+
#endif
|
147
|
+
if (theInstance == NULL) return;
|
148
|
+
|
149
|
+
theInstance->busy++;
|
150
|
+
}
|
151
|
+
|
152
|
+
/***************************************************/
|
153
|
+
/* DecrementInstanceCallback: Decrements the */
|
154
|
+
/* number of references to a specified instance. */
|
155
|
+
/***************************************************/
|
156
|
+
void DecrementInstanceCallback(
|
157
|
+
Environment *theEnv,
|
158
|
+
Instance *theInstance)
|
159
|
+
{
|
160
|
+
#if MAC_XCD
|
161
|
+
#pragma unused(theEnv)
|
162
|
+
#endif
|
163
|
+
if (theInstance == NULL) return;
|
164
|
+
|
165
|
+
theInstance->busy--;
|
166
|
+
}
|
167
|
+
|
168
|
+
/***************************************************
|
169
|
+
NAME : RetainInstance
|
170
|
+
DESCRIPTION : Increments instance busy count -
|
171
|
+
prevents it from being deleted
|
172
|
+
INPUTS : The address of the instance
|
173
|
+
RETURNS : Nothing useful
|
174
|
+
SIDE EFFECTS : Count set
|
175
|
+
NOTES : None
|
176
|
+
***************************************************/
|
177
|
+
void RetainInstance(
|
178
|
+
Instance *theInstance)
|
179
|
+
{
|
180
|
+
if (theInstance == NULL) return;
|
181
|
+
|
182
|
+
theInstance->busy++;
|
183
|
+
}
|
184
|
+
|
185
|
+
/***************************************************
|
186
|
+
NAME : ReleaseInstance
|
187
|
+
DESCRIPTION : Decrements instance busy count -
|
188
|
+
might allow it to be deleted
|
189
|
+
INPUTS : The address of the instance
|
190
|
+
RETURNS : Nothing useful
|
191
|
+
SIDE EFFECTS : Count set
|
192
|
+
NOTES : None
|
193
|
+
***************************************************/
|
194
|
+
void ReleaseInstance(
|
195
|
+
Instance *theInstance)
|
196
|
+
{
|
197
|
+
if (theInstance == NULL) return;
|
198
|
+
|
199
|
+
theInstance->busy--;
|
200
|
+
}
|
201
|
+
|
202
|
+
/***************************************************
|
203
|
+
NAME : InitializeInstanceTable
|
204
|
+
DESCRIPTION : Initializes instance hash table
|
205
|
+
to all NULL addresses
|
206
|
+
INPUTS : None
|
207
|
+
RETURNS : Nothing useful
|
208
|
+
SIDE EFFECTS : Hash table initialized
|
209
|
+
NOTES : None
|
210
|
+
***************************************************/
|
211
|
+
void InitializeInstanceTable(
|
212
|
+
Environment *theEnv)
|
213
|
+
{
|
214
|
+
int i;
|
215
|
+
|
216
|
+
InstanceData(theEnv)->InstanceTable = (Instance **)
|
217
|
+
gm2(theEnv,sizeof(Instance *) * INSTANCE_TABLE_HASH_SIZE);
|
218
|
+
for (i = 0 ; i < INSTANCE_TABLE_HASH_SIZE ; i++)
|
219
|
+
InstanceData(theEnv)->InstanceTable[i] = NULL;
|
220
|
+
}
|
221
|
+
|
222
|
+
/*******************************************************
|
223
|
+
NAME : CleanupInstances
|
224
|
+
DESCRIPTION : Iterates through instance garbage
|
225
|
+
list looking for nodes that
|
226
|
+
have become unused - and purges
|
227
|
+
them
|
228
|
+
INPUTS : None
|
229
|
+
RETURNS : Nothing useful
|
230
|
+
SIDE EFFECTS : Non-busy instance garbage nodes deleted
|
231
|
+
NOTES : None
|
232
|
+
*******************************************************/
|
233
|
+
void CleanupInstances(
|
234
|
+
Environment *theEnv,
|
235
|
+
void *context)
|
236
|
+
{
|
237
|
+
IGARBAGE *gprv,*gtmp,*dump;
|
238
|
+
|
239
|
+
if (InstanceData(theEnv)->MaintainGarbageInstances)
|
240
|
+
return;
|
241
|
+
gprv = NULL;
|
242
|
+
gtmp = InstanceData(theEnv)->InstanceGarbageList;
|
243
|
+
while (gtmp != NULL)
|
244
|
+
{
|
245
|
+
#if DEFRULE_CONSTRUCT
|
246
|
+
if ((gtmp->ins->busy == 0)
|
247
|
+
&& (gtmp->ins->patternHeader.busyCount == 0))
|
248
|
+
#else
|
249
|
+
if (gtmp->ins->busy == 0)
|
250
|
+
#endif
|
251
|
+
{
|
252
|
+
ReleaseLexeme(theEnv,gtmp->ins->name);
|
253
|
+
rtn_struct(theEnv,instance,gtmp->ins);
|
254
|
+
if (gprv == NULL)
|
255
|
+
InstanceData(theEnv)->InstanceGarbageList = gtmp->nxt;
|
256
|
+
else
|
257
|
+
gprv->nxt = gtmp->nxt;
|
258
|
+
dump = gtmp;
|
259
|
+
gtmp = gtmp->nxt;
|
260
|
+
rtn_struct(theEnv,igarbage,dump);
|
261
|
+
}
|
262
|
+
else
|
263
|
+
{
|
264
|
+
gprv = gtmp;
|
265
|
+
gtmp = gtmp->nxt;
|
266
|
+
}
|
267
|
+
}
|
268
|
+
}
|
269
|
+
|
270
|
+
/*******************************************************
|
271
|
+
NAME : HashInstance
|
272
|
+
DESCRIPTION : Generates a hash index for a given
|
273
|
+
instance name
|
274
|
+
INPUTS : The address of the instance name SYMBOL_HN
|
275
|
+
RETURNS : The hash index value
|
276
|
+
SIDE EFFECTS : None
|
277
|
+
NOTES : Counts on the fact that the symbol
|
278
|
+
has already been hashed into the
|
279
|
+
symbol table - uses that hash value
|
280
|
+
multiplied by a prime for a new hash
|
281
|
+
*******************************************************/
|
282
|
+
unsigned HashInstance(
|
283
|
+
CLIPSLexeme *cname)
|
284
|
+
{
|
285
|
+
unsigned long tally;
|
286
|
+
|
287
|
+
tally = ((unsigned long) cname->bucket) * BIG_PRIME;
|
288
|
+
return (unsigned) (tally % INSTANCE_TABLE_HASH_SIZE);
|
289
|
+
}
|
290
|
+
|
291
|
+
/***************************************************
|
292
|
+
NAME : DestroyAllInstances
|
293
|
+
DESCRIPTION : Deallocates all instances,
|
294
|
+
reinitializes hash table and
|
295
|
+
resets class instance pointers
|
296
|
+
INPUTS : None
|
297
|
+
RETURNS : Nothing useful
|
298
|
+
SIDE EFFECTS : All instances deallocated
|
299
|
+
NOTES : None
|
300
|
+
***************************************************/
|
301
|
+
void DestroyAllInstances(
|
302
|
+
Environment *theEnv,
|
303
|
+
void *context)
|
304
|
+
{
|
305
|
+
Instance *iptr;
|
306
|
+
bool svmaintain;
|
307
|
+
|
308
|
+
SaveCurrentModule(theEnv);
|
309
|
+
svmaintain = InstanceData(theEnv)->MaintainGarbageInstances;
|
310
|
+
InstanceData(theEnv)->MaintainGarbageInstances = true;
|
311
|
+
iptr = InstanceData(theEnv)->InstanceList;
|
312
|
+
while (iptr != NULL)
|
313
|
+
{
|
314
|
+
SetCurrentModule(theEnv,iptr->cls->header.whichModule->theModule);
|
315
|
+
DirectMessage(theEnv,MessageHandlerData(theEnv)->DELETE_SYMBOL,iptr,NULL,NULL);
|
316
|
+
iptr = iptr->nxtList;
|
317
|
+
while ((iptr != NULL) ? iptr->garbage : false)
|
318
|
+
iptr = iptr->nxtList;
|
319
|
+
}
|
320
|
+
InstanceData(theEnv)->MaintainGarbageInstances = svmaintain;
|
321
|
+
RestoreCurrentModule(theEnv);
|
322
|
+
}
|
323
|
+
|
324
|
+
/******************************************************
|
325
|
+
NAME : RemoveInstanceData
|
326
|
+
DESCRIPTION : Deallocates all the data objects
|
327
|
+
in instance slots and then dealloactes
|
328
|
+
the slots themeselves
|
329
|
+
INPUTS : The instance
|
330
|
+
RETURNS : Nothing useful
|
331
|
+
SIDE EFFECTS : Instance slots removed
|
332
|
+
NOTES : An instance made with CopyInstanceData
|
333
|
+
will have shared values removed
|
334
|
+
in all cases because they are not
|
335
|
+
"real" instances.
|
336
|
+
Instance class busy count decremented
|
337
|
+
******************************************************/
|
338
|
+
void RemoveInstanceData(
|
339
|
+
Environment *theEnv,
|
340
|
+
Instance *ins)
|
341
|
+
{
|
342
|
+
long i;
|
343
|
+
InstanceSlot *sp;
|
344
|
+
|
345
|
+
DecrementDefclassBusyCount(theEnv,ins->cls);
|
346
|
+
for (i = 0 ; i < ins->cls->instanceSlotCount ; i++)
|
347
|
+
{
|
348
|
+
sp = ins->slotAddresses[i];
|
349
|
+
if ((sp == &sp->desc->sharedValue) ?
|
350
|
+
(--sp->desc->sharedCount == 0) : true)
|
351
|
+
{
|
352
|
+
if (sp->desc->multiple)
|
353
|
+
{
|
354
|
+
ReleaseMultifield(theEnv,sp->multifieldValue);
|
355
|
+
AddToMultifieldList(theEnv,sp->multifieldValue);
|
356
|
+
}
|
357
|
+
else
|
358
|
+
AtomDeinstall(theEnv,sp->type,sp->value);
|
359
|
+
sp->value = NULL;
|
360
|
+
}
|
361
|
+
}
|
362
|
+
if (ins->cls->instanceSlotCount != 0)
|
363
|
+
{
|
364
|
+
rm(theEnv,ins->slotAddresses,
|
365
|
+
(ins->cls->instanceSlotCount * sizeof(InstanceSlot *)));
|
366
|
+
if (ins->cls->localInstanceSlotCount != 0)
|
367
|
+
rm(theEnv,ins->slots,
|
368
|
+
(ins->cls->localInstanceSlotCount * sizeof(InstanceSlot)));
|
369
|
+
}
|
370
|
+
ins->slots = NULL;
|
371
|
+
ins->slotAddresses = NULL;
|
372
|
+
}
|
373
|
+
|
374
|
+
/***************************************************************************
|
375
|
+
NAME : FindInstanceBySymbol
|
376
|
+
DESCRIPTION : Looks up a specified instance in the instance hash table
|
377
|
+
INPUTS : The symbol for the name of the instance
|
378
|
+
RETURNS : The address of the found instance, NULL otherwise
|
379
|
+
SIDE EFFECTS : None
|
380
|
+
NOTES : An instance is searched for by name first in the
|
381
|
+
current module - then in imported modules according
|
382
|
+
to the order given in the current module's definition.
|
383
|
+
Instances of the form [<name>] are now searched for in
|
384
|
+
all modules.
|
385
|
+
***************************************************************************/
|
386
|
+
Instance *FindInstanceBySymbol(
|
387
|
+
Environment *theEnv,
|
388
|
+
CLIPSLexeme *moduleAndInstanceName)
|
389
|
+
{
|
390
|
+
unsigned modulePosition;
|
391
|
+
bool searchImports;
|
392
|
+
CLIPSLexeme *moduleName, *instanceName;
|
393
|
+
Defmodule *currentModule,*theModule;
|
394
|
+
|
395
|
+
currentModule = GetCurrentModule(theEnv);
|
396
|
+
|
397
|
+
/* =======================================
|
398
|
+
Instance names of the form [<name>] are
|
399
|
+
searched for only in the current module
|
400
|
+
======================================= */
|
401
|
+
modulePosition = FindModuleSeparator(moduleAndInstanceName->contents);
|
402
|
+
if (modulePosition == 0)
|
403
|
+
{
|
404
|
+
Instance *ins;
|
405
|
+
if (moduleAndInstanceName->header.type == SYMBOL_TYPE)
|
406
|
+
{ moduleAndInstanceName = CreateInstanceName(theEnv,moduleAndInstanceName->contents); }
|
407
|
+
|
408
|
+
ins = InstanceData(theEnv)->InstanceTable[HashInstance(moduleAndInstanceName)];
|
409
|
+
while (ins != NULL)
|
410
|
+
{
|
411
|
+
if (ins->name == moduleAndInstanceName)
|
412
|
+
{ return ins; }
|
413
|
+
ins = ins->nxtHash;
|
414
|
+
}
|
415
|
+
return NULL;
|
416
|
+
}
|
417
|
+
|
418
|
+
/* =========================================
|
419
|
+
Instance names of the form [::<name>] are
|
420
|
+
searched for in the current module and
|
421
|
+
imported modules in the definition order
|
422
|
+
========================================= */
|
423
|
+
else if (modulePosition == 1)
|
424
|
+
{
|
425
|
+
theModule = currentModule;
|
426
|
+
instanceName = ExtractConstructName(theEnv,modulePosition,moduleAndInstanceName->contents,INSTANCE_NAME_TYPE);
|
427
|
+
searchImports = true;
|
428
|
+
}
|
429
|
+
|
430
|
+
/* =============================================
|
431
|
+
Instance names of the form [<module>::<name>]
|
432
|
+
are searched for in the specified module
|
433
|
+
============================================= */
|
434
|
+
else
|
435
|
+
{
|
436
|
+
moduleName = ExtractModuleName(theEnv,modulePosition,moduleAndInstanceName->contents);
|
437
|
+
theModule = FindDefmodule(theEnv,moduleName->contents);
|
438
|
+
instanceName = ExtractConstructName(theEnv,modulePosition,moduleAndInstanceName->contents,INSTANCE_NAME_TYPE);
|
439
|
+
if (theModule == NULL)
|
440
|
+
return NULL;
|
441
|
+
searchImports = false;
|
442
|
+
}
|
443
|
+
return(FindInstanceInModule(theEnv,instanceName,theModule,currentModule,searchImports));
|
444
|
+
}
|
445
|
+
|
446
|
+
/***************************************************
|
447
|
+
NAME : FindInstanceInModule
|
448
|
+
DESCRIPTION : Finds an instance of the given name
|
449
|
+
in the given module in scope of
|
450
|
+
the given current module
|
451
|
+
(will also search imported modules
|
452
|
+
if specified)
|
453
|
+
INPUTS : 1) The instance name (no module)
|
454
|
+
2) The module to search
|
455
|
+
3) The currently active module
|
456
|
+
4) A flag indicating whether
|
457
|
+
to search imported modules of
|
458
|
+
given module as well
|
459
|
+
RETURNS : The instance (NULL if none found)
|
460
|
+
SIDE EFFECTS : None
|
461
|
+
NOTES : The class no longer needs to be in
|
462
|
+
scope of the current module if the
|
463
|
+
instance's module name has been specified.
|
464
|
+
***************************************************/
|
465
|
+
Instance *FindInstanceInModule(
|
466
|
+
Environment *theEnv,
|
467
|
+
CLIPSLexeme *instanceName,
|
468
|
+
Defmodule *theModule,
|
469
|
+
Defmodule *currentModule,
|
470
|
+
bool searchImports)
|
471
|
+
{
|
472
|
+
Instance *startInstance,*ins;
|
473
|
+
|
474
|
+
/* ===============================
|
475
|
+
Find the first instance of the
|
476
|
+
correct name in the hash chain
|
477
|
+
=============================== */
|
478
|
+
startInstance = InstanceData(theEnv)->InstanceTable[HashInstance(instanceName)];
|
479
|
+
while (startInstance != NULL)
|
480
|
+
{
|
481
|
+
if (startInstance->name == instanceName)
|
482
|
+
break;
|
483
|
+
startInstance = startInstance->nxtHash;
|
484
|
+
}
|
485
|
+
|
486
|
+
if (startInstance == NULL)
|
487
|
+
return NULL;
|
488
|
+
|
489
|
+
/* ===========================================
|
490
|
+
Look for the instance in the specified
|
491
|
+
module - if the class of the found instance
|
492
|
+
is in scope of the current module, we have
|
493
|
+
found the instance
|
494
|
+
=========================================== */
|
495
|
+
for (ins = startInstance ;
|
496
|
+
(ins != NULL) ? (ins->name == startInstance->name) : false ;
|
497
|
+
ins = ins->nxtHash)
|
498
|
+
//if ((ins->cls->header.whichModule->theModule == theModule) &&
|
499
|
+
// DefclassInScope(theEnv,ins->cls,currentModule))
|
500
|
+
if (ins->cls->header.whichModule->theModule == theModule)
|
501
|
+
return(ins);
|
502
|
+
|
503
|
+
/* ================================
|
504
|
+
For ::<name> formats, we need to
|
505
|
+
search imported modules too
|
506
|
+
================================ */
|
507
|
+
if (searchImports == false)
|
508
|
+
return NULL;
|
509
|
+
MarkModulesAsUnvisited(theEnv);
|
510
|
+
return(FindImportedInstance(theEnv,theModule,currentModule,startInstance));
|
511
|
+
}
|
512
|
+
|
513
|
+
/********************************************************************
|
514
|
+
NAME : FindInstanceSlot
|
515
|
+
DESCRIPTION : Finds an instance slot by name
|
516
|
+
INPUTS : 1) The address of the instance
|
517
|
+
2) The symbolic name of the slot
|
518
|
+
RETURNS : The address of the slot, NULL if not found
|
519
|
+
SIDE EFFECTS : None
|
520
|
+
NOTES : None
|
521
|
+
********************************************************************/
|
522
|
+
InstanceSlot *FindInstanceSlot(
|
523
|
+
Environment *theEnv,
|
524
|
+
Instance *ins,
|
525
|
+
CLIPSLexeme *sname)
|
526
|
+
{
|
527
|
+
int i;
|
528
|
+
|
529
|
+
i = FindInstanceTemplateSlot(theEnv,ins->cls,sname);
|
530
|
+
return (i != -1) ? ins->slotAddresses[i] : NULL;
|
531
|
+
}
|
532
|
+
|
533
|
+
/********************************************************************
|
534
|
+
NAME : FindInstanceTemplateSlot
|
535
|
+
DESCRIPTION : Performs a search on an class's instance
|
536
|
+
template slot array to find a slot by name
|
537
|
+
INPUTS : 1) The address of the class
|
538
|
+
2) The symbolic name of the slot
|
539
|
+
RETURNS : The index of the slot, -1 if not found
|
540
|
+
SIDE EFFECTS : None
|
541
|
+
NOTES : The slot's unique id is used as index into
|
542
|
+
the slot map array.
|
543
|
+
********************************************************************/
|
544
|
+
int FindInstanceTemplateSlot(
|
545
|
+
Environment *theEnv,
|
546
|
+
Defclass *cls,
|
547
|
+
CLIPSLexeme *sname)
|
548
|
+
{
|
549
|
+
unsigned short sid;
|
550
|
+
|
551
|
+
sid = FindSlotNameID(theEnv,sname);
|
552
|
+
if (sid == SLOT_NAME_NOT_FOUND)
|
553
|
+
return -1;
|
554
|
+
|
555
|
+
if (sid > cls->maxSlotNameID)
|
556
|
+
return -1;
|
557
|
+
|
558
|
+
return((int) cls->slotNameMap[sid] - 1);
|
559
|
+
}
|
560
|
+
|
561
|
+
/*******************************************************
|
562
|
+
NAME : PutSlotValue
|
563
|
+
DESCRIPTION : Evaluates new slot-expression and
|
564
|
+
stores it as a multifield
|
565
|
+
variable for the slot.
|
566
|
+
INPUTS : 1) The address of the instance
|
567
|
+
(NULL if no trace-messages desired)
|
568
|
+
2) The address of the slot
|
569
|
+
3) The address of the value
|
570
|
+
4) UDFValue pointer to store the
|
571
|
+
set value
|
572
|
+
5) The command doing the put-
|
573
|
+
RETURNS : False on errors, or true
|
574
|
+
SIDE EFFECTS : Old value deleted and new one allocated
|
575
|
+
Old value symbols deinstalled
|
576
|
+
New value symbols installed
|
577
|
+
NOTES : None
|
578
|
+
*******************************************************/
|
579
|
+
PutSlotError PutSlotValue(
|
580
|
+
Environment *theEnv,
|
581
|
+
Instance *ins,
|
582
|
+
InstanceSlot *sp,
|
583
|
+
UDFValue *val,
|
584
|
+
UDFValue *setVal,
|
585
|
+
const char *theCommand)
|
586
|
+
{
|
587
|
+
PutSlotError rv;
|
588
|
+
if ((rv = ValidSlotValue(theEnv,val,sp->desc,ins,theCommand)) != PSE_NO_ERROR)
|
589
|
+
{
|
590
|
+
setVal->value = FalseSymbol(theEnv);
|
591
|
+
return rv;
|
592
|
+
}
|
593
|
+
return DirectPutSlotValue(theEnv,ins,sp,val,setVal);
|
594
|
+
}
|
595
|
+
|
596
|
+
/*******************************************************
|
597
|
+
NAME : DirectPutSlotValue
|
598
|
+
DESCRIPTION : Evaluates new slot-expression and
|
599
|
+
stores it as a multifield
|
600
|
+
variable for the slot.
|
601
|
+
INPUTS : 1) The address of the instance
|
602
|
+
(NULL if no trace-messages desired)
|
603
|
+
2) The address of the slot
|
604
|
+
3) The address of the value
|
605
|
+
4) UDFValue pointer to store the
|
606
|
+
set value
|
607
|
+
RETURNS : False on errors, or true
|
608
|
+
SIDE EFFECTS : Old value deleted and new one allocated
|
609
|
+
Old value symbols deinstalled
|
610
|
+
New value symbols installed
|
611
|
+
NOTES : None
|
612
|
+
*******************************************************/
|
613
|
+
PutSlotError DirectPutSlotValue(
|
614
|
+
Environment *theEnv,
|
615
|
+
Instance *ins,
|
616
|
+
InstanceSlot *sp,
|
617
|
+
UDFValue *val,
|
618
|
+
UDFValue *setVal)
|
619
|
+
{
|
620
|
+
size_t i,j; /* 6.04 Bug Fix */
|
621
|
+
#if DEFRULE_CONSTRUCT
|
622
|
+
int sharedTraversalID;
|
623
|
+
InstanceSlot *bsp,**spaddr;
|
624
|
+
#endif
|
625
|
+
UDFValue tmpVal;
|
626
|
+
|
627
|
+
setVal->value = FalseSymbol(theEnv);
|
628
|
+
if (val == NULL)
|
629
|
+
{
|
630
|
+
SystemError(theEnv,"INSFUN",1);
|
631
|
+
ExitRouter(theEnv,EXIT_FAILURE);
|
632
|
+
}
|
633
|
+
else if (val->value == ProceduralPrimitiveData(theEnv)->NoParamValue)
|
634
|
+
{
|
635
|
+
if (sp->desc->dynamicDefault)
|
636
|
+
{
|
637
|
+
val = &tmpVal;
|
638
|
+
if (!EvaluateAndStoreInDataObject(theEnv,sp->desc->multiple,
|
639
|
+
(Expression *) sp->desc->defaultValue,val,true))
|
640
|
+
return PSE_EVALUATION_ERROR;
|
641
|
+
}
|
642
|
+
else if (sp->desc->defaultValue != NULL)
|
643
|
+
{ val = (UDFValue *) sp->desc->defaultValue; }
|
644
|
+
else
|
645
|
+
{
|
646
|
+
PrintErrorID(theEnv,"INSMNGR",14,false);
|
647
|
+
WriteString(theEnv,STDERR,"Override required for slot '");
|
648
|
+
WriteString(theEnv,STDERR,sp->desc->slotName->name->contents);
|
649
|
+
WriteString(theEnv,STDERR,"' in instance [");
|
650
|
+
WriteString(theEnv,STDERR,ins->name->contents);
|
651
|
+
WriteString(theEnv,STDERR,"].\n");
|
652
|
+
SetEvaluationError(theEnv,true);
|
653
|
+
return PSE_EVALUATION_ERROR;
|
654
|
+
}
|
655
|
+
}
|
656
|
+
#if DEFRULE_CONSTRUCT
|
657
|
+
if (EngineData(theEnv)->JoinOperationInProgress && sp->desc->reactive &&
|
658
|
+
(ins->cls->reactive || sp->desc->shared))
|
659
|
+
{
|
660
|
+
PrintErrorID(theEnv,"INSFUN",5,false);
|
661
|
+
WriteString(theEnv,STDERR,"Cannot modify reactive instance slots while ");
|
662
|
+
WriteString(theEnv,STDERR,"pattern-matching is in process.\n");
|
663
|
+
SetEvaluationError(theEnv,true);
|
664
|
+
return PSE_RULE_NETWORK_ERROR;
|
665
|
+
}
|
666
|
+
|
667
|
+
/* =============================================
|
668
|
+
If we are about to change a slot of an object
|
669
|
+
which is a basis for a firing rule, we need
|
670
|
+
to make sure that slot is copied first
|
671
|
+
============================================= */
|
672
|
+
if (ins->basisSlots != NULL)
|
673
|
+
{
|
674
|
+
spaddr = &ins->slotAddresses[ins->cls->slotNameMap[sp->desc->slotName->id] - 1];
|
675
|
+
bsp = ins->basisSlots + (spaddr - ins->slotAddresses);
|
676
|
+
if (bsp->value == NULL)
|
677
|
+
{
|
678
|
+
bsp->type = sp->type;
|
679
|
+
bsp->value = sp->value;
|
680
|
+
if (sp->desc->multiple)
|
681
|
+
RetainMultifield(theEnv,bsp->multifieldValue);
|
682
|
+
else
|
683
|
+
AtomInstall(theEnv,bsp->type,bsp->value);
|
684
|
+
}
|
685
|
+
}
|
686
|
+
|
687
|
+
#endif
|
688
|
+
if (sp->desc->multiple == 0)
|
689
|
+
{
|
690
|
+
AtomDeinstall(theEnv,sp->type,sp->value);
|
691
|
+
|
692
|
+
/* ======================================
|
693
|
+
Assumed that multfield already checked
|
694
|
+
to be of cardinality 1
|
695
|
+
====================================== */
|
696
|
+
if (val->header->type == MULTIFIELD_TYPE)
|
697
|
+
{
|
698
|
+
sp->type = val->multifieldValue->contents[val->begin].header->type;
|
699
|
+
sp->value = val->multifieldValue->contents[val->begin].value;
|
700
|
+
}
|
701
|
+
else
|
702
|
+
{
|
703
|
+
sp->type = val->header->type;
|
704
|
+
sp->value = val->value;
|
705
|
+
}
|
706
|
+
AtomInstall(theEnv,sp->type,sp->value);
|
707
|
+
setVal->value = sp->value;
|
708
|
+
}
|
709
|
+
else
|
710
|
+
{
|
711
|
+
ReleaseMultifield(theEnv,sp->multifieldValue);
|
712
|
+
AddToMultifieldList(theEnv,sp->multifieldValue);
|
713
|
+
sp->type = MULTIFIELD_TYPE;
|
714
|
+
if (val->header->type == MULTIFIELD_TYPE)
|
715
|
+
{
|
716
|
+
sp->value = CreateUnmanagedMultifield(theEnv,(unsigned long) val->range);
|
717
|
+
for (i = 0 , j = val->begin ; i < val->range ; i++ , j++)
|
718
|
+
{
|
719
|
+
sp->multifieldValue->contents[i].value = val->multifieldValue->contents[j].value;
|
720
|
+
}
|
721
|
+
}
|
722
|
+
else
|
723
|
+
{
|
724
|
+
sp->multifieldValue = CreateUnmanagedMultifield(theEnv,1L);
|
725
|
+
sp->multifieldValue->contents[0].value = val->value;
|
726
|
+
}
|
727
|
+
RetainMultifield(theEnv,sp->multifieldValue);
|
728
|
+
setVal->value = sp->value;
|
729
|
+
setVal->begin = 0;
|
730
|
+
setVal->range = sp->multifieldValue->length;
|
731
|
+
}
|
732
|
+
/* ==================================================
|
733
|
+
6.05 Bug fix - any slot set directly or indirectly
|
734
|
+
by a slot override or other side-effect during an
|
735
|
+
instance initialization should not have its
|
736
|
+
default value set
|
737
|
+
================================================== */
|
738
|
+
|
739
|
+
sp->override = ins->initializeInProgress;
|
740
|
+
|
741
|
+
#if DEBUGGING_FUNCTIONS
|
742
|
+
if (ins->cls->traceSlots &&
|
743
|
+
(! ConstructData(theEnv)->ClearReadyInProgress) &&
|
744
|
+
(! ConstructData(theEnv)->ClearInProgress))
|
745
|
+
{
|
746
|
+
if (sp->desc->shared)
|
747
|
+
WriteString(theEnv,STDOUT,"::= shared slot ");
|
748
|
+
else
|
749
|
+
WriteString(theEnv,STDOUT,"::= local slot ");
|
750
|
+
WriteString(theEnv,STDOUT,sp->desc->slotName->name->contents);
|
751
|
+
WriteString(theEnv,STDOUT," in instance ");
|
752
|
+
WriteString(theEnv,STDOUT,ins->name->contents);
|
753
|
+
WriteString(theEnv,STDOUT," <- ");
|
754
|
+
if (sp->type != MULTIFIELD_TYPE)
|
755
|
+
PrintAtom(theEnv,STDOUT,sp->type,sp->value);
|
756
|
+
else
|
757
|
+
PrintMultifieldDriver(theEnv,STDOUT,sp->multifieldValue,0,
|
758
|
+
sp->multifieldValue->length,true);
|
759
|
+
WriteString(theEnv,STDOUT,"\n");
|
760
|
+
}
|
761
|
+
#endif
|
762
|
+
InstanceData(theEnv)->ChangesToInstances = true;
|
763
|
+
|
764
|
+
#if DEFRULE_CONSTRUCT
|
765
|
+
if (ins->cls->reactive && sp->desc->reactive)
|
766
|
+
{
|
767
|
+
/* ============================================
|
768
|
+
If we have changed a shared slot, we need to
|
769
|
+
perform a Rete update for every instance
|
770
|
+
which contains this slot
|
771
|
+
============================================ */
|
772
|
+
if (sp->desc->shared)
|
773
|
+
{
|
774
|
+
sharedTraversalID = GetTraversalID(theEnv);
|
775
|
+
if (sharedTraversalID != -1)
|
776
|
+
{
|
777
|
+
NetworkModifyForSharedSlot(theEnv,sharedTraversalID,sp->desc->cls,sp->desc);
|
778
|
+
ReleaseTraversalID(theEnv);
|
779
|
+
}
|
780
|
+
else
|
781
|
+
{
|
782
|
+
PrintErrorID(theEnv,"INSFUN",6,false);
|
783
|
+
WriteString(theEnv,STDERR,"Unable to pattern-match on shared slot '");
|
784
|
+
WriteString(theEnv,STDERR,sp->desc->slotName->name->contents);
|
785
|
+
WriteString(theEnv,STDERR,"' in class '");
|
786
|
+
WriteString(theEnv,STDERR,DefclassName(sp->desc->cls));
|
787
|
+
WriteString(theEnv,STDERR,"'.\n");
|
788
|
+
return PSE_RULE_NETWORK_ERROR;
|
789
|
+
}
|
790
|
+
}
|
791
|
+
else
|
792
|
+
ObjectNetworkAction(theEnv,OBJECT_MODIFY,ins,(int) sp->desc->slotName->id);
|
793
|
+
}
|
794
|
+
#endif
|
795
|
+
|
796
|
+
return PSE_NO_ERROR;
|
797
|
+
}
|
798
|
+
|
799
|
+
/*******************************************************************
|
800
|
+
NAME : ValidSlotValue
|
801
|
+
DESCRIPTION : Determines if a value is appropriate
|
802
|
+
for a slot-value
|
803
|
+
INPUTS : 1) The value buffer
|
804
|
+
2) Slot descriptor
|
805
|
+
3) Instance for which slot is being checked
|
806
|
+
(can be NULL)
|
807
|
+
4) Buffer holding printout of the offending command
|
808
|
+
(if NULL assumes message-handler is executing
|
809
|
+
and calls PrintHandler for CurrentCore instead)
|
810
|
+
RETURNS : True if value is OK, false otherwise
|
811
|
+
SIDE EFFECTS : Sets EvaluationError if slot is not OK
|
812
|
+
NOTES : Examines all fields of a multi-field
|
813
|
+
*******************************************************************/
|
814
|
+
PutSlotError ValidSlotValue(
|
815
|
+
Environment *theEnv,
|
816
|
+
UDFValue *val,
|
817
|
+
SlotDescriptor *sd,
|
818
|
+
Instance *ins,
|
819
|
+
const char *theCommand)
|
820
|
+
{
|
821
|
+
ConstraintViolationType violationCode;
|
822
|
+
|
823
|
+
/* ===================================
|
824
|
+
Special NoParamValue means to reset
|
825
|
+
slot to default value
|
826
|
+
=================================== */
|
827
|
+
if (val->value == ProceduralPrimitiveData(theEnv)->NoParamValue)
|
828
|
+
return PSE_NO_ERROR;
|
829
|
+
if ((sd->multiple == 0) && (val->header->type == MULTIFIELD_TYPE) &&
|
830
|
+
(val->range != 1))
|
831
|
+
{
|
832
|
+
PrintErrorID(theEnv,"INSFUN",7,false);
|
833
|
+
WriteString(theEnv,STDERR,"The value ");
|
834
|
+
WriteUDFValue(theEnv,STDERR,val);
|
835
|
+
WriteString(theEnv,STDERR," is illegal for single-field ");
|
836
|
+
PrintSlot(theEnv,STDERR,sd,ins,theCommand);
|
837
|
+
WriteString(theEnv,STDERR,".\n");
|
838
|
+
SetEvaluationError(theEnv,true);
|
839
|
+
return PSE_CARDINALITY_ERROR;
|
840
|
+
}
|
841
|
+
if (val->header->type == VOID_TYPE)
|
842
|
+
{
|
843
|
+
PrintErrorID(theEnv,"INSFUN",8,false);
|
844
|
+
WriteString(theEnv,STDERR,"Void function illegal value for ");
|
845
|
+
PrintSlot(theEnv,STDERR,sd,ins,theCommand);
|
846
|
+
WriteString(theEnv,STDERR,".\n");
|
847
|
+
SetEvaluationError(theEnv,true);
|
848
|
+
return PSE_CARDINALITY_ERROR;
|
849
|
+
}
|
850
|
+
if (GetDynamicConstraintChecking(theEnv))
|
851
|
+
{
|
852
|
+
violationCode = ConstraintCheckDataObject(theEnv,val,sd->constraint);
|
853
|
+
if (violationCode != NO_VIOLATION)
|
854
|
+
{
|
855
|
+
PrintErrorID(theEnv,"CSTRNCHK",1,false);
|
856
|
+
WriteString(theEnv,STDERR,"The value ");
|
857
|
+
if ((val->header->type == MULTIFIELD_TYPE) && (sd->multiple == 0))
|
858
|
+
PrintAtom(theEnv,STDERR,val->multifieldValue->contents[val->begin].header->type,
|
859
|
+
val->multifieldValue->contents[val->begin].value);
|
860
|
+
else
|
861
|
+
WriteUDFValue(theEnv,STDERR,val);
|
862
|
+
WriteString(theEnv,STDERR," for ");
|
863
|
+
PrintSlot(theEnv,STDERR,sd,ins,theCommand);
|
864
|
+
ConstraintViolationErrorMessage(theEnv,NULL,NULL,0,0,NULL,0,
|
865
|
+
violationCode,sd->constraint,false);
|
866
|
+
SetEvaluationError(theEnv,true);
|
867
|
+
|
868
|
+
switch(violationCode)
|
869
|
+
{
|
870
|
+
case NO_VIOLATION:
|
871
|
+
SystemError(theEnv,"FACTMNGR",2);
|
872
|
+
ExitRouter(theEnv,EXIT_FAILURE);
|
873
|
+
break;
|
874
|
+
|
875
|
+
case FUNCTION_RETURN_TYPE_VIOLATION:
|
876
|
+
case TYPE_VIOLATION:
|
877
|
+
return PSE_TYPE_ERROR;
|
878
|
+
|
879
|
+
case RANGE_VIOLATION:
|
880
|
+
return PSE_RANGE_ERROR;
|
881
|
+
|
882
|
+
case ALLOWED_VALUES_VIOLATION:
|
883
|
+
return PSE_ALLOWED_VALUES_ERROR;
|
884
|
+
|
885
|
+
case CARDINALITY_VIOLATION:
|
886
|
+
return PSE_CARDINALITY_ERROR;
|
887
|
+
|
888
|
+
case ALLOWED_CLASSES_VIOLATION:
|
889
|
+
return PSE_ALLOWED_CLASSES_ERROR;
|
890
|
+
}
|
891
|
+
}
|
892
|
+
}
|
893
|
+
return PSE_NO_ERROR;
|
894
|
+
}
|
895
|
+
|
896
|
+
/********************************************************
|
897
|
+
NAME : CheckInstance
|
898
|
+
DESCRIPTION : Checks to see if the first argument to
|
899
|
+
a function is a valid instance
|
900
|
+
INPUTS : Name of the calling function
|
901
|
+
RETURNS : The address of the instance
|
902
|
+
SIDE EFFECTS : EvaluationError set and messages printed
|
903
|
+
on errors
|
904
|
+
NOTES : Used by Initialize and ModifyInstance
|
905
|
+
********************************************************/
|
906
|
+
Instance *CheckInstance(
|
907
|
+
UDFContext *context)
|
908
|
+
{
|
909
|
+
Instance *ins;
|
910
|
+
UDFValue temp;
|
911
|
+
Environment *theEnv = context->environment;
|
912
|
+
|
913
|
+
UDFFirstArgument(context,ANY_TYPE_BITS,&temp);
|
914
|
+
if (temp.header->type == INSTANCE_ADDRESS_TYPE)
|
915
|
+
{
|
916
|
+
ins = temp.instanceValue;
|
917
|
+
if (ins->garbage == 1)
|
918
|
+
{
|
919
|
+
StaleInstanceAddress(theEnv,UDFContextFunctionName(context),0);
|
920
|
+
SetEvaluationError(theEnv,true);
|
921
|
+
return NULL;
|
922
|
+
}
|
923
|
+
}
|
924
|
+
else if (temp.header->type == INSTANCE_NAME_TYPE)
|
925
|
+
{
|
926
|
+
ins = FindInstanceBySymbol(theEnv,temp.lexemeValue);
|
927
|
+
if (ins == NULL)
|
928
|
+
{
|
929
|
+
NoInstanceError(theEnv,temp.lexemeValue->contents,UDFContextFunctionName(context));
|
930
|
+
return NULL;
|
931
|
+
}
|
932
|
+
}
|
933
|
+
else if (temp.header->type == SYMBOL_TYPE)
|
934
|
+
{
|
935
|
+
temp.value = CreateInstanceName(theEnv,temp.lexemeValue->contents);
|
936
|
+
ins = FindInstanceBySymbol(theEnv,temp.lexemeValue);
|
937
|
+
if (ins == NULL)
|
938
|
+
{
|
939
|
+
NoInstanceError(theEnv,temp.lexemeValue->contents,UDFContextFunctionName(context));
|
940
|
+
return NULL;
|
941
|
+
}
|
942
|
+
}
|
943
|
+
else
|
944
|
+
{
|
945
|
+
PrintErrorID(theEnv,"INSFUN",1,false);
|
946
|
+
WriteString(theEnv,STDERR,"Expected a valid instance in function '");
|
947
|
+
WriteString(theEnv,STDERR,UDFContextFunctionName(context));
|
948
|
+
WriteString(theEnv,STDERR,"'.\n");
|
949
|
+
SetEvaluationError(theEnv,true);
|
950
|
+
return NULL;
|
951
|
+
}
|
952
|
+
return(ins);
|
953
|
+
}
|
954
|
+
|
955
|
+
/***************************************************
|
956
|
+
NAME : NoInstanceError
|
957
|
+
DESCRIPTION : Prints out an appropriate error
|
958
|
+
message when an instance cannot be
|
959
|
+
found for a function
|
960
|
+
INPUTS : 1) The instance name
|
961
|
+
2) The function name
|
962
|
+
RETURNS : Nothing useful
|
963
|
+
SIDE EFFECTS : None
|
964
|
+
NOTES : None
|
965
|
+
***************************************************/
|
966
|
+
void NoInstanceError(
|
967
|
+
Environment *theEnv,
|
968
|
+
const char *iname,
|
969
|
+
const char *func)
|
970
|
+
{
|
971
|
+
PrintErrorID(theEnv,"INSFUN",2,false);
|
972
|
+
WriteString(theEnv,STDERR,"No such instance [");
|
973
|
+
WriteString(theEnv,STDERR,iname);
|
974
|
+
WriteString(theEnv,STDERR,"] in function '");
|
975
|
+
WriteString(theEnv,STDERR,func);
|
976
|
+
WriteString(theEnv,STDERR,"'.\n");
|
977
|
+
SetEvaluationError(theEnv,true);
|
978
|
+
}
|
979
|
+
|
980
|
+
/***************************************************
|
981
|
+
NAME : StaleInstanceAddress
|
982
|
+
DESCRIPTION : Prints out an appropriate error
|
983
|
+
message when an instance address
|
984
|
+
is no longer valid
|
985
|
+
INPUTS : The function name
|
986
|
+
RETURNS : Nothing useful
|
987
|
+
SIDE EFFECTS : None
|
988
|
+
NOTES : None
|
989
|
+
***************************************************/
|
990
|
+
void StaleInstanceAddress(
|
991
|
+
Environment *theEnv,
|
992
|
+
const char *func,
|
993
|
+
int whichArg)
|
994
|
+
{
|
995
|
+
PrintErrorID(theEnv,"INSFUN",4,false);
|
996
|
+
WriteString(theEnv,STDERR,"Invalid instance-address in function '");
|
997
|
+
WriteString(theEnv,STDERR,func);
|
998
|
+
WriteString(theEnv,STDERR,"'");
|
999
|
+
if (whichArg > 0)
|
1000
|
+
{
|
1001
|
+
WriteString(theEnv,STDERR,", argument #");
|
1002
|
+
WriteInteger(theEnv,STDERR,whichArg);
|
1003
|
+
}
|
1004
|
+
WriteString(theEnv,STDERR,".\n");
|
1005
|
+
}
|
1006
|
+
|
1007
|
+
/**********************************************************************
|
1008
|
+
NAME : GetInstancesChanged
|
1009
|
+
DESCRIPTION : Returns whether instances have changed
|
1010
|
+
(any were added/deleted or slot values were changed)
|
1011
|
+
since last time flag was set to false
|
1012
|
+
INPUTS : None
|
1013
|
+
RETURNS : The instances-changed flag
|
1014
|
+
SIDE EFFECTS : None
|
1015
|
+
NOTES : Used by interfaces to update instance windows
|
1016
|
+
**********************************************************************/
|
1017
|
+
bool GetInstancesChanged(
|
1018
|
+
Environment *theEnv)
|
1019
|
+
{
|
1020
|
+
return InstanceData(theEnv)->ChangesToInstances;
|
1021
|
+
}
|
1022
|
+
|
1023
|
+
/*******************************************************
|
1024
|
+
NAME : SetInstancesChanged
|
1025
|
+
DESCRIPTION : Sets instances-changed flag (see above)
|
1026
|
+
INPUTS : The value (true or false)
|
1027
|
+
RETURNS : Nothing useful
|
1028
|
+
SIDE EFFECTS : The flag is set
|
1029
|
+
NOTES : None
|
1030
|
+
*******************************************************/
|
1031
|
+
void SetInstancesChanged(
|
1032
|
+
Environment *theEnv,
|
1033
|
+
bool changed)
|
1034
|
+
{
|
1035
|
+
InstanceData(theEnv)->ChangesToInstances = changed;
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
/*******************************************************************
|
1039
|
+
NAME : PrintSlot
|
1040
|
+
DESCRIPTION : Displays the name and origin of a slot
|
1041
|
+
INPUTS : 1) The logical output name
|
1042
|
+
2) The slot descriptor
|
1043
|
+
3) The instance source (can be NULL)
|
1044
|
+
4) Buffer holding printout of the offending command
|
1045
|
+
(if NULL assumes message-handler is executing
|
1046
|
+
and calls PrintHandler for CurrentCore instead)
|
1047
|
+
RETURNS : Nothing useful
|
1048
|
+
SIDE EFFECTS : Message printed
|
1049
|
+
NOTES : None
|
1050
|
+
*******************************************************************/
|
1051
|
+
void PrintSlot(
|
1052
|
+
Environment *theEnv,
|
1053
|
+
const char *logName,
|
1054
|
+
SlotDescriptor *sd,
|
1055
|
+
Instance *ins,
|
1056
|
+
const char *theCommand)
|
1057
|
+
{
|
1058
|
+
WriteString(theEnv,logName,"slot '");
|
1059
|
+
WriteString(theEnv,logName,sd->slotName->name->contents);
|
1060
|
+
WriteString(theEnv,logName,"'");
|
1061
|
+
if (ins != NULL)
|
1062
|
+
{
|
1063
|
+
WriteString(theEnv,logName," of instance [");
|
1064
|
+
WriteString(theEnv,logName,ins->name->contents);
|
1065
|
+
WriteString(theEnv,logName,"]");
|
1066
|
+
}
|
1067
|
+
else if (sd->cls != NULL)
|
1068
|
+
{
|
1069
|
+
WriteString(theEnv,logName," of class '");
|
1070
|
+
WriteString(theEnv,logName,DefclassName(sd->cls));
|
1071
|
+
WriteString(theEnv,logName," of class '");
|
1072
|
+
}
|
1073
|
+
WriteString(theEnv,logName," found in ");
|
1074
|
+
if (theCommand != NULL)
|
1075
|
+
WriteString(theEnv,logName,theCommand);
|
1076
|
+
else
|
1077
|
+
PrintHandler(theEnv,logName,MessageHandlerData(theEnv)->CurrentCore->hnd,true,false);
|
1078
|
+
}
|
1079
|
+
|
1080
|
+
/*****************************************************
|
1081
|
+
NAME : PrintInstanceNameAndClass
|
1082
|
+
DESCRIPTION : Displays an instance's name and class
|
1083
|
+
INPUTS : 1) Logical name of output
|
1084
|
+
2) The instance
|
1085
|
+
3) Flag indicating whether to
|
1086
|
+
print carriage-return at end
|
1087
|
+
RETURNS : Nothing useful
|
1088
|
+
SIDE EFFECTS : Instnace name and class printed
|
1089
|
+
NOTES : None
|
1090
|
+
*****************************************************/
|
1091
|
+
void PrintInstanceNameAndClass(
|
1092
|
+
Environment *theEnv,
|
1093
|
+
const char *logicalName,
|
1094
|
+
Instance *theInstance,
|
1095
|
+
bool linefeedFlag)
|
1096
|
+
{
|
1097
|
+
WriteString(theEnv,logicalName,"[");
|
1098
|
+
WriteString(theEnv,logicalName,InstanceName(theInstance));
|
1099
|
+
WriteString(theEnv,logicalName,"] of ");
|
1100
|
+
PrintClassName(theEnv,logicalName,theInstance->cls,false,linefeedFlag);
|
1101
|
+
}
|
1102
|
+
|
1103
|
+
/***************************************************
|
1104
|
+
NAME : PrintInstanceName
|
1105
|
+
DESCRIPTION : Used by the rule system commands
|
1106
|
+
such as (matches) and (agenda)
|
1107
|
+
to print out the name of an instance
|
1108
|
+
INPUTS : 1) The logical output name
|
1109
|
+
2) A pointer to the instance
|
1110
|
+
RETURNS : Nothing useful
|
1111
|
+
SIDE EFFECTS : Name of instance printed
|
1112
|
+
NOTES : None
|
1113
|
+
***************************************************/
|
1114
|
+
void PrintInstanceName(
|
1115
|
+
Environment *theEnv,
|
1116
|
+
const char *logName,
|
1117
|
+
Instance *theInstance)
|
1118
|
+
{
|
1119
|
+
if (theInstance->garbage)
|
1120
|
+
{
|
1121
|
+
WriteString(theEnv,logName,"<stale instance [");
|
1122
|
+
WriteString(theEnv,logName,theInstance->name->contents);
|
1123
|
+
WriteString(theEnv,logName,"]>");
|
1124
|
+
}
|
1125
|
+
else
|
1126
|
+
{
|
1127
|
+
WriteString(theEnv,logName,"[");
|
1128
|
+
WriteString(theEnv,logName,GetFullInstanceName(theEnv,theInstance)->contents);
|
1129
|
+
WriteString(theEnv,logName,"]");
|
1130
|
+
}
|
1131
|
+
}
|
1132
|
+
|
1133
|
+
/***************************************************
|
1134
|
+
NAME : PrintInstanceLongForm
|
1135
|
+
DESCRIPTION : Used by kernel to print
|
1136
|
+
instance addresses
|
1137
|
+
INPUTS : 1) The logical output name
|
1138
|
+
2) A pointer to the instance
|
1139
|
+
RETURNS : Nothing useful
|
1140
|
+
SIDE EFFECTS : Address of instance printed
|
1141
|
+
NOTES : None
|
1142
|
+
***************************************************/
|
1143
|
+
void PrintInstanceLongForm(
|
1144
|
+
Environment *theEnv,
|
1145
|
+
const char *logName,
|
1146
|
+
Instance *theInstance)
|
1147
|
+
{
|
1148
|
+
if (PrintUtilityData(theEnv)->InstanceAddressesToNames)
|
1149
|
+
{
|
1150
|
+
if (theInstance == &InstanceData(theEnv)->DummyInstance)
|
1151
|
+
WriteString(theEnv,logName,"\"<Dummy Instance>\"");
|
1152
|
+
else
|
1153
|
+
{
|
1154
|
+
WriteString(theEnv,logName,"[");
|
1155
|
+
WriteString(theEnv,logName,GetFullInstanceName(theEnv,theInstance)->contents);
|
1156
|
+
WriteString(theEnv,logName,"]");
|
1157
|
+
}
|
1158
|
+
}
|
1159
|
+
else
|
1160
|
+
{
|
1161
|
+
if (PrintUtilityData(theEnv)->AddressesToStrings)
|
1162
|
+
WriteString(theEnv,logName,"\"");
|
1163
|
+
if (theInstance == &InstanceData(theEnv)->DummyInstance)
|
1164
|
+
WriteString(theEnv,logName,"<Dummy Instance>");
|
1165
|
+
else if (theInstance->garbage)
|
1166
|
+
{
|
1167
|
+
WriteString(theEnv,logName,"<Stale Instance-");
|
1168
|
+
WriteString(theEnv,logName,theInstance->name->contents);
|
1169
|
+
WriteString(theEnv,logName,">");
|
1170
|
+
}
|
1171
|
+
else
|
1172
|
+
{
|
1173
|
+
WriteString(theEnv,logName,"<Instance-");
|
1174
|
+
WriteString(theEnv,logName,GetFullInstanceName(theEnv,theInstance)->contents);
|
1175
|
+
WriteString(theEnv,logName,">");
|
1176
|
+
}
|
1177
|
+
if (PrintUtilityData(theEnv)->AddressesToStrings)
|
1178
|
+
WriteString(theEnv,logName,"\"");
|
1179
|
+
}
|
1180
|
+
}
|
1181
|
+
|
1182
|
+
#if DEFRULE_CONSTRUCT
|
1183
|
+
|
1184
|
+
/***************************************************
|
1185
|
+
NAME : DecrementObjectBasisCount
|
1186
|
+
DESCRIPTION : Decrements the basis count of an
|
1187
|
+
object indicating that it is in
|
1188
|
+
use by the partial match of the
|
1189
|
+
currently executing rule
|
1190
|
+
INPUTS : The instance address
|
1191
|
+
RETURNS : Nothing useful
|
1192
|
+
SIDE EFFECTS : Basis count decremented and
|
1193
|
+
basis copy (possibly) deleted
|
1194
|
+
NOTES : When the count goes to zero, the
|
1195
|
+
basis copy of the object (if any)
|
1196
|
+
is deleted.
|
1197
|
+
***************************************************/
|
1198
|
+
void DecrementObjectBasisCount(
|
1199
|
+
Environment *theEnv,
|
1200
|
+
Instance *theInstance)
|
1201
|
+
{
|
1202
|
+
long i;
|
1203
|
+
|
1204
|
+
theInstance->patternHeader.busyCount--;
|
1205
|
+
if (theInstance->patternHeader.busyCount == 0)
|
1206
|
+
{
|
1207
|
+
if (theInstance->garbage)
|
1208
|
+
RemoveInstanceData(theEnv,theInstance);
|
1209
|
+
if (theInstance->cls->instanceSlotCount != 0)
|
1210
|
+
{
|
1211
|
+
for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++)
|
1212
|
+
if (theInstance->basisSlots[i].value != NULL)
|
1213
|
+
{
|
1214
|
+
if (theInstance->basisSlots[i].desc->multiple)
|
1215
|
+
ReleaseMultifield(theEnv,theInstance->basisSlots[i].multifieldValue);
|
1216
|
+
else
|
1217
|
+
AtomDeinstall(theEnv,theInstance->basisSlots[i].type,
|
1218
|
+
theInstance->basisSlots[i].value);
|
1219
|
+
}
|
1220
|
+
rm(theEnv,theInstance->basisSlots,
|
1221
|
+
(theInstance->cls->instanceSlotCount * sizeof(InstanceSlot)));
|
1222
|
+
theInstance->basisSlots = NULL;
|
1223
|
+
}
|
1224
|
+
}
|
1225
|
+
}
|
1226
|
+
|
1227
|
+
/***************************************************
|
1228
|
+
NAME : IncrementObjectBasisCount
|
1229
|
+
DESCRIPTION : Increments the basis count of an
|
1230
|
+
object indicating that it is in
|
1231
|
+
use by the partial match of the
|
1232
|
+
currently executing rule
|
1233
|
+
|
1234
|
+
If this the count was zero,
|
1235
|
+
allocate an array of extra
|
1236
|
+
instance slots for use by
|
1237
|
+
slot variables
|
1238
|
+
INPUTS : The instance address
|
1239
|
+
RETURNS : Nothing useful
|
1240
|
+
SIDE EFFECTS : Basis count incremented
|
1241
|
+
NOTES : None
|
1242
|
+
***************************************************/
|
1243
|
+
void IncrementObjectBasisCount(
|
1244
|
+
Environment *theEnv,
|
1245
|
+
Instance *theInstance)
|
1246
|
+
{
|
1247
|
+
long i;
|
1248
|
+
|
1249
|
+
if (theInstance->patternHeader.busyCount == 0)
|
1250
|
+
{
|
1251
|
+
if (theInstance->cls->instanceSlotCount != 0)
|
1252
|
+
{
|
1253
|
+
theInstance->basisSlots = (InstanceSlot *)
|
1254
|
+
gm2(theEnv,(sizeof(InstanceSlot) * theInstance->cls->instanceSlotCount));
|
1255
|
+
for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++)
|
1256
|
+
{
|
1257
|
+
theInstance->basisSlots[i].desc = theInstance->slotAddresses[i]->desc;
|
1258
|
+
theInstance->basisSlots[i].value = NULL;
|
1259
|
+
}
|
1260
|
+
}
|
1261
|
+
}
|
1262
|
+
theInstance->patternHeader.busyCount++;
|
1263
|
+
}
|
1264
|
+
|
1265
|
+
/***************************************************
|
1266
|
+
NAME : MatchObjectFunction
|
1267
|
+
DESCRIPTION : Filters an instance through the
|
1268
|
+
object pattern network
|
1269
|
+
Used for incremental resets in
|
1270
|
+
binary loads and run-time modules
|
1271
|
+
INPUTS : The instance
|
1272
|
+
RETURNS : Nothing useful
|
1273
|
+
SIDE EFFECTS : Instance pattern-matched
|
1274
|
+
NOTES : None
|
1275
|
+
***************************************************/
|
1276
|
+
void MatchObjectFunction(
|
1277
|
+
Environment *theEnv,
|
1278
|
+
Instance *theInstance)
|
1279
|
+
{
|
1280
|
+
ObjectNetworkAction(theEnv,OBJECT_ASSERT,theInstance,-1);
|
1281
|
+
}
|
1282
|
+
|
1283
|
+
/***************************************************
|
1284
|
+
NAME : NetworkSynchronized
|
1285
|
+
DESCRIPTION : Determines if state of instance is
|
1286
|
+
consistent with last push through
|
1287
|
+
pattern-matching network
|
1288
|
+
INPUTS : The instance
|
1289
|
+
RETURNS : True if instance has not
|
1290
|
+
changed since last push through the
|
1291
|
+
Rete network, false otherwise
|
1292
|
+
SIDE EFFECTS : None
|
1293
|
+
NOTES : None
|
1294
|
+
***************************************************/
|
1295
|
+
bool NetworkSynchronized(
|
1296
|
+
Environment *theEnv,
|
1297
|
+
Instance *theInstance)
|
1298
|
+
{
|
1299
|
+
#if MAC_XCD
|
1300
|
+
#pragma unused(theEnv)
|
1301
|
+
#endif
|
1302
|
+
|
1303
|
+
return theInstance->reteSynchronized;
|
1304
|
+
}
|
1305
|
+
|
1306
|
+
/***************************************************
|
1307
|
+
NAME : InstanceIsDeleted
|
1308
|
+
DESCRIPTION : Determines if an instance has been
|
1309
|
+
deleted
|
1310
|
+
INPUTS : The instance
|
1311
|
+
RETURNS : True if instance has been deleted,
|
1312
|
+
false otherwise
|
1313
|
+
SIDE EFFECTS : None
|
1314
|
+
NOTES : None
|
1315
|
+
***************************************************/
|
1316
|
+
bool InstanceIsDeleted(
|
1317
|
+
Environment *theEnv,
|
1318
|
+
Instance *theInstance)
|
1319
|
+
{
|
1320
|
+
#if MAC_XCD
|
1321
|
+
#pragma unused(theEnv)
|
1322
|
+
#endif
|
1323
|
+
|
1324
|
+
return theInstance->garbage;
|
1325
|
+
}
|
1326
|
+
#endif
|
1327
|
+
|
1328
|
+
/* =========================================
|
1329
|
+
*****************************************
|
1330
|
+
INTERNALLY VISIBLE FUNCTIONS
|
1331
|
+
=========================================
|
1332
|
+
***************************************** */
|
1333
|
+
|
1334
|
+
/*****************************************************
|
1335
|
+
NAME : FindImportedInstance
|
1336
|
+
DESCRIPTION : Searches imported modules for an
|
1337
|
+
instance of the correct name
|
1338
|
+
The imports are searched recursively
|
1339
|
+
in the order of the module definition
|
1340
|
+
INPUTS : 1) The module for which to
|
1341
|
+
search imported modules
|
1342
|
+
2) The currently active module
|
1343
|
+
3) The first instance of the
|
1344
|
+
correct name (cannot be NULL)
|
1345
|
+
RETURNS : An instance of the correct name
|
1346
|
+
imported from another module which
|
1347
|
+
is in scope of the current module
|
1348
|
+
SIDE EFFECTS : None
|
1349
|
+
NOTES : None
|
1350
|
+
*****************************************************/
|
1351
|
+
static Instance *FindImportedInstance(
|
1352
|
+
Environment *theEnv,
|
1353
|
+
Defmodule *theModule,
|
1354
|
+
Defmodule *currentModule,
|
1355
|
+
Instance *startInstance)
|
1356
|
+
{
|
1357
|
+
struct portItem *importList;
|
1358
|
+
Instance *ins;
|
1359
|
+
|
1360
|
+
if (theModule->visitedFlag)
|
1361
|
+
return NULL;
|
1362
|
+
theModule->visitedFlag = true;
|
1363
|
+
importList = theModule->importList;
|
1364
|
+
while (importList != NULL)
|
1365
|
+
{
|
1366
|
+
theModule = FindDefmodule(theEnv,importList->moduleName->contents);
|
1367
|
+
for (ins = startInstance ;
|
1368
|
+
(ins != NULL) ? (ins->name == startInstance->name) : false ;
|
1369
|
+
ins = ins->nxtHash)
|
1370
|
+
if ((ins->cls->header.whichModule->theModule == theModule) &&
|
1371
|
+
DefclassInScope(theEnv,ins->cls,currentModule))
|
1372
|
+
return(ins);
|
1373
|
+
ins = FindImportedInstance(theEnv,theModule,currentModule,startInstance);
|
1374
|
+
if (ins != NULL)
|
1375
|
+
return(ins);
|
1376
|
+
importList = importList->next;
|
1377
|
+
}
|
1378
|
+
|
1379
|
+
/* ========================================================
|
1380
|
+
Make sure instances of system classes are always visible
|
1381
|
+
======================================================== */
|
1382
|
+
for (ins = startInstance ;
|
1383
|
+
(ins != NULL) ? (ins->name == startInstance->name) : false ;
|
1384
|
+
ins = ins->nxtHash)
|
1385
|
+
if (ins->cls->system)
|
1386
|
+
return(ins);
|
1387
|
+
|
1388
|
+
return NULL;
|
1389
|
+
}
|
1390
|
+
|
1391
|
+
#if DEFRULE_CONSTRUCT
|
1392
|
+
|
1393
|
+
/*****************************************************
|
1394
|
+
NAME : NetworkModifyForSharedSlot
|
1395
|
+
DESCRIPTION : Performs a Rete network modify for
|
1396
|
+
all instances which contain a
|
1397
|
+
specific shared slot
|
1398
|
+
INPUTS : 1) The traversal id to use when
|
1399
|
+
recursively entering subclasses
|
1400
|
+
to prevent duplicate examinations
|
1401
|
+
of a class
|
1402
|
+
2) The class
|
1403
|
+
3) The descriptor for the shared slot
|
1404
|
+
RETURNS : Nothing useful
|
1405
|
+
SIDE EFFECTS : Instances which contain the shared
|
1406
|
+
slot are filtered through the
|
1407
|
+
Rete network via a retract/assert
|
1408
|
+
NOTES : Assumes traversal id has been
|
1409
|
+
established
|
1410
|
+
*****************************************************/
|
1411
|
+
static void NetworkModifyForSharedSlot(
|
1412
|
+
Environment *theEnv,
|
1413
|
+
int sharedTraversalID,
|
1414
|
+
Defclass *cls,
|
1415
|
+
SlotDescriptor *sd)
|
1416
|
+
{
|
1417
|
+
Instance *ins;
|
1418
|
+
unsigned long i;
|
1419
|
+
|
1420
|
+
/* ================================================
|
1421
|
+
Make sure we haven't already examined this class
|
1422
|
+
================================================ */
|
1423
|
+
if (TestTraversalID(cls->traversalRecord,sharedTraversalID))
|
1424
|
+
return;
|
1425
|
+
SetTraversalID(cls->traversalRecord,sharedTraversalID);
|
1426
|
+
|
1427
|
+
/* ===========================================
|
1428
|
+
If the instances of this class contain the
|
1429
|
+
shared slot, send update events to the Rete
|
1430
|
+
network for all of its instances
|
1431
|
+
=========================================== */
|
1432
|
+
if ((sd->slotName->id > cls->maxSlotNameID) ? false :
|
1433
|
+
((cls->slotNameMap[sd->slotName->id] == 0) ? false :
|
1434
|
+
(cls->instanceTemplate[cls->slotNameMap[sd->slotName->id] - 1] == sd)))
|
1435
|
+
{
|
1436
|
+
for (ins = cls->instanceList ; ins != NULL ; ins = ins->nxtClass)
|
1437
|
+
ObjectNetworkAction(theEnv,OBJECT_MODIFY,ins,(int) sd->slotName->id);
|
1438
|
+
}
|
1439
|
+
|
1440
|
+
/* ==================================
|
1441
|
+
Check the subclasses of this class
|
1442
|
+
================================== */
|
1443
|
+
for (i = 0 ; i < cls->directSubclasses.classCount ; i++)
|
1444
|
+
NetworkModifyForSharedSlot(theEnv,sharedTraversalID,cls->directSubclasses.classArray[i],sd);
|
1445
|
+
}
|
1446
|
+
|
1447
|
+
#endif /* DEFRULE_CONSTRUCT */
|
1448
|
+
|
1449
|
+
#endif /* OBJECT_SYSTEM */
|
1450
|
+
|
1451
|
+
|