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,1373 @@
|
|
1
|
+
/*******************************************************/
|
2
|
+
/* "C" Language Integrated Production System */
|
3
|
+
/* */
|
4
|
+
/* CLIPS Version 6.41 01/29/23 */
|
5
|
+
/* */
|
6
|
+
/* AGENDA MODULE */
|
7
|
+
/*******************************************************/
|
8
|
+
|
9
|
+
/*************************************************************/
|
10
|
+
/* Purpose: */
|
11
|
+
/* Provides functionality for examining, manipulating, */
|
12
|
+
/* adding, and removing activations from the agenda. */
|
13
|
+
/* */
|
14
|
+
/* Principal Programmer(s): */
|
15
|
+
/* Gary D. Riley */
|
16
|
+
/* */
|
17
|
+
/* Contributing Programmer(s): */
|
18
|
+
/* Brian L. Dantes */
|
19
|
+
/* */
|
20
|
+
/* Revision History: */
|
21
|
+
/* 6.23: Corrected compilation errors for files */
|
22
|
+
/* generated by constructs-to-c. DR0861 */
|
23
|
+
/* */
|
24
|
+
/* 6.24: Removed CONFLICT_RESOLUTION_STRATEGIES */
|
25
|
+
/* and DYNAMIC_SALIENCE compilation flags. */
|
26
|
+
/* */
|
27
|
+
/* Renamed BOOLEAN macro type to intBool. */
|
28
|
+
/* */
|
29
|
+
/* Added EnvGetActivationBasisPPForm function. */
|
30
|
+
/* */
|
31
|
+
/* 6.30: Added salience groups to improve performance */
|
32
|
+
/* with large numbers of activations of different */
|
33
|
+
/* saliences. */
|
34
|
+
/* */
|
35
|
+
/* Borland C (IBM_TBC) and Metrowerks CodeWarrior */
|
36
|
+
/* (MAC_MCW, IBM_MCW) are no longer supported. */
|
37
|
+
/* */
|
38
|
+
/* Support for long long integers. */
|
39
|
+
/* */
|
40
|
+
/* Added const qualifiers to remove C++ */
|
41
|
+
/* deprecation warnings. */
|
42
|
+
/* */
|
43
|
+
/* Converted API macros to function calls. */
|
44
|
+
/* */
|
45
|
+
/* 6.40: Added Env prefix to GetEvaluationError and */
|
46
|
+
/* SetEvaluationError functions. */
|
47
|
+
/* */
|
48
|
+
/* Pragma once and other inclusion changes. */
|
49
|
+
/* */
|
50
|
+
/* Added support for booleans with <stdbool.h>. */
|
51
|
+
/* */
|
52
|
+
/* Removed use of void pointers for specific */
|
53
|
+
/* data structures. */
|
54
|
+
/* */
|
55
|
+
/* ALLOW_ENVIRONMENT_GLOBALS no longer supported. */
|
56
|
+
/* */
|
57
|
+
/* UDF redesign. */
|
58
|
+
/* */
|
59
|
+
/* 6.41: Used gensnprintf in place of gensprintf and. */
|
60
|
+
/* sprintf. */
|
61
|
+
/* */
|
62
|
+
/* Added ExitRouter after SystemError call in */
|
63
|
+
/* DetachActivation. */
|
64
|
+
/* */
|
65
|
+
/*************************************************************/
|
66
|
+
|
67
|
+
#include <stdio.h>
|
68
|
+
#include <string.h>
|
69
|
+
|
70
|
+
#include "setup.h"
|
71
|
+
|
72
|
+
#if DEFRULE_CONSTRUCT
|
73
|
+
|
74
|
+
#include "argacces.h"
|
75
|
+
#include "constant.h"
|
76
|
+
#include "crstrtgy.h"
|
77
|
+
#include "engine.h"
|
78
|
+
#include "envrnmnt.h"
|
79
|
+
#include "extnfunc.h"
|
80
|
+
#include "memalloc.h"
|
81
|
+
#include "moduldef.h"
|
82
|
+
#include "modulutl.h"
|
83
|
+
#include "multifld.h"
|
84
|
+
#include "prntutil.h"
|
85
|
+
#include "reteutil.h"
|
86
|
+
#include "retract.h"
|
87
|
+
#include "router.h"
|
88
|
+
#include "rulebsc.h"
|
89
|
+
#include "ruledef.h"
|
90
|
+
#include "strngrtr.h"
|
91
|
+
#include "sysdep.h"
|
92
|
+
#include "watch.h"
|
93
|
+
|
94
|
+
#include "agenda.h"
|
95
|
+
|
96
|
+
/***************************************/
|
97
|
+
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
|
98
|
+
/***************************************/
|
99
|
+
|
100
|
+
static void PrintActivation(Environment *,const char *,Activation *);
|
101
|
+
static void AgendaClearFunction(Environment *,void *);
|
102
|
+
static const char *SalienceEvaluationName(SalienceEvaluationType);
|
103
|
+
static int EvaluateSalience(Environment *,Defrule *);
|
104
|
+
static struct salienceGroup *ReuseOrCreateSalienceGroup(Environment *,struct defruleModule *,int);
|
105
|
+
static struct salienceGroup *FindSalienceGroup(struct defruleModule *,int);
|
106
|
+
static void RemoveActivationFromGroup(Environment *,Activation *,struct defruleModule *);
|
107
|
+
|
108
|
+
/*************************************************/
|
109
|
+
/* InitializeAgenda: Initializes the activations */
|
110
|
+
/* watch item and the H/L commands for */
|
111
|
+
/* manipulating the agenda. */
|
112
|
+
/*************************************************/
|
113
|
+
void InitializeAgenda(
|
114
|
+
Environment *theEnv)
|
115
|
+
{
|
116
|
+
AllocateEnvironmentData(theEnv,AGENDA_DATA,sizeof(struct agendaData),NULL);
|
117
|
+
|
118
|
+
AgendaData(theEnv)->SalienceEvaluation = WHEN_DEFINED;
|
119
|
+
|
120
|
+
AgendaData(theEnv)->Strategy = DEFAULT_STRATEGY;
|
121
|
+
|
122
|
+
AddClearFunction(theEnv,"agenda",AgendaClearFunction,0,NULL);
|
123
|
+
#if DEBUGGING_FUNCTIONS
|
124
|
+
AddWatchItem(theEnv,"activations",1,&AgendaData(theEnv)->WatchActivations,40,DefruleWatchAccess,DefruleWatchPrint);
|
125
|
+
#endif
|
126
|
+
#if ! RUN_TIME
|
127
|
+
AddUDF(theEnv,"refresh","v",1,1,"y",RefreshCommand,"RefreshCommand",NULL);
|
128
|
+
AddUDF(theEnv,"refresh-agenda","v",0,1,"y",RefreshAgendaCommand,"RefreshAgendaCommand",NULL);
|
129
|
+
AddUDF(theEnv,"get-salience-evaluation","y",0,0,NULL,GetSalienceEvaluationCommand,"GetSalienceEvaluationCommand",NULL);
|
130
|
+
AddUDF(theEnv,"set-salience-evaluation","y",1,1,"y",SetSalienceEvaluationCommand,"SetSalienceEvaluationCommand",NULL);
|
131
|
+
|
132
|
+
#if DEBUGGING_FUNCTIONS
|
133
|
+
AddUDF(theEnv,"agenda","v",0,1,"y",AgendaCommand,"AgendaCommand",NULL);
|
134
|
+
#endif
|
135
|
+
#endif
|
136
|
+
}
|
137
|
+
|
138
|
+
/*****************************************************************/
|
139
|
+
/* AddActivation: Creates a rule activation to be added to the */
|
140
|
+
/* Agenda and links the activation with its associated partial */
|
141
|
+
/* match. The function PlaceActivation is then called to place */
|
142
|
+
/* the activation on the Agenda. Typically called when all */
|
143
|
+
/* patterns on the LHS of a rule have been satisfied. */
|
144
|
+
/*****************************************************************/
|
145
|
+
void AddActivation(
|
146
|
+
Environment *theEnv,
|
147
|
+
Defrule *theRule,
|
148
|
+
PartialMatch *binds)
|
149
|
+
{
|
150
|
+
Activation *newActivation;
|
151
|
+
struct defruleModule *theModuleItem;
|
152
|
+
struct salienceGroup *theGroup;
|
153
|
+
|
154
|
+
/*=======================================*/
|
155
|
+
/* Focus on the module if the activation */
|
156
|
+
/* is from an auto-focus rule. */
|
157
|
+
/*=======================================*/
|
158
|
+
|
159
|
+
if (theRule->autoFocus)
|
160
|
+
{ Focus(theRule->header.whichModule->theModule); }
|
161
|
+
|
162
|
+
/*=======================================================*/
|
163
|
+
/* Create the activation. The activation stores pointers */
|
164
|
+
/* to its associated partial match and defrule. The */
|
165
|
+
/* activation is given a time tag, its salience is */
|
166
|
+
/* evaluated, and it is assigned a random number for use */
|
167
|
+
/* with the random conflict resolution strategy. */
|
168
|
+
/*=======================================================*/
|
169
|
+
|
170
|
+
newActivation = get_struct(theEnv,activation);
|
171
|
+
newActivation->theRule = theRule;
|
172
|
+
newActivation->basis = binds;
|
173
|
+
newActivation->timetag = AgendaData(theEnv)->CurrentTimetag++;
|
174
|
+
newActivation->salience = EvaluateSalience(theEnv,theRule);
|
175
|
+
|
176
|
+
newActivation->randomID = genrand();
|
177
|
+
newActivation->prev = NULL;
|
178
|
+
newActivation->next = NULL;
|
179
|
+
|
180
|
+
AgendaData(theEnv)->NumberOfActivations++;
|
181
|
+
|
182
|
+
/*=======================================================*/
|
183
|
+
/* Point the partial match to the activation to complete */
|
184
|
+
/* the link between the join network and the agenda. */
|
185
|
+
/*=======================================================*/
|
186
|
+
|
187
|
+
binds->marker = newActivation;
|
188
|
+
|
189
|
+
/*====================================================*/
|
190
|
+
/* If activations are being watch, display a message. */
|
191
|
+
/*====================================================*/
|
192
|
+
|
193
|
+
#if DEBUGGING_FUNCTIONS
|
194
|
+
if (newActivation->theRule->watchActivation &&
|
195
|
+
(! ConstructData(theEnv)->ClearReadyInProgress) &&
|
196
|
+
(! ConstructData(theEnv)->ClearInProgress))
|
197
|
+
{
|
198
|
+
WriteString(theEnv,STDOUT,"==> Activation ");
|
199
|
+
PrintActivation(theEnv,STDOUT,newActivation);
|
200
|
+
WriteString(theEnv,STDOUT,"\n");
|
201
|
+
}
|
202
|
+
#endif
|
203
|
+
|
204
|
+
/*=====================================*/
|
205
|
+
/* Place the activation on the agenda. */
|
206
|
+
/*=====================================*/
|
207
|
+
|
208
|
+
theModuleItem = (struct defruleModule *) theRule->header.whichModule;
|
209
|
+
|
210
|
+
theGroup = ReuseOrCreateSalienceGroup(theEnv,theModuleItem,newActivation->salience);
|
211
|
+
|
212
|
+
PlaceActivation(theEnv,&(theModuleItem->agenda),newActivation,theGroup);
|
213
|
+
}
|
214
|
+
|
215
|
+
/*******************************/
|
216
|
+
/* ReuseOrCreateSalienceGroup: */
|
217
|
+
/*******************************/
|
218
|
+
static struct salienceGroup *ReuseOrCreateSalienceGroup(
|
219
|
+
Environment *theEnv,
|
220
|
+
struct defruleModule *theRuleModule,
|
221
|
+
int salience)
|
222
|
+
{
|
223
|
+
struct salienceGroup *theGroup, *lastGroup, *newGroup;
|
224
|
+
|
225
|
+
for (lastGroup = NULL, theGroup = theRuleModule->groupings;
|
226
|
+
theGroup != NULL;
|
227
|
+
lastGroup = theGroup, theGroup = theGroup->next)
|
228
|
+
{
|
229
|
+
if (theGroup->salience == salience)
|
230
|
+
{ return(theGroup); }
|
231
|
+
|
232
|
+
if (theGroup->salience < salience)
|
233
|
+
{ break; }
|
234
|
+
}
|
235
|
+
|
236
|
+
newGroup = get_struct(theEnv,salienceGroup);
|
237
|
+
newGroup->salience = salience;
|
238
|
+
newGroup->first = NULL;
|
239
|
+
newGroup->last = NULL;
|
240
|
+
newGroup->next = theGroup;
|
241
|
+
newGroup->prev = lastGroup;
|
242
|
+
|
243
|
+
if (newGroup->next != NULL)
|
244
|
+
{ newGroup->next->prev = newGroup; }
|
245
|
+
|
246
|
+
if (newGroup->prev != NULL)
|
247
|
+
{ newGroup->prev->next = newGroup; }
|
248
|
+
|
249
|
+
if (lastGroup == NULL)
|
250
|
+
{ theRuleModule->groupings = newGroup; }
|
251
|
+
|
252
|
+
return newGroup;
|
253
|
+
}
|
254
|
+
|
255
|
+
/**********************/
|
256
|
+
/* FindSalienceGroup: */
|
257
|
+
/**********************/
|
258
|
+
static struct salienceGroup *FindSalienceGroup(
|
259
|
+
struct defruleModule *theRuleModule,
|
260
|
+
int salience)
|
261
|
+
{
|
262
|
+
struct salienceGroup *theGroup;
|
263
|
+
|
264
|
+
for (theGroup = theRuleModule->groupings;
|
265
|
+
theGroup != NULL;
|
266
|
+
theGroup = theGroup->next)
|
267
|
+
{
|
268
|
+
if (theGroup->salience == salience)
|
269
|
+
{ return(theGroup); }
|
270
|
+
|
271
|
+
if (theGroup->salience < salience)
|
272
|
+
{ break; }
|
273
|
+
}
|
274
|
+
|
275
|
+
return NULL;
|
276
|
+
}
|
277
|
+
|
278
|
+
/***************************************************************/
|
279
|
+
/* ClearRuleFromAgenda: Clears the agenda of a specified rule. */
|
280
|
+
/***************************************************************/
|
281
|
+
void ClearRuleFromAgenda(
|
282
|
+
Environment *theEnv,
|
283
|
+
Defrule *theRule)
|
284
|
+
{
|
285
|
+
Defrule *tempRule;
|
286
|
+
struct activation *agendaPtr, *agendaNext;
|
287
|
+
|
288
|
+
/*============================================*/
|
289
|
+
/* Get a pointer to the agenda for the module */
|
290
|
+
/* in which the rule is contained. */
|
291
|
+
/*============================================*/
|
292
|
+
|
293
|
+
agendaPtr = ((struct defruleModule *) theRule->header.whichModule)->agenda;
|
294
|
+
|
295
|
+
/*==============================================*/
|
296
|
+
/* Loop through every activation on the agenda. */
|
297
|
+
/*==============================================*/
|
298
|
+
|
299
|
+
while (agendaPtr != NULL)
|
300
|
+
{
|
301
|
+
agendaNext = agendaPtr->next;
|
302
|
+
|
303
|
+
/*========================================================*/
|
304
|
+
/* Check each disjunct of the rule against the activation */
|
305
|
+
/* to determine if the activation points to the rule. If */
|
306
|
+
/* it does, then remove the activation from the agenda. */
|
307
|
+
/*========================================================*/
|
308
|
+
|
309
|
+
for (tempRule = theRule;
|
310
|
+
tempRule != NULL;
|
311
|
+
tempRule = tempRule->disjunct)
|
312
|
+
{
|
313
|
+
if (agendaPtr->theRule == tempRule)
|
314
|
+
{
|
315
|
+
RemoveActivation(theEnv,agendaPtr,true,true);
|
316
|
+
break;
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
320
|
+
agendaPtr = agendaNext;
|
321
|
+
}
|
322
|
+
}
|
323
|
+
|
324
|
+
/***************************************************************/
|
325
|
+
/* GetNextActivation: Returns an activation from the Agenda. */
|
326
|
+
/* If its argument is NULL, then the first activation on the */
|
327
|
+
/* Agenda is returned. If its argument is not NULL, the next */
|
328
|
+
/* activation after the argument is returned. */
|
329
|
+
/***************************************************************/
|
330
|
+
Activation *GetNextActivation(
|
331
|
+
Environment *theEnv,
|
332
|
+
Activation *actPtr)
|
333
|
+
{
|
334
|
+
struct defruleModule *theModuleItem;
|
335
|
+
|
336
|
+
if (actPtr == NULL)
|
337
|
+
{
|
338
|
+
theModuleItem = (struct defruleModule *) GetModuleItem(theEnv,NULL,DefruleData(theEnv)->DefruleModuleIndex);
|
339
|
+
if (theModuleItem == NULL) return NULL;
|
340
|
+
return theModuleItem->agenda;
|
341
|
+
}
|
342
|
+
else
|
343
|
+
{ return actPtr->next; }
|
344
|
+
}
|
345
|
+
|
346
|
+
/*********************************************/
|
347
|
+
/* GetActivationBasis: Returns the basis of */
|
348
|
+
/* the rule associated with an activation. */
|
349
|
+
/*********************************************/
|
350
|
+
struct partialMatch *GetActivationBasis(
|
351
|
+
Environment *theEnv,
|
352
|
+
Activation *actPtr)
|
353
|
+
{
|
354
|
+
#if MAC_XCD
|
355
|
+
#pragma unused(theEnv)
|
356
|
+
#endif
|
357
|
+
return actPtr->basis;
|
358
|
+
}
|
359
|
+
|
360
|
+
/*********************************************/
|
361
|
+
/* ActivationRuleName: Returns the name of */
|
362
|
+
/* the rule associated with an activation. */
|
363
|
+
/*********************************************/
|
364
|
+
const char *ActivationRuleName(
|
365
|
+
Activation *actPtr)
|
366
|
+
{
|
367
|
+
return actPtr->theRule->header.name->contents;
|
368
|
+
}
|
369
|
+
|
370
|
+
/***************************************/
|
371
|
+
/* GetActivationRule: Returns the rule */
|
372
|
+
/* associated with an activation. */
|
373
|
+
/***************************************/
|
374
|
+
Defrule *GetActivationRule(
|
375
|
+
Environment *theEnv,
|
376
|
+
Activation *actPtr)
|
377
|
+
{
|
378
|
+
#if MAC_XCD
|
379
|
+
#pragma unused(theEnv)
|
380
|
+
#endif
|
381
|
+
return actPtr->theRule;
|
382
|
+
}
|
383
|
+
|
384
|
+
/************************************************/
|
385
|
+
/* ActivationGetSalience: Returns the salience */
|
386
|
+
/* of the rule associated with an activation. */
|
387
|
+
/************************************************/
|
388
|
+
int ActivationGetSalience(
|
389
|
+
Activation *actPtr)
|
390
|
+
{
|
391
|
+
return actPtr->salience;
|
392
|
+
}
|
393
|
+
|
394
|
+
/**************************************/
|
395
|
+
/* ActivationSetSalience: Sets the */
|
396
|
+
/* salience value of an activation. */
|
397
|
+
/**************************************/
|
398
|
+
int ActivationSetSalience(
|
399
|
+
Activation *actPtr,
|
400
|
+
int value)
|
401
|
+
{
|
402
|
+
int temp;
|
403
|
+
|
404
|
+
if (value > MAX_DEFRULE_SALIENCE)
|
405
|
+
{ value = MAX_DEFRULE_SALIENCE; }
|
406
|
+
else if (value < MIN_DEFRULE_SALIENCE)
|
407
|
+
{ value = MIN_DEFRULE_SALIENCE; }
|
408
|
+
|
409
|
+
temp = actPtr->salience;
|
410
|
+
actPtr->salience = value;
|
411
|
+
return temp;
|
412
|
+
}
|
413
|
+
|
414
|
+
/********************************************/
|
415
|
+
/* ActivationPPForm: Returns the pretty */
|
416
|
+
/* print representation of an activation. */
|
417
|
+
/********************************************/
|
418
|
+
void ActivationPPForm(
|
419
|
+
Activation *theActivation,
|
420
|
+
StringBuilder *theSB)
|
421
|
+
{
|
422
|
+
Environment *theEnv = theActivation->theRule->header.env;
|
423
|
+
|
424
|
+
OpenStringBuilderDestination(theEnv,"ActPPForm",theSB);
|
425
|
+
PrintActivation(theEnv,"ActPPForm",theActivation);
|
426
|
+
CloseStringBuilderDestination(theEnv,"ActPPForm");
|
427
|
+
}
|
428
|
+
|
429
|
+
/****************************************************/
|
430
|
+
/* GetActivationBasisPPForm: Returns the pretty */
|
431
|
+
/* print representation of an activation's basis. */
|
432
|
+
/****************************************************/
|
433
|
+
void GetActivationBasisPPForm(
|
434
|
+
Environment *theEnv,
|
435
|
+
char *buffer,
|
436
|
+
size_t bufferLength,
|
437
|
+
Activation *theActivation)
|
438
|
+
{
|
439
|
+
OpenStringDestination(theEnv,"ActPPForm",buffer,bufferLength);
|
440
|
+
PrintPartialMatch(theEnv,"ActPPForm",theActivation->basis);
|
441
|
+
CloseStringDestination(theEnv,"ActPPForm");
|
442
|
+
}
|
443
|
+
|
444
|
+
/********************************************/
|
445
|
+
/* MoveActivationToTop: Moves the specified */
|
446
|
+
/* activation to the top of the agenda. */
|
447
|
+
/********************************************/
|
448
|
+
bool MoveActivationToTop(
|
449
|
+
Environment *theEnv,
|
450
|
+
Activation *theActivation)
|
451
|
+
{
|
452
|
+
struct activation *prevPtr;
|
453
|
+
struct defruleModule *theModuleItem;
|
454
|
+
|
455
|
+
/*====================================*/
|
456
|
+
/* Determine the module of the agenda */
|
457
|
+
/* in which the activation is stored. */
|
458
|
+
/*====================================*/
|
459
|
+
|
460
|
+
theModuleItem = (struct defruleModule *) theActivation->theRule->header.whichModule;
|
461
|
+
|
462
|
+
/*============================================*/
|
463
|
+
/* If the activation is already at the top of */
|
464
|
+
/* the agenda, then nothing needs to be done. */
|
465
|
+
/*============================================*/
|
466
|
+
|
467
|
+
if (theActivation == theModuleItem->agenda) return false;
|
468
|
+
|
469
|
+
/*=================================================*/
|
470
|
+
/* Update the pointers of the activation preceding */
|
471
|
+
/* and following the activation being moved. */
|
472
|
+
/*=================================================*/
|
473
|
+
|
474
|
+
prevPtr = theActivation->prev;
|
475
|
+
prevPtr->next = theActivation->next;
|
476
|
+
if (theActivation->next != NULL) theActivation->next->prev = prevPtr;
|
477
|
+
|
478
|
+
/*=======================================================*/
|
479
|
+
/* Move the activation and then update its pointers, the */
|
480
|
+
/* pointers of the activation following it, and the */
|
481
|
+
/* module pointer to the top activation on the agenda. */
|
482
|
+
/*=======================================================*/
|
483
|
+
|
484
|
+
theActivation->next = theModuleItem->agenda;
|
485
|
+
theModuleItem->agenda->prev = theActivation;
|
486
|
+
theActivation->prev = NULL;
|
487
|
+
theModuleItem->agenda = theActivation;
|
488
|
+
|
489
|
+
/*=============================*/
|
490
|
+
/* Mark the agenda as changed. */
|
491
|
+
/*=============================*/
|
492
|
+
|
493
|
+
AgendaData(theEnv)->AgendaChanged = true;
|
494
|
+
|
495
|
+
return true;
|
496
|
+
}
|
497
|
+
|
498
|
+
/*******************************************/
|
499
|
+
/* DeleteActivation: Removes the specified */
|
500
|
+
/* activation from the agenda. */
|
501
|
+
/*******************************************/
|
502
|
+
void DeleteActivation(
|
503
|
+
Activation *theActivation)
|
504
|
+
{
|
505
|
+
RemoveActivation(theActivation->theRule->header.env,theActivation,true,true);
|
506
|
+
}
|
507
|
+
|
508
|
+
/*************************************************/
|
509
|
+
/* DeleteAllActivations: Removes all activations */
|
510
|
+
/* from the agenda of the specified module. */
|
511
|
+
/*************************************************/
|
512
|
+
void DeleteAllActivations(
|
513
|
+
Defmodule *theModule)
|
514
|
+
{
|
515
|
+
struct activation *tempPtr, *theActivation;
|
516
|
+
struct salienceGroup *theGroup, *tempGroup;
|
517
|
+
Environment *theEnv = theModule->header.env;
|
518
|
+
|
519
|
+
theActivation = GetDefruleModuleItem(theEnv,NULL)->agenda;
|
520
|
+
while (theActivation != NULL)
|
521
|
+
{
|
522
|
+
tempPtr = theActivation->next;
|
523
|
+
RemoveActivation(theEnv,theActivation,true,true);
|
524
|
+
theActivation = tempPtr;
|
525
|
+
}
|
526
|
+
|
527
|
+
theGroup = GetDefruleModuleItem(theEnv,NULL)->groupings;
|
528
|
+
while (theGroup != NULL)
|
529
|
+
{
|
530
|
+
tempGroup = theGroup->next;
|
531
|
+
rtn_struct(theEnv,salienceGroup,theGroup);
|
532
|
+
theGroup = tempGroup;
|
533
|
+
}
|
534
|
+
}
|
535
|
+
|
536
|
+
/*******************************************************/
|
537
|
+
/* DetachActivation: Detaches the specified activation */
|
538
|
+
/* from the list of activations on the Agenda. */
|
539
|
+
/*******************************************************/
|
540
|
+
bool DetachActivation(
|
541
|
+
Environment *theEnv,
|
542
|
+
Activation *theActivation)
|
543
|
+
{
|
544
|
+
struct defruleModule *theModuleItem;
|
545
|
+
|
546
|
+
/*============================*/
|
547
|
+
/* A NULL pointer is invalid. */
|
548
|
+
/*============================*/
|
549
|
+
|
550
|
+
if (theActivation == NULL)
|
551
|
+
{
|
552
|
+
SystemError(theEnv,"AGENDA",1);
|
553
|
+
ExitRouter(theEnv,EXIT_FAILURE);
|
554
|
+
}
|
555
|
+
|
556
|
+
/*====================================*/
|
557
|
+
/* Determine the module of the agenda */
|
558
|
+
/* in which the activation is stored. */
|
559
|
+
/*====================================*/
|
560
|
+
|
561
|
+
theModuleItem = (struct defruleModule *) theActivation->theRule->header.whichModule;
|
562
|
+
|
563
|
+
RemoveActivationFromGroup(theEnv,theActivation,theModuleItem);
|
564
|
+
|
565
|
+
/*========================================================*/
|
566
|
+
/* If the activation is the top activation on the agenda, */
|
567
|
+
/* then update the module pointer to agenda. */
|
568
|
+
/*========================================================*/
|
569
|
+
|
570
|
+
if (theActivation == theModuleItem->agenda)
|
571
|
+
{ theModuleItem->agenda = theActivation->next; }
|
572
|
+
|
573
|
+
/*==================================================*/
|
574
|
+
/* Update the pointers in the preceding activation. */
|
575
|
+
/*==================================================*/
|
576
|
+
|
577
|
+
if (theActivation->prev != NULL)
|
578
|
+
{ theActivation->prev->next = theActivation->next; }
|
579
|
+
|
580
|
+
/*==================================================*/
|
581
|
+
/* Update the pointers in the following activation. */
|
582
|
+
/*==================================================*/
|
583
|
+
|
584
|
+
if (theActivation->next != NULL)
|
585
|
+
{ theActivation->next->prev = theActivation->prev; }
|
586
|
+
|
587
|
+
/*=================================================*/
|
588
|
+
/* Update the pointers in the detached activation. */
|
589
|
+
/*=================================================*/
|
590
|
+
|
591
|
+
theActivation->prev = NULL;
|
592
|
+
theActivation->next = NULL;
|
593
|
+
|
594
|
+
/*=============================*/
|
595
|
+
/* Mark the agenda as changed. */
|
596
|
+
/*=============================*/
|
597
|
+
|
598
|
+
AgendaData(theEnv)->AgendaChanged = true;
|
599
|
+
|
600
|
+
return true;
|
601
|
+
}
|
602
|
+
|
603
|
+
/****************************************************************************/
|
604
|
+
/* PrintActivation: Prints an activation in a "pretty" format. Salience, */
|
605
|
+
/* rule name, and the partial match which activated the rule are printed. */
|
606
|
+
/****************************************************************************/
|
607
|
+
static void PrintActivation(
|
608
|
+
Environment *theEnv,
|
609
|
+
const char *logicalName,
|
610
|
+
Activation *theActivation)
|
611
|
+
{
|
612
|
+
char printSpace[20];
|
613
|
+
|
614
|
+
gensnprintf(printSpace,sizeof(printSpace),"%-6d ",theActivation->salience);
|
615
|
+
WriteString(theEnv,logicalName,printSpace);
|
616
|
+
WriteString(theEnv,logicalName,theActivation->theRule->header.name->contents);
|
617
|
+
WriteString(theEnv,logicalName,": ");
|
618
|
+
PrintPartialMatch(theEnv,logicalName,theActivation->basis);
|
619
|
+
}
|
620
|
+
|
621
|
+
/*****************************/
|
622
|
+
/* Agenda: C access routine */
|
623
|
+
/* for the agenda command. */
|
624
|
+
/*****************************/
|
625
|
+
void Agenda(
|
626
|
+
Environment *theEnv,
|
627
|
+
const char *logicalName,
|
628
|
+
Defmodule *theModule)
|
629
|
+
{
|
630
|
+
ListItemsDriver(theEnv,logicalName,theModule,"activation","activations",
|
631
|
+
(GetNextItemFunction *) GetNextActivation,
|
632
|
+
NULL,
|
633
|
+
(PrintItemFunction *) PrintActivation,
|
634
|
+
NULL);
|
635
|
+
}
|
636
|
+
|
637
|
+
/*******************************************************************/
|
638
|
+
/* RemoveActivation: Returns an activation and its associated data */
|
639
|
+
/* structures to the Memory Manager. Links to other activations */
|
640
|
+
/* and partial matches may also be updated. */
|
641
|
+
/*******************************************************************/
|
642
|
+
void RemoveActivation(
|
643
|
+
Environment *theEnv,
|
644
|
+
Activation *theActivation,
|
645
|
+
bool updateAgenda,
|
646
|
+
bool updateLinks)
|
647
|
+
{
|
648
|
+
struct defruleModule *theModuleItem;
|
649
|
+
|
650
|
+
/*====================================*/
|
651
|
+
/* Determine the module of the agenda */
|
652
|
+
/* in which the activation is stored. */
|
653
|
+
/*====================================*/
|
654
|
+
|
655
|
+
theModuleItem = (struct defruleModule *) theActivation->theRule->header.whichModule;
|
656
|
+
|
657
|
+
/*=================================*/
|
658
|
+
/* Update the agenda if necessary. */
|
659
|
+
/*=================================*/
|
660
|
+
|
661
|
+
if (updateAgenda == true)
|
662
|
+
{
|
663
|
+
RemoveActivationFromGroup(theEnv,theActivation,theModuleItem);
|
664
|
+
|
665
|
+
/*===============================================*/
|
666
|
+
/* Update the pointer links between activations. */
|
667
|
+
/*===============================================*/
|
668
|
+
|
669
|
+
if (theActivation->prev == NULL)
|
670
|
+
{
|
671
|
+
theModuleItem->agenda = theModuleItem->agenda->next;
|
672
|
+
if (theModuleItem->agenda != NULL) theModuleItem->agenda->prev = NULL;
|
673
|
+
}
|
674
|
+
else
|
675
|
+
{
|
676
|
+
theActivation->prev->next = theActivation->next;
|
677
|
+
if (theActivation->next != NULL)
|
678
|
+
{ theActivation->next->prev = theActivation->prev; }
|
679
|
+
}
|
680
|
+
|
681
|
+
/*===================================*/
|
682
|
+
/* Indicate removal of activation if */
|
683
|
+
/* activations are being watched. */
|
684
|
+
/*===================================*/
|
685
|
+
|
686
|
+
#if DEBUGGING_FUNCTIONS
|
687
|
+
if (theActivation->theRule->watchActivation &&
|
688
|
+
(! ConstructData(theEnv)->ClearReadyInProgress) &&
|
689
|
+
(! ConstructData(theEnv)->ClearInProgress))
|
690
|
+
{
|
691
|
+
WriteString(theEnv,STDOUT,"<== Activation ");
|
692
|
+
PrintActivation(theEnv,STDOUT,theActivation);
|
693
|
+
WriteString(theEnv,STDOUT,"\n");
|
694
|
+
}
|
695
|
+
#endif
|
696
|
+
|
697
|
+
/*=============================*/
|
698
|
+
/* Mark the agenda as changed. */
|
699
|
+
/*=============================*/
|
700
|
+
|
701
|
+
AgendaData(theEnv)->AgendaChanged = true;
|
702
|
+
}
|
703
|
+
|
704
|
+
/*============================================*/
|
705
|
+
/* Update join and agenda links if necessary. */
|
706
|
+
/*============================================*/
|
707
|
+
|
708
|
+
if ((updateLinks == true) && (theActivation->basis != NULL))
|
709
|
+
{ theActivation->basis->marker = NULL; }
|
710
|
+
|
711
|
+
/*================================================*/
|
712
|
+
/* Return the activation to the free memory pool. */
|
713
|
+
/*================================================*/
|
714
|
+
|
715
|
+
AgendaData(theEnv)->NumberOfActivations--;
|
716
|
+
|
717
|
+
rtn_struct(theEnv,activation,theActivation);
|
718
|
+
}
|
719
|
+
|
720
|
+
/******************************/
|
721
|
+
/* RemoveActivationFromGroup: */
|
722
|
+
/******************************/
|
723
|
+
static void RemoveActivationFromGroup(
|
724
|
+
Environment *theEnv,
|
725
|
+
Activation *theActivation,
|
726
|
+
struct defruleModule *theRuleModule)
|
727
|
+
{
|
728
|
+
struct salienceGroup *theGroup;
|
729
|
+
|
730
|
+
theGroup = FindSalienceGroup(theRuleModule,theActivation->salience);
|
731
|
+
if (theGroup == NULL) return;
|
732
|
+
|
733
|
+
if (theActivation == theGroup->first)
|
734
|
+
{
|
735
|
+
/*====================================================*/
|
736
|
+
/* If the activation is the only remaining activation */
|
737
|
+
/* in the group, then the group needs to be removed. */
|
738
|
+
/*====================================================*/
|
739
|
+
|
740
|
+
if (theActivation == theGroup->last)
|
741
|
+
{
|
742
|
+
if (theGroup->prev == NULL)
|
743
|
+
{ theRuleModule->groupings = theGroup->next; }
|
744
|
+
else
|
745
|
+
{ theGroup->prev->next = theGroup->next; }
|
746
|
+
|
747
|
+
if (theGroup->next != NULL)
|
748
|
+
{ theGroup->next->prev = theGroup->prev; }
|
749
|
+
|
750
|
+
rtn_struct(theEnv,salienceGroup,theGroup);
|
751
|
+
}
|
752
|
+
|
753
|
+
/*======================================================*/
|
754
|
+
/* Otherwise this is the first activation in the group, */
|
755
|
+
/* but there are other activations which follow. */
|
756
|
+
/*======================================================*/
|
757
|
+
|
758
|
+
else
|
759
|
+
{ theGroup->first = theActivation->next; }
|
760
|
+
}
|
761
|
+
else
|
762
|
+
{
|
763
|
+
/*====================================================*/
|
764
|
+
/* Otherwise if the activation isn't the first in the */
|
765
|
+
/* group, then check to see if it's the last. */
|
766
|
+
/*====================================================*/
|
767
|
+
|
768
|
+
if (theActivation == theGroup->last)
|
769
|
+
{ theGroup->last = theActivation->prev; }
|
770
|
+
|
771
|
+
/*==================================================*/
|
772
|
+
/* Otherwise the activation is in the middle of the */
|
773
|
+
/* group and no first/last updates are needed. */
|
774
|
+
/*==================================================*/
|
775
|
+
|
776
|
+
else
|
777
|
+
{ return; }
|
778
|
+
}
|
779
|
+
}
|
780
|
+
|
781
|
+
/**************************************************************/
|
782
|
+
/* AgendaClearFunction: Agenda clear routine for use with the */
|
783
|
+
/* clear command. Resets the current time tag to zero. */
|
784
|
+
/**************************************************************/
|
785
|
+
static void AgendaClearFunction(
|
786
|
+
Environment *theEnv,
|
787
|
+
void *context)
|
788
|
+
{
|
789
|
+
AgendaData(theEnv)->CurrentTimetag = 1;
|
790
|
+
}
|
791
|
+
|
792
|
+
/*************************************************/
|
793
|
+
/* RemoveAllActivations: Removes all activations */
|
794
|
+
/* from the agenda of the current module. */
|
795
|
+
/*************************************************/
|
796
|
+
void RemoveAllActivations(
|
797
|
+
Environment *theEnv)
|
798
|
+
{
|
799
|
+
struct activation *tempPtr, *theActivation;
|
800
|
+
struct salienceGroup *theGroup, *tempGroup;
|
801
|
+
|
802
|
+
theActivation = GetDefruleModuleItem(theEnv,NULL)->agenda;
|
803
|
+
while (theActivation != NULL)
|
804
|
+
{
|
805
|
+
tempPtr = theActivation->next;
|
806
|
+
RemoveActivation(theEnv,theActivation,true,true);
|
807
|
+
theActivation = tempPtr;
|
808
|
+
}
|
809
|
+
|
810
|
+
theGroup = GetDefruleModuleItem(theEnv,NULL)->groupings;
|
811
|
+
while (theGroup != NULL)
|
812
|
+
{
|
813
|
+
tempGroup = theGroup->next;
|
814
|
+
rtn_struct(theEnv,salienceGroup,theGroup);
|
815
|
+
theGroup = tempGroup;
|
816
|
+
}
|
817
|
+
}
|
818
|
+
|
819
|
+
/**********************************************/
|
820
|
+
/* GetAgendaChanged: Returns the value of the */
|
821
|
+
/* boolean flag which indicates whether any */
|
822
|
+
/* changes have been made to the agenda. */
|
823
|
+
/**********************************************/
|
824
|
+
bool GetAgendaChanged(
|
825
|
+
Environment *theEnv)
|
826
|
+
{
|
827
|
+
return(AgendaData(theEnv)->AgendaChanged);
|
828
|
+
}
|
829
|
+
|
830
|
+
/*****************************************************************/
|
831
|
+
/* SetAgendaChanged: Sets the value of the boolean flag which */
|
832
|
+
/* indicates whether any changes have been made to the agenda. */
|
833
|
+
/*****************************************************************/
|
834
|
+
void SetAgendaChanged(
|
835
|
+
Environment *theEnv,
|
836
|
+
bool value)
|
837
|
+
{
|
838
|
+
AgendaData(theEnv)->AgendaChanged = value;
|
839
|
+
}
|
840
|
+
|
841
|
+
/**********************/
|
842
|
+
/* ReorderAllAgendas: */
|
843
|
+
/**********************/
|
844
|
+
void ReorderAllAgendas(
|
845
|
+
Environment *theEnv)
|
846
|
+
{
|
847
|
+
Defmodule *theModule;
|
848
|
+
|
849
|
+
for (theModule = GetNextDefmodule(theEnv,NULL);
|
850
|
+
theModule != NULL;
|
851
|
+
theModule = GetNextDefmodule(theEnv,theModule))
|
852
|
+
{ ReorderAgenda(theModule); }
|
853
|
+
}
|
854
|
+
|
855
|
+
/*******************************************************/
|
856
|
+
/* ReorderAgenda: Completely reorders the agenda based */
|
857
|
+
/* on the current conflict resolution strategy. */
|
858
|
+
/*******************************************************/
|
859
|
+
void ReorderAgenda(
|
860
|
+
Defmodule *theModule)
|
861
|
+
{
|
862
|
+
struct activation *theActivation, *tempPtr;
|
863
|
+
struct defruleModule *theModuleItem;
|
864
|
+
struct salienceGroup *theGroup, *tempGroup;
|
865
|
+
Environment *theEnv;
|
866
|
+
|
867
|
+
if (theModule == NULL) return;
|
868
|
+
theEnv = theModule->header.env;
|
869
|
+
|
870
|
+
/*=================================*/
|
871
|
+
/* Get the list of activations and */
|
872
|
+
/* remove them from the agenda. */
|
873
|
+
/*=================================*/
|
874
|
+
|
875
|
+
theModuleItem = GetDefruleModuleItem(theEnv,theModule);
|
876
|
+
theActivation = theModuleItem->agenda;
|
877
|
+
theModuleItem->agenda = NULL;
|
878
|
+
|
879
|
+
theGroup = theModuleItem->groupings;
|
880
|
+
while (theGroup != NULL)
|
881
|
+
{
|
882
|
+
tempGroup = theGroup->next;
|
883
|
+
rtn_struct(theEnv,salienceGroup,theGroup);
|
884
|
+
theGroup = tempGroup;
|
885
|
+
}
|
886
|
+
|
887
|
+
theModuleItem->groupings = NULL;
|
888
|
+
|
889
|
+
/*=========================================*/
|
890
|
+
/* Reorder the activations by placing them */
|
891
|
+
/* back on the agenda one by one. */
|
892
|
+
/*=========================================*/
|
893
|
+
|
894
|
+
while (theActivation != NULL)
|
895
|
+
{
|
896
|
+
tempPtr = theActivation->next;
|
897
|
+
theActivation->next = NULL;
|
898
|
+
theActivation->prev = NULL;
|
899
|
+
theGroup = ReuseOrCreateSalienceGroup(theEnv,theModuleItem,theActivation->salience);
|
900
|
+
PlaceActivation(theEnv,&(theModuleItem->agenda),theActivation,theGroup);
|
901
|
+
theActivation = tempPtr;
|
902
|
+
}
|
903
|
+
}
|
904
|
+
|
905
|
+
/****************************************************/
|
906
|
+
/* GetNumberOfActivations: Returns the value of the */
|
907
|
+
/* total number of activations on all agendas. */
|
908
|
+
/****************************************************/
|
909
|
+
unsigned long GetNumberOfActivations(
|
910
|
+
Environment *theEnv)
|
911
|
+
{
|
912
|
+
return(AgendaData(theEnv)->NumberOfActivations);
|
913
|
+
}
|
914
|
+
|
915
|
+
/******************************************************/
|
916
|
+
/* RefreshCommand: H/L Command for refreshing a rule. */
|
917
|
+
/* Syntax: (refresh <defrule-name>) */
|
918
|
+
/******************************************************/
|
919
|
+
void RefreshCommand(
|
920
|
+
Environment *theEnv,
|
921
|
+
UDFContext *context,
|
922
|
+
UDFValue *returnValue)
|
923
|
+
{
|
924
|
+
const char *ruleName;
|
925
|
+
Defrule *rulePtr;
|
926
|
+
|
927
|
+
/*===========================*/
|
928
|
+
/* Get the name of the rule. */
|
929
|
+
/*===========================*/
|
930
|
+
|
931
|
+
ruleName = GetConstructName(context,"refresh","rule name");
|
932
|
+
if (ruleName == NULL) return;
|
933
|
+
|
934
|
+
/*===============================*/
|
935
|
+
/* Determine if the rule exists. */
|
936
|
+
/*===============================*/
|
937
|
+
|
938
|
+
rulePtr = FindDefrule(theEnv,ruleName);
|
939
|
+
if (rulePtr == NULL)
|
940
|
+
{
|
941
|
+
CantFindItemErrorMessage(theEnv,"defrule",ruleName,true);
|
942
|
+
return;
|
943
|
+
}
|
944
|
+
|
945
|
+
/*===================*/
|
946
|
+
/* Refresh the rule. */
|
947
|
+
/*===================*/
|
948
|
+
|
949
|
+
Refresh(rulePtr);
|
950
|
+
}
|
951
|
+
|
952
|
+
/***********************************************************/
|
953
|
+
/* Refresh: Refreshes a defrule. Activations of the rule */
|
954
|
+
/* that have already been fired are added to the agenda. */
|
955
|
+
/***********************************************************/
|
956
|
+
void Refresh(
|
957
|
+
Defrule *theRule)
|
958
|
+
{
|
959
|
+
Defrule *rulePtr;
|
960
|
+
struct partialMatch *listOfMatches;
|
961
|
+
unsigned long b;
|
962
|
+
Environment *theEnv = theRule->header.env;
|
963
|
+
|
964
|
+
/*====================================*/
|
965
|
+
/* Refresh each disjunct of the rule. */
|
966
|
+
/*====================================*/
|
967
|
+
|
968
|
+
for (rulePtr = theRule;
|
969
|
+
rulePtr != NULL;
|
970
|
+
rulePtr = rulePtr->disjunct)
|
971
|
+
{
|
972
|
+
/*================================*/
|
973
|
+
/* Check each partial match that */
|
974
|
+
/* satisfies the LHS of the rule. */
|
975
|
+
/*================================*/
|
976
|
+
|
977
|
+
for (b = 0; b < rulePtr->lastJoin->leftMemory->size; b++)
|
978
|
+
{
|
979
|
+
for (listOfMatches = rulePtr->lastJoin->leftMemory->beta[b];
|
980
|
+
listOfMatches != NULL;
|
981
|
+
listOfMatches = listOfMatches->nextInMemory)
|
982
|
+
{
|
983
|
+
/*=======================================================*/
|
984
|
+
/* If the partial match is associated with an activation */
|
985
|
+
/* (which it should always be), then place a new */
|
986
|
+
/* activation on the agenda if this partial matchdoesn't */
|
987
|
+
/* have an activation associated with it. */
|
988
|
+
/*=======================================================*/
|
989
|
+
|
990
|
+
if (((struct joinNode *) listOfMatches->owner)->ruleToActivate != NULL)
|
991
|
+
{
|
992
|
+
if (listOfMatches->marker == NULL)
|
993
|
+
{ AddActivation(theEnv,rulePtr,listOfMatches); }
|
994
|
+
}
|
995
|
+
}
|
996
|
+
}
|
997
|
+
}
|
998
|
+
}
|
999
|
+
|
1000
|
+
/**********************************************/
|
1001
|
+
/* RefreshAgendaCommand: H/L access routine */
|
1002
|
+
/* for the refresh-agenda command. */
|
1003
|
+
/**********************************************/
|
1004
|
+
void RefreshAgendaCommand(
|
1005
|
+
Environment *theEnv,
|
1006
|
+
UDFContext *context,
|
1007
|
+
UDFValue *returnValue)
|
1008
|
+
{
|
1009
|
+
unsigned int numArgs;
|
1010
|
+
bool error;
|
1011
|
+
Defmodule *theModule;
|
1012
|
+
|
1013
|
+
/*==============================================*/
|
1014
|
+
/* This function can have at most one argument. */
|
1015
|
+
/*==============================================*/
|
1016
|
+
|
1017
|
+
numArgs = UDFArgumentCount(context);
|
1018
|
+
|
1019
|
+
/*===============================================================*/
|
1020
|
+
/* If a module name is specified, then the agenda of that module */
|
1021
|
+
/* is refreshed. Otherwise, the agenda of the current module is */
|
1022
|
+
/* refreshed. */
|
1023
|
+
/*===============================================================*/
|
1024
|
+
|
1025
|
+
if (numArgs == 1)
|
1026
|
+
{
|
1027
|
+
theModule = GetModuleName(context,1,&error);
|
1028
|
+
if (error) return;
|
1029
|
+
}
|
1030
|
+
else
|
1031
|
+
{ theModule = GetCurrentModule(theEnv); }
|
1032
|
+
|
1033
|
+
/*===============================================*/
|
1034
|
+
/* Refresh the agenda of the appropriate module. */
|
1035
|
+
/*===============================================*/
|
1036
|
+
|
1037
|
+
if (theModule == NULL)
|
1038
|
+
{ RefreshAllAgendas(theEnv); }
|
1039
|
+
else
|
1040
|
+
{ RefreshAgenda(theModule); }
|
1041
|
+
}
|
1042
|
+
|
1043
|
+
/**********************/
|
1044
|
+
/* RefreshAllAgendas: */
|
1045
|
+
/**********************/
|
1046
|
+
void RefreshAllAgendas(
|
1047
|
+
Environment *theEnv)
|
1048
|
+
{
|
1049
|
+
Defmodule *theModule;
|
1050
|
+
|
1051
|
+
for (theModule = GetNextDefmodule(theEnv,NULL);
|
1052
|
+
theModule != NULL;
|
1053
|
+
theModule = GetNextDefmodule(theEnv,theModule))
|
1054
|
+
{ RefreshAgenda(theModule); }
|
1055
|
+
}
|
1056
|
+
|
1057
|
+
/*************************************/
|
1058
|
+
/* RefreshAgenda: C access routine */
|
1059
|
+
/* for the refresh-agenda command. */
|
1060
|
+
/*************************************/
|
1061
|
+
void RefreshAgenda(
|
1062
|
+
Defmodule *theModule)
|
1063
|
+
{
|
1064
|
+
Activation *theActivation;
|
1065
|
+
SalienceEvaluationType oldValue;
|
1066
|
+
Environment *theEnv;
|
1067
|
+
|
1068
|
+
if (theModule == NULL) return;
|
1069
|
+
theEnv = theModule->header.env;
|
1070
|
+
|
1071
|
+
/*=====================================*/
|
1072
|
+
/* If embedded, clear the error flags. */
|
1073
|
+
/*=====================================*/
|
1074
|
+
|
1075
|
+
if (EvaluationData(theEnv)->CurrentExpression == NULL)
|
1076
|
+
{ ResetErrorFlags(theEnv); }
|
1077
|
+
|
1078
|
+
/*==========================*/
|
1079
|
+
/* Save the current module. */
|
1080
|
+
/*==========================*/
|
1081
|
+
|
1082
|
+
SaveCurrentModule(theEnv);
|
1083
|
+
|
1084
|
+
/*=======================================================*/
|
1085
|
+
/* Remember the current setting for salience evaluation. */
|
1086
|
+
/* To perform the refresh, the when activated setting is */
|
1087
|
+
/* used to recompute the salience values. */
|
1088
|
+
/*=======================================================*/
|
1089
|
+
|
1090
|
+
oldValue = GetSalienceEvaluation(theEnv);
|
1091
|
+
SetSalienceEvaluation(theEnv,WHEN_ACTIVATED);
|
1092
|
+
|
1093
|
+
/*============================*/
|
1094
|
+
/* Change the current module. */
|
1095
|
+
/*============================*/
|
1096
|
+
|
1097
|
+
SetCurrentModule(theEnv,theModule);
|
1098
|
+
|
1099
|
+
/*================================================================*/
|
1100
|
+
/* Recompute the salience values for the current module's agenda. */
|
1101
|
+
/*================================================================*/
|
1102
|
+
|
1103
|
+
for (theActivation = GetNextActivation(theEnv,NULL);
|
1104
|
+
theActivation != NULL;
|
1105
|
+
theActivation = GetNextActivation(theEnv,theActivation))
|
1106
|
+
{ theActivation->salience = EvaluateSalience(theEnv,theActivation->theRule); }
|
1107
|
+
|
1108
|
+
/*======================================================*/
|
1109
|
+
/* Reorder the agenda based on the new salience values. */
|
1110
|
+
/*======================================================*/
|
1111
|
+
|
1112
|
+
ReorderAgenda(theModule);
|
1113
|
+
|
1114
|
+
/*==========================================*/
|
1115
|
+
/* Restore the salience evaluation setting. */
|
1116
|
+
/*==========================================*/
|
1117
|
+
|
1118
|
+
SetSalienceEvaluation(theEnv,oldValue);
|
1119
|
+
|
1120
|
+
/*=============================*/
|
1121
|
+
/* Restore the current module. */
|
1122
|
+
/*=============================*/
|
1123
|
+
|
1124
|
+
RestoreCurrentModule(theEnv);
|
1125
|
+
}
|
1126
|
+
|
1127
|
+
/*********************************************************/
|
1128
|
+
/* SetSalienceEvaluationCommand: H/L Command for setting */
|
1129
|
+
/* the salience evaluation behavior. */
|
1130
|
+
/* Syntax: (set-salience-evaluation-behavior <symbol>) */
|
1131
|
+
/*********************************************************/
|
1132
|
+
void SetSalienceEvaluationCommand(
|
1133
|
+
Environment *theEnv,
|
1134
|
+
UDFContext *context,
|
1135
|
+
UDFValue *returnValue)
|
1136
|
+
{
|
1137
|
+
UDFValue value;
|
1138
|
+
const char *argument;
|
1139
|
+
const char *oldValue;
|
1140
|
+
|
1141
|
+
/*==================================================*/
|
1142
|
+
/* Get the current setting for salience evaluation. */
|
1143
|
+
/*==================================================*/
|
1144
|
+
|
1145
|
+
oldValue = SalienceEvaluationName(GetSalienceEvaluation(theEnv));
|
1146
|
+
|
1147
|
+
/*=========================================*/
|
1148
|
+
/* This function expects a single argument */
|
1149
|
+
/* which must be a symbol. */
|
1150
|
+
/*=========================================*/
|
1151
|
+
|
1152
|
+
if (! UDFFirstArgument(context,SYMBOL_BIT,&value))
|
1153
|
+
{ return; }
|
1154
|
+
|
1155
|
+
/*=============================================================*/
|
1156
|
+
/* The allowed symbols to pass as an argument to this function */
|
1157
|
+
/* are when-defined, when-activated, and every-cycle. */
|
1158
|
+
/*=============================================================*/
|
1159
|
+
|
1160
|
+
argument = value.lexemeValue->contents;
|
1161
|
+
|
1162
|
+
if (strcmp(argument,"when-defined") == 0)
|
1163
|
+
{ SetSalienceEvaluation(theEnv,WHEN_DEFINED); }
|
1164
|
+
else if (strcmp(argument,"when-activated") == 0)
|
1165
|
+
{ SetSalienceEvaluation(theEnv,WHEN_ACTIVATED); }
|
1166
|
+
else if (strcmp(argument,"every-cycle") == 0)
|
1167
|
+
{ SetSalienceEvaluation(theEnv,EVERY_CYCLE); }
|
1168
|
+
else
|
1169
|
+
{
|
1170
|
+
UDFInvalidArgumentMessage(context,
|
1171
|
+
"symbol with value when-defined, when-activated, or every-cycle");
|
1172
|
+
returnValue->lexemeValue = CreateSymbol(theEnv,oldValue);
|
1173
|
+
return;
|
1174
|
+
}
|
1175
|
+
|
1176
|
+
/*=================================================*/
|
1177
|
+
/* Return the old setting for salience evaluation. */
|
1178
|
+
/*=================================================*/
|
1179
|
+
|
1180
|
+
returnValue->lexemeValue = CreateSymbol(theEnv,oldValue);
|
1181
|
+
}
|
1182
|
+
|
1183
|
+
/*********************************************************/
|
1184
|
+
/* GetSalienceEvaluationCommand: H/L Command for getting */
|
1185
|
+
/* the salience evaluation behavior. */
|
1186
|
+
/* Syntax: (get-salience-evaluation-behavior) */
|
1187
|
+
/*********************************************************/
|
1188
|
+
void GetSalienceEvaluationCommand(
|
1189
|
+
Environment *theEnv,
|
1190
|
+
UDFContext *context,
|
1191
|
+
UDFValue *returnValue)
|
1192
|
+
{
|
1193
|
+
returnValue->lexemeValue = CreateSymbol(theEnv,SalienceEvaluationName(GetSalienceEvaluation(theEnv)));
|
1194
|
+
}
|
1195
|
+
|
1196
|
+
/*****************************************************************/
|
1197
|
+
/* SalienceEvaluationName: Given the integer value corresponding */
|
1198
|
+
/* to a specified salience evaluation behavior, returns a */
|
1199
|
+
/* character string of the behavior's name. */
|
1200
|
+
/*****************************************************************/
|
1201
|
+
static const char *SalienceEvaluationName(
|
1202
|
+
SalienceEvaluationType strategy)
|
1203
|
+
{
|
1204
|
+
const char *sname;
|
1205
|
+
|
1206
|
+
switch (strategy)
|
1207
|
+
{
|
1208
|
+
case WHEN_DEFINED:
|
1209
|
+
sname = "when-defined";
|
1210
|
+
break;
|
1211
|
+
case WHEN_ACTIVATED:
|
1212
|
+
sname = "when-activated";
|
1213
|
+
break;
|
1214
|
+
case EVERY_CYCLE:
|
1215
|
+
sname = "every-cycle";
|
1216
|
+
break;
|
1217
|
+
default:
|
1218
|
+
sname = "unknown";
|
1219
|
+
break;
|
1220
|
+
}
|
1221
|
+
|
1222
|
+
return sname;
|
1223
|
+
}
|
1224
|
+
|
1225
|
+
/*******************************************************/
|
1226
|
+
/* GetSalienceEvaluation: Returns the value of current */
|
1227
|
+
/* type of salience evaluation (e.g., when defined, */
|
1228
|
+
/* when activated, or every cycle). */
|
1229
|
+
/*******************************************************/
|
1230
|
+
SalienceEvaluationType GetSalienceEvaluation(
|
1231
|
+
Environment *theEnv)
|
1232
|
+
{
|
1233
|
+
return AgendaData(theEnv)->SalienceEvaluation;
|
1234
|
+
}
|
1235
|
+
|
1236
|
+
/**********************************************/
|
1237
|
+
/* SetSalienceEvaluation: Sets the value of */
|
1238
|
+
/* the current type of salience evaluation. */
|
1239
|
+
/**********************************************/
|
1240
|
+
SalienceEvaluationType SetSalienceEvaluation(
|
1241
|
+
Environment *theEnv,
|
1242
|
+
SalienceEvaluationType value)
|
1243
|
+
{
|
1244
|
+
SalienceEvaluationType ov;
|
1245
|
+
|
1246
|
+
ov = AgendaData(theEnv)->SalienceEvaluation;
|
1247
|
+
AgendaData(theEnv)->SalienceEvaluation = value;
|
1248
|
+
return ov;
|
1249
|
+
}
|
1250
|
+
|
1251
|
+
/*****************************************************************/
|
1252
|
+
/* EvaluateSalience: Returns the salience value of the specified */
|
1253
|
+
/* defrule. If salience evaluation is currently set to */
|
1254
|
+
/* when-defined, then the current value of the rule's salience */
|
1255
|
+
/* is returned. Otherwise the salience expression associated */
|
1256
|
+
/* with the rule is reevaluated, the value is stored as the */
|
1257
|
+
/* rule's current salience, and it is then returned. */
|
1258
|
+
/*****************************************************************/
|
1259
|
+
static int EvaluateSalience(
|
1260
|
+
Environment *theEnv,
|
1261
|
+
Defrule *theDefrule)
|
1262
|
+
{
|
1263
|
+
UDFValue salienceValue;
|
1264
|
+
long long salience;
|
1265
|
+
|
1266
|
+
/*==================================================*/
|
1267
|
+
/* If saliences are only being evaluated when rules */
|
1268
|
+
/* are defined, then just return the last salience */
|
1269
|
+
/* value evaluated for the rule. */
|
1270
|
+
/*==================================================*/
|
1271
|
+
|
1272
|
+
if (GetSalienceEvaluation(theEnv) == WHEN_DEFINED)
|
1273
|
+
{ return theDefrule->salience; }
|
1274
|
+
|
1275
|
+
/*=================================================================*/
|
1276
|
+
/* If the rule's salience value was defined as an integer constant */
|
1277
|
+
/* (i.e., not an expression or global variable which could change */
|
1278
|
+
/* on reevaluation), then just return the salience value computed */
|
1279
|
+
/* for the rule when it was defined. */
|
1280
|
+
/*=================================================================*/
|
1281
|
+
|
1282
|
+
if (theDefrule->dynamicSalience == NULL) return theDefrule->salience;
|
1283
|
+
|
1284
|
+
/*====================================================*/
|
1285
|
+
/* Reevaluate the rule's salience. If an error occurs */
|
1286
|
+
/* during evaluation, print an error message. */
|
1287
|
+
/*====================================================*/
|
1288
|
+
|
1289
|
+
SetEvaluationError(theEnv,false);
|
1290
|
+
if (EvaluateExpression(theEnv,theDefrule->dynamicSalience,&salienceValue))
|
1291
|
+
{
|
1292
|
+
SalienceInformationError(theEnv,"defrule",theDefrule->header.name->contents);
|
1293
|
+
return theDefrule->salience;
|
1294
|
+
}
|
1295
|
+
|
1296
|
+
/*========================================*/
|
1297
|
+
/* The salience value must be an integer. */
|
1298
|
+
/*========================================*/
|
1299
|
+
|
1300
|
+
if (salienceValue.header->type != INTEGER_TYPE)
|
1301
|
+
{
|
1302
|
+
SalienceNonIntegerError(theEnv);
|
1303
|
+
SalienceInformationError(theEnv,"defrule",theDefrule->header.name->contents);
|
1304
|
+
SetEvaluationError(theEnv,true);
|
1305
|
+
return theDefrule->salience;
|
1306
|
+
}
|
1307
|
+
|
1308
|
+
/*==========================================*/
|
1309
|
+
/* The salience value must fall between the */
|
1310
|
+
/* minimum and maximum allowed values. */
|
1311
|
+
/*==========================================*/
|
1312
|
+
|
1313
|
+
salience = salienceValue.integerValue->contents;
|
1314
|
+
|
1315
|
+
if ((salience > MAX_DEFRULE_SALIENCE) || (salience < MIN_DEFRULE_SALIENCE))
|
1316
|
+
{
|
1317
|
+
SalienceRangeError(theEnv,MIN_DEFRULE_SALIENCE,MAX_DEFRULE_SALIENCE);
|
1318
|
+
SetEvaluationError(theEnv,true);
|
1319
|
+
SalienceInformationError(theEnv,"defrule",theDefrule->header.name->contents);
|
1320
|
+
return theDefrule->salience;
|
1321
|
+
}
|
1322
|
+
|
1323
|
+
/*===================================*/
|
1324
|
+
/* Store the new salience value with */
|
1325
|
+
/* the rule and return this value. */
|
1326
|
+
/*===================================*/
|
1327
|
+
|
1328
|
+
theDefrule->salience = (int) salience;
|
1329
|
+
return theDefrule->salience;
|
1330
|
+
}
|
1331
|
+
|
1332
|
+
#if DEBUGGING_FUNCTIONS
|
1333
|
+
|
1334
|
+
/***********************************************/
|
1335
|
+
/* AgendaCommand: Prints out the agenda of the */
|
1336
|
+
/* rules that are ready to fire. */
|
1337
|
+
/* Syntax: (agenda) */
|
1338
|
+
/***********************************************/
|
1339
|
+
void AgendaCommand(
|
1340
|
+
Environment *theEnv,
|
1341
|
+
UDFContext *context,
|
1342
|
+
UDFValue *returnValue)
|
1343
|
+
{
|
1344
|
+
unsigned int numArgs;
|
1345
|
+
bool error;
|
1346
|
+
Defmodule *theModule;
|
1347
|
+
|
1348
|
+
/*===============================================================*/
|
1349
|
+
/* If a module name is specified, then the agenda of that module */
|
1350
|
+
/* is displayed. Otherwise, the agenda of the current module is */
|
1351
|
+
/* displayed. */
|
1352
|
+
/*===============================================================*/
|
1353
|
+
|
1354
|
+
numArgs = UDFArgumentCount(context);
|
1355
|
+
if (numArgs == 1)
|
1356
|
+
{
|
1357
|
+
theModule = GetModuleName(context,1,&error);
|
1358
|
+
if (error) return;
|
1359
|
+
}
|
1360
|
+
else
|
1361
|
+
{ theModule = GetCurrentModule(theEnv); }
|
1362
|
+
|
1363
|
+
/*===============================================*/
|
1364
|
+
/* Display the agenda of the appropriate module. */
|
1365
|
+
/*===============================================*/
|
1366
|
+
|
1367
|
+
Agenda(theEnv,STDOUT,theModule);
|
1368
|
+
}
|
1369
|
+
|
1370
|
+
#endif /* DEBUGGING_FUNCTIONS */
|
1371
|
+
|
1372
|
+
#endif /* DEFRULE_CONSTRUCT */
|
1373
|
+
|