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,1079 @@
|
|
1
|
+
/*******************************************************/
|
2
|
+
/* "C" Language Integrated Production System */
|
3
|
+
/* */
|
4
|
+
/* CLIPS Version 6.40 07/30/16 */
|
5
|
+
/* */
|
6
|
+
/* GENERATE MODULE */
|
7
|
+
/*******************************************************/
|
8
|
+
|
9
|
+
/*************************************************************/
|
10
|
+
/* Purpose: Provides routines for converting field */
|
11
|
+
/* constraints to expressions which can be used */
|
12
|
+
/* in the pattern and join networks. */
|
13
|
+
/* */
|
14
|
+
/* Principal Programmer(s): */
|
15
|
+
/* Gary D. Riley */
|
16
|
+
/* */
|
17
|
+
/* Contributing Programmer(s): */
|
18
|
+
/* */
|
19
|
+
/* Revision History: */
|
20
|
+
/* */
|
21
|
+
/* 6.30: Added support for hashed alpha memories. */
|
22
|
+
/* */
|
23
|
+
/* Added support for hashed comparisons to */
|
24
|
+
/* constants. */
|
25
|
+
/* */
|
26
|
+
/* Reimplemented algorithm for comparisons to */
|
27
|
+
/* variables contained within not/and CEs. */
|
28
|
+
/* */
|
29
|
+
/* 6.31: Not/and unification was only occurring for the */
|
30
|
+
/* first not/and group referencing a variable. */
|
31
|
+
/* Use of the marked flag was unneccessary since */
|
32
|
+
/* the referring variable is always the closest */
|
33
|
+
/* and unification does not occur within the same */
|
34
|
+
/* non/and group. */
|
35
|
+
/* */
|
36
|
+
/* 6.40: Pragma once and other inclusion changes. */
|
37
|
+
/* */
|
38
|
+
/* Added support for booleans with <stdbool.h>. */
|
39
|
+
/* */
|
40
|
+
/* Removed use of void pointers for specific */
|
41
|
+
/* data structures. */
|
42
|
+
/* */
|
43
|
+
/*************************************************************/
|
44
|
+
|
45
|
+
#include <stdio.h>
|
46
|
+
#include <stdlib.h>
|
47
|
+
|
48
|
+
#include "setup.h"
|
49
|
+
|
50
|
+
#if (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT
|
51
|
+
|
52
|
+
#include "argacces.h"
|
53
|
+
#include "constant.h"
|
54
|
+
#include "envrnmnt.h"
|
55
|
+
#include "exprnpsr.h"
|
56
|
+
|
57
|
+
#if DEFGLOBAL_CONSTRUCT
|
58
|
+
#include "globlpsr.h"
|
59
|
+
#endif
|
60
|
+
|
61
|
+
#include "memalloc.h"
|
62
|
+
#include "pattern.h"
|
63
|
+
#include "prntutil.h"
|
64
|
+
#include "router.h"
|
65
|
+
#include "ruledef.h"
|
66
|
+
#include "symbol.h"
|
67
|
+
|
68
|
+
#include "generate.h"
|
69
|
+
|
70
|
+
/***************************************/
|
71
|
+
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
|
72
|
+
/***************************************/
|
73
|
+
|
74
|
+
static void ExtractAnds(Environment *,struct lhsParseNode *,bool,
|
75
|
+
struct expr **,struct expr **,struct expr **,
|
76
|
+
struct expr **,struct nandFrame *);
|
77
|
+
static void ExtractFieldTest(Environment *,struct lhsParseNode *,bool,
|
78
|
+
struct expr **,struct expr **,struct expr **,
|
79
|
+
struct expr **,struct nandFrame *);
|
80
|
+
static struct expr *GetfieldReplace(Environment *,struct lhsParseNode *);
|
81
|
+
static struct expr *GenPNConstant(Environment *,struct lhsParseNode *);
|
82
|
+
static struct expr *GenJNConstant(Environment *,struct lhsParseNode *,bool);
|
83
|
+
static struct expr *GenJNColon(Environment *,struct lhsParseNode *,bool,struct nandFrame *);
|
84
|
+
static struct expr *GenPNColon(Environment *,struct lhsParseNode *);
|
85
|
+
static struct expr *GenJNEq(Environment *,struct lhsParseNode *,bool,struct nandFrame *);
|
86
|
+
static struct expr *GenPNEq(Environment *,struct lhsParseNode *);
|
87
|
+
static struct expr *GenJNVariableComparison(Environment *,struct lhsParseNode *,
|
88
|
+
struct lhsParseNode *,bool);
|
89
|
+
static struct expr *GenPNVariableComparison(Environment *,struct lhsParseNode *,
|
90
|
+
struct lhsParseNode *);
|
91
|
+
static bool AllVariablesInPattern(struct lhsParseNode *,
|
92
|
+
int);
|
93
|
+
static bool AllVariablesInExpression(struct lhsParseNode *,
|
94
|
+
int);
|
95
|
+
|
96
|
+
/*******************************************************/
|
97
|
+
/* FieldConversion: Generates join and pattern network */
|
98
|
+
/* expressions for a field constraint. */
|
99
|
+
/*******************************************************/
|
100
|
+
void FieldConversion(
|
101
|
+
Environment *theEnv,
|
102
|
+
struct lhsParseNode *theField,
|
103
|
+
struct lhsParseNode *thePattern,
|
104
|
+
struct nandFrame *theNandFrames)
|
105
|
+
{
|
106
|
+
bool testInPatternNetwork = true;
|
107
|
+
struct lhsParseNode *patternPtr;
|
108
|
+
struct expr *headOfPNExpression, *headOfJNExpression;
|
109
|
+
struct expr *lastPNExpression, *lastJNExpression;
|
110
|
+
struct expr *tempExpression;
|
111
|
+
struct expr *patternNetTest = NULL;
|
112
|
+
struct expr *joinNetTest = NULL;
|
113
|
+
struct expr *constantSelector = NULL;
|
114
|
+
struct expr *constantValue = NULL;
|
115
|
+
|
116
|
+
/*==================================================*/
|
117
|
+
/* Consider a NULL pointer to be an internal error. */
|
118
|
+
/*==================================================*/
|
119
|
+
|
120
|
+
if (theField == NULL)
|
121
|
+
{
|
122
|
+
SystemError(theEnv,"ANALYSIS",3);
|
123
|
+
ExitRouter(theEnv,EXIT_FAILURE);
|
124
|
+
}
|
125
|
+
|
126
|
+
/*========================================================*/
|
127
|
+
/* Determine if constant testing must be performed in the */
|
128
|
+
/* join network. Only possible when a field contains an */
|
129
|
+
/* or ('|') and references are made to variables outside */
|
130
|
+
/* the pattern. */
|
131
|
+
/*========================================================*/
|
132
|
+
|
133
|
+
if (theField->bottom != NULL)
|
134
|
+
{
|
135
|
+
if (theField->bottom->bottom != NULL)
|
136
|
+
{ testInPatternNetwork = AllVariablesInPattern(theField->bottom,theField->pattern); }
|
137
|
+
}
|
138
|
+
|
139
|
+
/*=============================================================*/
|
140
|
+
/* Extract pattern and join network expressions. Loop through */
|
141
|
+
/* the or'ed constraints of the field, extracting pattern and */
|
142
|
+
/* join network expressions and adding them to a running list. */
|
143
|
+
/*=============================================================*/
|
144
|
+
|
145
|
+
headOfPNExpression = lastPNExpression = NULL;
|
146
|
+
headOfJNExpression = lastJNExpression = NULL;
|
147
|
+
|
148
|
+
for (patternPtr = theField->bottom;
|
149
|
+
patternPtr != NULL;
|
150
|
+
patternPtr = patternPtr->bottom)
|
151
|
+
{
|
152
|
+
/*=============================================*/
|
153
|
+
/* Extract pattern and join network tests from */
|
154
|
+
/* the or'ed constraint being examined. */
|
155
|
+
/*=============================================*/
|
156
|
+
|
157
|
+
ExtractAnds(theEnv,patternPtr,testInPatternNetwork,&patternNetTest,&joinNetTest,
|
158
|
+
&constantSelector,&constantValue,theNandFrames);
|
159
|
+
|
160
|
+
/*=============================================================*/
|
161
|
+
/* Constant hashing is only used in the pattern network if the */
|
162
|
+
/* field doesn't contain an or'ed constraint. For example, the */
|
163
|
+
/* constaint "red | blue" can not use hashing. */
|
164
|
+
/*=============================================================*/
|
165
|
+
|
166
|
+
if (constantSelector != NULL)
|
167
|
+
{
|
168
|
+
if ((patternPtr == theField->bottom) &&
|
169
|
+
(patternPtr->bottom == NULL))
|
170
|
+
{
|
171
|
+
theField->constantSelector = constantSelector;
|
172
|
+
theField->constantValue = constantValue;
|
173
|
+
}
|
174
|
+
else
|
175
|
+
{
|
176
|
+
ReturnExpression(theEnv,constantSelector);
|
177
|
+
ReturnExpression(theEnv,constantValue);
|
178
|
+
ReturnExpression(theEnv,theField->constantSelector);
|
179
|
+
ReturnExpression(theEnv,theField->constantValue);
|
180
|
+
theField->constantSelector = NULL;
|
181
|
+
theField->constantValue = NULL;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
/*=====================================================*/
|
186
|
+
/* Add the new pattern network expressions to the list */
|
187
|
+
/* of pattern network expressions being constructed. */
|
188
|
+
/*=====================================================*/
|
189
|
+
|
190
|
+
if (patternNetTest != NULL)
|
191
|
+
{
|
192
|
+
if (lastPNExpression == NULL)
|
193
|
+
{ headOfPNExpression = patternNetTest; }
|
194
|
+
else
|
195
|
+
{ lastPNExpression->nextArg = patternNetTest; }
|
196
|
+
lastPNExpression = patternNetTest;
|
197
|
+
}
|
198
|
+
|
199
|
+
/*==================================================*/
|
200
|
+
/* Add the new join network expressions to the list */
|
201
|
+
/* of join network expressions being constructed. */
|
202
|
+
/*==================================================*/
|
203
|
+
|
204
|
+
if (joinNetTest != NULL)
|
205
|
+
{
|
206
|
+
if (lastJNExpression == NULL)
|
207
|
+
{ headOfJNExpression = joinNetTest; }
|
208
|
+
else
|
209
|
+
{ lastJNExpression->nextArg = joinNetTest; }
|
210
|
+
lastJNExpression = joinNetTest;
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
/*==========================================================*/
|
215
|
+
/* If there was more than one expression generated from the */
|
216
|
+
/* or'ed field constraints for the pattern network, then */
|
217
|
+
/* enclose the expressions within an "or" function call. */
|
218
|
+
/*==========================================================*/
|
219
|
+
|
220
|
+
if ((headOfPNExpression != NULL) ? (headOfPNExpression->nextArg != NULL) : false)
|
221
|
+
{
|
222
|
+
tempExpression = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_OR);
|
223
|
+
tempExpression->argList = headOfPNExpression;
|
224
|
+
headOfPNExpression = tempExpression;
|
225
|
+
}
|
226
|
+
|
227
|
+
/*==========================================================*/
|
228
|
+
/* If there was more than one expression generated from the */
|
229
|
+
/* or'ed field constraints for the join network, then */
|
230
|
+
/* enclose the expressions within an "or" function call. */
|
231
|
+
/*==========================================================*/
|
232
|
+
|
233
|
+
if ((headOfJNExpression != NULL) ? (headOfJNExpression->nextArg != NULL) : false)
|
234
|
+
{
|
235
|
+
tempExpression = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_OR);
|
236
|
+
tempExpression->argList = headOfJNExpression;
|
237
|
+
headOfJNExpression = tempExpression;
|
238
|
+
}
|
239
|
+
|
240
|
+
/*===============================================================*/
|
241
|
+
/* If the field constraint binds a variable that was previously */
|
242
|
+
/* bound somewhere in the LHS of the rule, then generate an */
|
243
|
+
/* expression to compare this binding occurrence of the variable */
|
244
|
+
/* to the previous binding occurrence. */
|
245
|
+
/*===============================================================*/
|
246
|
+
|
247
|
+
if (((theField->pnType == MF_VARIABLE_NODE) || (theField->pnType == SF_VARIABLE_NODE)) &&
|
248
|
+
(theField->referringNode != NULL))
|
249
|
+
{
|
250
|
+
/*================================================================*/
|
251
|
+
/* If the previous variable reference is within the same pattern, */
|
252
|
+
/* then the variable comparison can occur in the pattern network. */
|
253
|
+
/*================================================================*/
|
254
|
+
|
255
|
+
if (theField->referringNode->pattern == theField->pattern)
|
256
|
+
{
|
257
|
+
tempExpression = GenPNVariableComparison(theEnv,theField,theField->referringNode);
|
258
|
+
headOfPNExpression = CombineExpressions(theEnv,tempExpression,headOfPNExpression);
|
259
|
+
}
|
260
|
+
|
261
|
+
/*====================================*/
|
262
|
+
/* Otherwise, the variable comparison */
|
263
|
+
/* must occur in the join network. */
|
264
|
+
/*====================================*/
|
265
|
+
|
266
|
+
else if (theField->referringNode->pattern > 0)
|
267
|
+
{
|
268
|
+
AddNandUnification(theEnv,theField,theNandFrames);
|
269
|
+
|
270
|
+
/*====================================*/
|
271
|
+
/* Generate an expression to test the */
|
272
|
+
/* variable in a non-nand join. */
|
273
|
+
/*====================================*/
|
274
|
+
|
275
|
+
tempExpression = GenJNVariableComparison(theEnv,theField,theField->referringNode,false);
|
276
|
+
headOfJNExpression = CombineExpressions(theEnv,tempExpression,headOfJNExpression);
|
277
|
+
|
278
|
+
/*==========================*/
|
279
|
+
/* Generate the hash index. */
|
280
|
+
/*==========================*/
|
281
|
+
|
282
|
+
if (theField->patternType->genGetPNValueFunction != NULL)
|
283
|
+
{
|
284
|
+
tempExpression = (*theField->patternType->genGetPNValueFunction)(theEnv,theField);
|
285
|
+
thePattern->rightHash = AppendExpressions(tempExpression,thePattern->rightHash);
|
286
|
+
}
|
287
|
+
|
288
|
+
if (theField->referringNode->patternType->genGetJNValueFunction)
|
289
|
+
{
|
290
|
+
tempExpression = (*theField->referringNode->patternType->genGetJNValueFunction)(theEnv,theField->referringNode,LHS);
|
291
|
+
thePattern->leftHash = AppendExpressions(tempExpression,thePattern->leftHash);
|
292
|
+
}
|
293
|
+
}
|
294
|
+
}
|
295
|
+
|
296
|
+
/*======================================================*/
|
297
|
+
/* Attach the pattern network expressions to the field. */
|
298
|
+
/*======================================================*/
|
299
|
+
|
300
|
+
theField->networkTest = headOfPNExpression;
|
301
|
+
|
302
|
+
/*=====================================================*/
|
303
|
+
/* Attach the join network expressions to the pattern. */
|
304
|
+
/*=====================================================*/
|
305
|
+
|
306
|
+
thePattern->networkTest = CombineExpressions(theEnv,thePattern->networkTest,headOfJNExpression);
|
307
|
+
}
|
308
|
+
|
309
|
+
/****************************************************************************/
|
310
|
+
/* ExtractAnds: Loops through a single set of subfields bound together by */
|
311
|
+
/* an & connective constraint in a field and generates expressions needed */
|
312
|
+
/* for testing conditions in the pattern and join network. */
|
313
|
+
/****************************************************************************/
|
314
|
+
static void ExtractAnds(
|
315
|
+
Environment *theEnv,
|
316
|
+
struct lhsParseNode *andField,
|
317
|
+
bool testInPatternNetwork,
|
318
|
+
struct expr **patternNetTest,
|
319
|
+
struct expr **joinNetTest,
|
320
|
+
struct expr **constantSelector,
|
321
|
+
struct expr **constantValue,
|
322
|
+
struct nandFrame *theNandFrames)
|
323
|
+
{
|
324
|
+
struct expr *newPNTest, *newJNTest, *newConstantSelector, *newConstantValue;
|
325
|
+
|
326
|
+
/*=================================================*/
|
327
|
+
/* Before starting, the subfield has no pattern or */
|
328
|
+
/* join network expressions associated with it. */
|
329
|
+
/*=================================================*/
|
330
|
+
|
331
|
+
*patternNetTest = NULL;
|
332
|
+
*joinNetTest = NULL;
|
333
|
+
*constantSelector = NULL;
|
334
|
+
*constantValue = NULL;
|
335
|
+
|
336
|
+
/*=========================================*/
|
337
|
+
/* Loop through each of the subfields tied */
|
338
|
+
/* together by the & constraint. */
|
339
|
+
/*=========================================*/
|
340
|
+
|
341
|
+
for (;
|
342
|
+
andField != NULL;
|
343
|
+
andField = andField->right)
|
344
|
+
{
|
345
|
+
/*======================================*/
|
346
|
+
/* Extract the pattern and join network */
|
347
|
+
/* expressions from the subfield. */
|
348
|
+
/*======================================*/
|
349
|
+
|
350
|
+
ExtractFieldTest(theEnv,andField,testInPatternNetwork,&newPNTest,&newJNTest,
|
351
|
+
&newConstantSelector,&newConstantValue,theNandFrames);
|
352
|
+
|
353
|
+
/*=================================================*/
|
354
|
+
/* Add the new expressions to the list of pattern */
|
355
|
+
/* and join network expressions being constructed. */
|
356
|
+
/*=================================================*/
|
357
|
+
|
358
|
+
*patternNetTest = CombineExpressions(theEnv,*patternNetTest,newPNTest);
|
359
|
+
*joinNetTest = CombineExpressions(theEnv,*joinNetTest,newJNTest);
|
360
|
+
*constantSelector = CombineExpressions(theEnv,*constantSelector,newConstantSelector);
|
361
|
+
*constantValue = CombineExpressions(theEnv,*constantValue,newConstantValue);
|
362
|
+
}
|
363
|
+
}
|
364
|
+
|
365
|
+
/************************************************************************/
|
366
|
+
/* ExtractFieldTest: Generates the pattern or join network expression */
|
367
|
+
/* associated with the basic field constraints: constants, predicate, */
|
368
|
+
/* return value, and variable constraints. Based on the context in */
|
369
|
+
/* which a constraint is used, some constraints may be tested in the */
|
370
|
+
/* pattern network while other constraints must be tested in the join */
|
371
|
+
/* network. Constraints which refer to variables in other patterns */
|
372
|
+
/* must be tested in the join network. The predicate constraint */
|
373
|
+
/* associated with a test CE is tested in the join network (even if */
|
374
|
+
/* all the variables it refers to are contained in the previous */
|
375
|
+
/* pattern CE). If one of the or'ed constraints in a field refers to */
|
376
|
+
/* a binding occurrence of a variable in another pattern, then the */
|
377
|
+
/* other constraints in the field must be tested in the join network */
|
378
|
+
/* (this is how some constant constraint tests must occasionally be */
|
379
|
+
/* performed in the join network). */
|
380
|
+
/************************************************************************/
|
381
|
+
static void ExtractFieldTest(
|
382
|
+
Environment *theEnv,
|
383
|
+
struct lhsParseNode *theField,
|
384
|
+
bool testInPatternNetwork,
|
385
|
+
struct expr **patternNetTest,
|
386
|
+
struct expr **joinNetTest,
|
387
|
+
struct expr **constantSelector,
|
388
|
+
struct expr **constantValue,
|
389
|
+
struct nandFrame *theNandFrames)
|
390
|
+
{
|
391
|
+
*patternNetTest = NULL;
|
392
|
+
*joinNetTest = NULL;
|
393
|
+
*constantSelector = NULL;
|
394
|
+
*constantValue = NULL;
|
395
|
+
|
396
|
+
/*==========================================================*/
|
397
|
+
/* Generate a network expression for a constant constraint. */
|
398
|
+
/*==========================================================*/
|
399
|
+
|
400
|
+
if ((theField->pnType == STRING_NODE) || (theField->pnType == SYMBOL_NODE) ||
|
401
|
+
#if OBJECT_SYSTEM
|
402
|
+
(theField->pnType == INSTANCE_NAME_NODE) ||
|
403
|
+
#endif
|
404
|
+
(theField->pnType == FLOAT_NODE) || (theField->pnType == INTEGER_NODE))
|
405
|
+
{
|
406
|
+
if (testInPatternNetwork == true)
|
407
|
+
{
|
408
|
+
*patternNetTest = GenPNConstant(theEnv,theField);
|
409
|
+
|
410
|
+
if (! theField->negated)
|
411
|
+
{
|
412
|
+
*constantSelector = (*theField->patternType->genGetPNValueFunction)(theEnv,theField);
|
413
|
+
*constantValue = GenConstant(theEnv,NodeTypeToType(theField),theField->value);
|
414
|
+
}
|
415
|
+
}
|
416
|
+
else
|
417
|
+
{ *joinNetTest = GenJNConstant(theEnv,theField,false); } // TBD Remove false
|
418
|
+
}
|
419
|
+
|
420
|
+
/*===========================================================*/
|
421
|
+
/* Generate a network expression for a predicate constraint. */
|
422
|
+
/*===========================================================*/
|
423
|
+
|
424
|
+
else if (theField->pnType == PREDICATE_CONSTRAINT_NODE)
|
425
|
+
{
|
426
|
+
if ((testInPatternNetwork == true) &&
|
427
|
+
(AllVariablesInExpression(theField->expression,theField->pattern) == true))
|
428
|
+
{ *patternNetTest = GenPNColon(theEnv,theField); }
|
429
|
+
else
|
430
|
+
{ *joinNetTest = GenJNColon(theEnv,theField,false,theNandFrames); } // TBD Remove false
|
431
|
+
}
|
432
|
+
|
433
|
+
/*==============================================================*/
|
434
|
+
/* Generate a network expression for a return value constraint. */
|
435
|
+
/*==============================================================*/
|
436
|
+
|
437
|
+
else if (theField->pnType == RETURN_VALUE_CONSTRAINT_NODE)
|
438
|
+
{
|
439
|
+
if ((testInPatternNetwork == true) &&
|
440
|
+
(AllVariablesInExpression(theField->expression,theField->pattern) == true))
|
441
|
+
{ *patternNetTest = GenPNEq(theEnv,theField); }
|
442
|
+
else
|
443
|
+
{ *joinNetTest = GenJNEq(theEnv,theField,false,theNandFrames); } // TBD Remove false
|
444
|
+
}
|
445
|
+
|
446
|
+
/*=====================================================================*/
|
447
|
+
/* Generate a network expression for a variable comparison constraint. */
|
448
|
+
/*=====================================================================*/
|
449
|
+
|
450
|
+
else if ((theField->pnType == SF_VARIABLE_NODE) || (theField->pnType == MF_VARIABLE_NODE))
|
451
|
+
{
|
452
|
+
if ((testInPatternNetwork == true) &&
|
453
|
+
((theField->referringNode != NULL) ?
|
454
|
+
(theField->referringNode->pattern == theField->pattern) :
|
455
|
+
false))
|
456
|
+
{ *patternNetTest = GenPNVariableComparison(theEnv,theField,theField->referringNode); }
|
457
|
+
else
|
458
|
+
{
|
459
|
+
*joinNetTest = GenJNVariableComparison(theEnv,theField,theField->referringNode,false);
|
460
|
+
AddNandUnification(theEnv,theField,theNandFrames);
|
461
|
+
}
|
462
|
+
}
|
463
|
+
}
|
464
|
+
|
465
|
+
/*********************************************************/
|
466
|
+
/* GenPNConstant: Generates an expression for use in the */
|
467
|
+
/* pattern network of a data entity (such as a fact or */
|
468
|
+
/* instance). The expression generated is for comparing */
|
469
|
+
/* a constant value against a specified slot/field in */
|
470
|
+
/* the data entity for equality or inequality. */
|
471
|
+
/*********************************************************/
|
472
|
+
static struct expr *GenPNConstant(
|
473
|
+
Environment *theEnv,
|
474
|
+
struct lhsParseNode *theField)
|
475
|
+
{
|
476
|
+
struct expr *top;
|
477
|
+
|
478
|
+
/*===============================================*/
|
479
|
+
/* If the pattern parser is capable of creating */
|
480
|
+
/* a specialized test, then call the function to */
|
481
|
+
/* generate the pattern network test and return */
|
482
|
+
/* the expression generated. */
|
483
|
+
/*===============================================*/
|
484
|
+
|
485
|
+
if (theField->patternType->genPNConstantFunction != NULL)
|
486
|
+
{ return (*theField->patternType->genPNConstantFunction)(theEnv,theField); }
|
487
|
+
|
488
|
+
/*===================================================*/
|
489
|
+
/* Otherwise, generate a test which uses the eq/neq */
|
490
|
+
/* function to compare the pattern field/slot to the */
|
491
|
+
/* constant and then return the expression. */
|
492
|
+
/*===================================================*/
|
493
|
+
|
494
|
+
if (theField->negated)
|
495
|
+
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NEQ); }
|
496
|
+
else
|
497
|
+
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_EQ); }
|
498
|
+
|
499
|
+
top->argList = (*theField->patternType->genGetPNValueFunction)(theEnv,theField);
|
500
|
+
top->argList->nextArg = GenConstant(theEnv,NodeTypeToType(theField),theField->value);
|
501
|
+
|
502
|
+
return(top);
|
503
|
+
}
|
504
|
+
|
505
|
+
/************************************************************/
|
506
|
+
/* GenJNConstant: Generates an expression for use in the */
|
507
|
+
/* join network. The expression generated is for comparing */
|
508
|
+
/* a constant value against a specified slot/field in the */
|
509
|
+
/* data entity for equality or inequality. */
|
510
|
+
/************************************************************/
|
511
|
+
static struct expr *GenJNConstant(
|
512
|
+
Environment *theEnv,
|
513
|
+
struct lhsParseNode *theField,
|
514
|
+
bool isNand)
|
515
|
+
{
|
516
|
+
struct expr *top;
|
517
|
+
|
518
|
+
/*===============================================*/
|
519
|
+
/* If the pattern parser is capable of creating */
|
520
|
+
/* a specialized test, then call the function to */
|
521
|
+
/* generate the join network test and return the */
|
522
|
+
/* expression generated. */
|
523
|
+
/*===============================================*/
|
524
|
+
|
525
|
+
if (theField->patternType->genJNConstantFunction != NULL)
|
526
|
+
{
|
527
|
+
if (isNand)
|
528
|
+
{ return (*theField->patternType->genJNConstantFunction)(theEnv,theField,NESTED_RHS); }
|
529
|
+
else
|
530
|
+
{ return (*theField->patternType->genJNConstantFunction)(theEnv,theField,RHS); }
|
531
|
+
}
|
532
|
+
|
533
|
+
/*===================================================*/
|
534
|
+
/* Otherwise, generate a test which uses the eq/neq */
|
535
|
+
/* function to compare the pattern field/slot to the */
|
536
|
+
/* constant and then return the expression. */
|
537
|
+
/*===================================================*/
|
538
|
+
|
539
|
+
if (theField->negated)
|
540
|
+
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NEQ); }
|
541
|
+
else
|
542
|
+
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_EQ); }
|
543
|
+
|
544
|
+
if (isNand)
|
545
|
+
{ top->argList = (*theField->patternType->genGetJNValueFunction)(theEnv,theField,NESTED_RHS); }
|
546
|
+
else
|
547
|
+
{ top->argList = (*theField->patternType->genGetJNValueFunction)(theEnv,theField,RHS); }
|
548
|
+
|
549
|
+
top->argList->nextArg = GenConstant(theEnv,NodeTypeToType(theField),theField->value);
|
550
|
+
|
551
|
+
return(top);
|
552
|
+
}
|
553
|
+
|
554
|
+
/******************************************************/
|
555
|
+
/* GenJNColon: Generates an expression for use in the */
|
556
|
+
/* join network. The expression generated is for a */
|
557
|
+
/* predicate field constraint (the : constraint). */
|
558
|
+
/******************************************************/
|
559
|
+
static struct expr *GenJNColon(
|
560
|
+
Environment *theEnv,
|
561
|
+
struct lhsParseNode *theField,
|
562
|
+
bool isNand,
|
563
|
+
struct nandFrame *theNandFrames)
|
564
|
+
{
|
565
|
+
struct expr *top, *conversion;
|
566
|
+
|
567
|
+
/*==================================================*/
|
568
|
+
/* Replace variables with function calls to extract */
|
569
|
+
/* the appropriate value from the data entity. */
|
570
|
+
/*==================================================*/
|
571
|
+
|
572
|
+
if (isNand)
|
573
|
+
{ conversion = GetvarReplace(theEnv,theField->expression,true,theNandFrames); }
|
574
|
+
else
|
575
|
+
{ conversion = GetvarReplace(theEnv,theField->expression,false,theNandFrames); }
|
576
|
+
|
577
|
+
/*================================================*/
|
578
|
+
/* If the predicate constraint is negated by a ~, */
|
579
|
+
/* then wrap a "not" function call around the */
|
580
|
+
/* expression before returning it. Otherwise, */
|
581
|
+
/* just return the expression. */
|
582
|
+
/*================================================*/
|
583
|
+
|
584
|
+
if (theField->negated)
|
585
|
+
{
|
586
|
+
top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NOT);
|
587
|
+
top->argList = conversion;
|
588
|
+
}
|
589
|
+
else
|
590
|
+
{ top = conversion; }
|
591
|
+
|
592
|
+
return(top);
|
593
|
+
}
|
594
|
+
|
595
|
+
/******************************************************/
|
596
|
+
/* GenPNColon: Generates an expression for use in the */
|
597
|
+
/* pattern network. The expression generated is for */
|
598
|
+
/* a predicate field constraint (the : constraint). */
|
599
|
+
/******************************************************/
|
600
|
+
static struct expr *GenPNColon(
|
601
|
+
Environment *theEnv,
|
602
|
+
struct lhsParseNode *theField)
|
603
|
+
{
|
604
|
+
struct expr *top, *conversion;
|
605
|
+
|
606
|
+
/*==================================================*/
|
607
|
+
/* Replace variables with function calls to extract */
|
608
|
+
/* the appropriate value from the data entity. */
|
609
|
+
/*==================================================*/
|
610
|
+
|
611
|
+
conversion = GetfieldReplace(theEnv,theField->expression);
|
612
|
+
|
613
|
+
/*================================================*/
|
614
|
+
/* If the predicate constraint is negated by a ~, */
|
615
|
+
/* then wrap a "not" function call around the */
|
616
|
+
/* expression before returning it. Otherwise, */
|
617
|
+
/* just return the expression. */
|
618
|
+
/*================================================*/
|
619
|
+
|
620
|
+
if (theField->negated)
|
621
|
+
{
|
622
|
+
top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NOT);
|
623
|
+
top->argList = conversion;
|
624
|
+
}
|
625
|
+
else
|
626
|
+
{ top = conversion; }
|
627
|
+
|
628
|
+
return(top);
|
629
|
+
}
|
630
|
+
|
631
|
+
/******************************************************/
|
632
|
+
/* GenJNEq: Generates an expression for use in the */
|
633
|
+
/* join network. The expression generated is for a */
|
634
|
+
/* return value field constraint (the = constraint). */
|
635
|
+
/******************************************************/
|
636
|
+
static struct expr *GenJNEq(
|
637
|
+
Environment *theEnv,
|
638
|
+
struct lhsParseNode *theField,
|
639
|
+
bool isNand,
|
640
|
+
struct nandFrame *theNandFrames)
|
641
|
+
{
|
642
|
+
struct expr *top, *conversion;
|
643
|
+
|
644
|
+
/*==================================================*/
|
645
|
+
/* Replace variables with function calls to extract */
|
646
|
+
/* the appropriate value from the data entity. */
|
647
|
+
/*==================================================*/
|
648
|
+
|
649
|
+
if (isNand)
|
650
|
+
{ conversion = GetvarReplace(theEnv,theField->expression,true,theNandFrames); }
|
651
|
+
else
|
652
|
+
{ conversion = GetvarReplace(theEnv,theField->expression,false,theNandFrames); }
|
653
|
+
|
654
|
+
/*============================================================*/
|
655
|
+
/* If the return value constraint is negated by a ~, then use */
|
656
|
+
/* the neq function to compare the value of the field to the */
|
657
|
+
/* value returned by the function call. Otherwise, use eq to */
|
658
|
+
/* compare the two values. */
|
659
|
+
/*============================================================*/
|
660
|
+
|
661
|
+
if (theField->negated)
|
662
|
+
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NEQ); }
|
663
|
+
else
|
664
|
+
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_EQ); }
|
665
|
+
|
666
|
+
if (isNand)
|
667
|
+
{ top->argList = (*theField->patternType->genGetJNValueFunction)(theEnv,theField,NESTED_RHS); }
|
668
|
+
else
|
669
|
+
{ top->argList = (*theField->patternType->genGetJNValueFunction)(theEnv,theField,RHS); }
|
670
|
+
|
671
|
+
top->argList->nextArg = conversion;
|
672
|
+
|
673
|
+
return(top);
|
674
|
+
}
|
675
|
+
|
676
|
+
/*******************************************************/
|
677
|
+
/* GenPNEq: Generates an expression for use in the */
|
678
|
+
/* pattern network. The expression generated is for a */
|
679
|
+
/* return value field constraint (the = constraint). */
|
680
|
+
/*******************************************************/
|
681
|
+
static struct expr *GenPNEq(
|
682
|
+
Environment *theEnv,
|
683
|
+
struct lhsParseNode *theField)
|
684
|
+
{
|
685
|
+
struct expr *top, *conversion;
|
686
|
+
|
687
|
+
/*==================================================*/
|
688
|
+
/* Replace variables with function calls to extract */
|
689
|
+
/* the appropriate value from the data entity. */
|
690
|
+
/*==================================================*/
|
691
|
+
|
692
|
+
conversion = GetfieldReplace(theEnv,theField->expression);
|
693
|
+
|
694
|
+
/*============================================================*/
|
695
|
+
/* If the return value constraint is negated by a ~, then use */
|
696
|
+
/* the neq function to compare the value of the field to the */
|
697
|
+
/* value returned by the function call. Otherwise, use eq to */
|
698
|
+
/* compare the two values. */
|
699
|
+
/*============================================================*/
|
700
|
+
|
701
|
+
if (theField->negated)
|
702
|
+
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NEQ); }
|
703
|
+
else
|
704
|
+
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_EQ); }
|
705
|
+
|
706
|
+
top->argList = (*theField->patternType->genGetPNValueFunction)(theEnv,theField);
|
707
|
+
top->argList->nextArg = conversion;
|
708
|
+
|
709
|
+
return(top);
|
710
|
+
}
|
711
|
+
|
712
|
+
/************************************************************************/
|
713
|
+
/* AddNandUnification: Adds expressions to the nand joins to unify the */
|
714
|
+
/* variable bindings that need to match from the left and right paths */
|
715
|
+
/* taken through the join network for not/and CE group. */
|
716
|
+
/************************************************************************/
|
717
|
+
void AddNandUnification(
|
718
|
+
Environment *theEnv,
|
719
|
+
struct lhsParseNode *nodeList,
|
720
|
+
struct nandFrame *theNandFrames)
|
721
|
+
{
|
722
|
+
struct nandFrame *theFrame;
|
723
|
+
struct expr *tempExpression;
|
724
|
+
|
725
|
+
/*====================================================*/
|
726
|
+
/* If the reference is to a prior variable within the */
|
727
|
+
/* same nand group, then there's no need to create an */
|
728
|
+
/* external network test. */
|
729
|
+
/*====================================================*/
|
730
|
+
|
731
|
+
if (nodeList->beginNandDepth == nodeList->referringNode->beginNandDepth)
|
732
|
+
{ return; }
|
733
|
+
|
734
|
+
/*=========================================*/
|
735
|
+
/* Don't generate an external network test */
|
736
|
+
/* if one has already been generated. */
|
737
|
+
/*=========================================*/
|
738
|
+
|
739
|
+
// if (nodeList->referringNode->marked)
|
740
|
+
// { return; }
|
741
|
+
|
742
|
+
/*======================================================*/
|
743
|
+
/* Find the frame to which the test should be attached. */
|
744
|
+
/*======================================================*/
|
745
|
+
|
746
|
+
for (theFrame = theNandFrames;
|
747
|
+
theFrame != NULL;
|
748
|
+
theFrame = theFrame->next)
|
749
|
+
{
|
750
|
+
if (theFrame->depth >= nodeList->referringNode->beginNandDepth)
|
751
|
+
{
|
752
|
+
// nodeList->referringNode->marked = true;
|
753
|
+
|
754
|
+
tempExpression = GenJNVariableComparison(theEnv,nodeList->referringNode,nodeList->referringNode,true);
|
755
|
+
|
756
|
+
theFrame->nandCE->externalNetworkTest = CombineExpressions(theEnv,theFrame->nandCE->externalNetworkTest,tempExpression);
|
757
|
+
|
758
|
+
tempExpression = (*nodeList->referringNode->patternType->genGetJNValueFunction)(theEnv,nodeList->referringNode,LHS);
|
759
|
+
theFrame->nandCE->externalRightHash = AppendExpressions(theFrame->nandCE->externalRightHash,tempExpression);
|
760
|
+
|
761
|
+
tempExpression = (*nodeList->referringNode->patternType->genGetJNValueFunction)(theEnv,nodeList->referringNode,LHS);
|
762
|
+
theFrame->nandCE->externalLeftHash = AppendExpressions(theFrame->nandCE->externalLeftHash,tempExpression);
|
763
|
+
}
|
764
|
+
}
|
765
|
+
}
|
766
|
+
|
767
|
+
/*******************************************************************/
|
768
|
+
/* GetvarReplace: Replaces occurences of variables in expressions */
|
769
|
+
/* with function calls that will extract the variable's value */
|
770
|
+
/* from a partial match (i.e. from information stored in the */
|
771
|
+
/* join network or the activation of the rule). */
|
772
|
+
/*******************************************************************/
|
773
|
+
struct expr *GetvarReplace(
|
774
|
+
Environment *theEnv,
|
775
|
+
struct lhsParseNode *nodeList,
|
776
|
+
bool isNand,
|
777
|
+
struct nandFrame *theNandFrames)
|
778
|
+
{
|
779
|
+
struct expr *newList;
|
780
|
+
|
781
|
+
/*====================================*/
|
782
|
+
/* Return NULL for a NULL pointer */
|
783
|
+
/* (i.e. nothing has to be replaced). */
|
784
|
+
/*====================================*/
|
785
|
+
|
786
|
+
if (nodeList == NULL) return NULL;
|
787
|
+
|
788
|
+
/*=====================================================*/
|
789
|
+
/* Create an expression data structure and recursively */
|
790
|
+
/* replace variables in its argument list and next */
|
791
|
+
/* argument links. */
|
792
|
+
/*=====================================================*/
|
793
|
+
|
794
|
+
newList = get_struct(theEnv,expr);
|
795
|
+
newList->type = NodeTypeToType(nodeList);
|
796
|
+
newList->value = nodeList->value;
|
797
|
+
newList->nextArg = GetvarReplace(theEnv,nodeList->right,isNand,theNandFrames);
|
798
|
+
newList->argList = GetvarReplace(theEnv,nodeList->bottom,isNand,theNandFrames);
|
799
|
+
|
800
|
+
/*=========================================================*/
|
801
|
+
/* If the present node being examined is either a local or */
|
802
|
+
/* global variable, then replace it with a function call */
|
803
|
+
/* that will return the variable's value. */
|
804
|
+
/*=========================================================*/
|
805
|
+
|
806
|
+
if ((nodeList->pnType == SF_VARIABLE_NODE) || (nodeList->pnType == MF_VARIABLE_NODE))
|
807
|
+
{
|
808
|
+
AddNandUnification(theEnv,nodeList,theNandFrames);
|
809
|
+
|
810
|
+
/*=============================================================*/
|
811
|
+
/* Referencing a variable outside the scope of the immediately */
|
812
|
+
/* enclosing not/and CE requires that the test be performed in */
|
813
|
+
/* the "join from the right" join. */
|
814
|
+
/*=============================================================*/
|
815
|
+
|
816
|
+
if (isNand)
|
817
|
+
{
|
818
|
+
if (nodeList->beginNandDepth > nodeList->referringNode->beginNandDepth)
|
819
|
+
{
|
820
|
+
(*nodeList->referringNode->patternType->replaceGetJNValueFunction)
|
821
|
+
(theEnv,newList,nodeList->referringNode,LHS);
|
822
|
+
}
|
823
|
+
else
|
824
|
+
{
|
825
|
+
(*nodeList->referringNode->patternType->replaceGetJNValueFunction)
|
826
|
+
(theEnv,newList,nodeList->referringNode,NESTED_RHS);
|
827
|
+
}
|
828
|
+
}
|
829
|
+
else
|
830
|
+
{
|
831
|
+
if (nodeList->joinDepth != nodeList->referringNode->joinDepth)
|
832
|
+
{
|
833
|
+
(*nodeList->referringNode->patternType->replaceGetJNValueFunction)
|
834
|
+
(theEnv,newList,nodeList->referringNode,LHS);
|
835
|
+
}
|
836
|
+
else
|
837
|
+
{
|
838
|
+
(*nodeList->referringNode->patternType->replaceGetJNValueFunction)
|
839
|
+
(theEnv,newList,nodeList->referringNode,RHS);
|
840
|
+
}
|
841
|
+
}
|
842
|
+
}
|
843
|
+
#if DEFGLOBAL_CONSTRUCT
|
844
|
+
else if (newList->type == GBL_VARIABLE)
|
845
|
+
{ ReplaceGlobalVariable(theEnv,newList); }
|
846
|
+
#endif
|
847
|
+
|
848
|
+
/*====================================================*/
|
849
|
+
/* Return the expression with its variables replaced. */
|
850
|
+
/*====================================================*/
|
851
|
+
|
852
|
+
return(newList);
|
853
|
+
}
|
854
|
+
|
855
|
+
/**********************************************************************/
|
856
|
+
/* GetfieldReplace: Replaces occurences of variables in expressions */
|
857
|
+
/* with function calls that will extract the variable's value */
|
858
|
+
/* given a pointer to the data entity that contains the value (i.e. */
|
859
|
+
/* from information stored in the pattern network). */
|
860
|
+
/**********************************************************************/
|
861
|
+
static struct expr *GetfieldReplace(
|
862
|
+
Environment *theEnv,
|
863
|
+
struct lhsParseNode *nodeList)
|
864
|
+
{
|
865
|
+
struct expr *newList;
|
866
|
+
|
867
|
+
/*====================================*/
|
868
|
+
/* Return NULL for a NULL pointer */
|
869
|
+
/* (i.e. nothing has to be replaced). */
|
870
|
+
/*====================================*/
|
871
|
+
|
872
|
+
if (nodeList == NULL) return NULL;
|
873
|
+
|
874
|
+
/*=====================================================*/
|
875
|
+
/* Create an expression data structure and recursively */
|
876
|
+
/* replace variables in its argument list and next */
|
877
|
+
/* argument links. */
|
878
|
+
/*=====================================================*/
|
879
|
+
|
880
|
+
newList = get_struct(theEnv,expr);
|
881
|
+
newList->type = NodeTypeToType(nodeList);
|
882
|
+
newList->value = nodeList->value;
|
883
|
+
newList->nextArg = GetfieldReplace(theEnv,nodeList->right);
|
884
|
+
newList->argList = GetfieldReplace(theEnv,nodeList->bottom);
|
885
|
+
|
886
|
+
/*=========================================================*/
|
887
|
+
/* If the present node being examined is either a local or */
|
888
|
+
/* global variable, then replace it with a function call */
|
889
|
+
/* that will return the variable's value. */
|
890
|
+
/*=========================================================*/
|
891
|
+
|
892
|
+
if ((nodeList->pnType == SF_VARIABLE_NODE) || (nodeList->pnType == MF_VARIABLE_NODE))
|
893
|
+
{
|
894
|
+
(*nodeList->referringNode->patternType->replaceGetPNValueFunction)
|
895
|
+
(theEnv,newList,nodeList->referringNode);
|
896
|
+
}
|
897
|
+
#if DEFGLOBAL_CONSTRUCT
|
898
|
+
else if (newList->type == GBL_VARIABLE)
|
899
|
+
{ ReplaceGlobalVariable(theEnv,newList); }
|
900
|
+
#endif
|
901
|
+
|
902
|
+
/*====================================================*/
|
903
|
+
/* Return the expression with its variables replaced. */
|
904
|
+
/*====================================================*/
|
905
|
+
|
906
|
+
return(newList);
|
907
|
+
}
|
908
|
+
|
909
|
+
/**************************************************************/
|
910
|
+
/* GenJNVariableComparison: Generates a join network test for */
|
911
|
+
/* comparing two variables found in different patterns. */
|
912
|
+
/**************************************************************/
|
913
|
+
static struct expr *GenJNVariableComparison(
|
914
|
+
Environment *theEnv,
|
915
|
+
struct lhsParseNode *selfNode,
|
916
|
+
struct lhsParseNode *referringNode,
|
917
|
+
bool isNand)
|
918
|
+
{
|
919
|
+
struct expr *top;
|
920
|
+
|
921
|
+
/*========================================================*/
|
922
|
+
/* If either pattern is missing a function for generating */
|
923
|
+
/* the appropriate test, then no test is generated. */
|
924
|
+
/*========================================================*/
|
925
|
+
|
926
|
+
if ((selfNode->patternType->genCompareJNValuesFunction == NULL) ||
|
927
|
+
(referringNode->patternType->genCompareJNValuesFunction == NULL))
|
928
|
+
{ return NULL; }
|
929
|
+
|
930
|
+
/*=====================================================*/
|
931
|
+
/* If both patterns are of the same type, then use the */
|
932
|
+
/* special function for generating the join test. */
|
933
|
+
/*=====================================================*/
|
934
|
+
|
935
|
+
if (selfNode->patternType->genCompareJNValuesFunction ==
|
936
|
+
referringNode->patternType->genCompareJNValuesFunction)
|
937
|
+
|
938
|
+
{
|
939
|
+
return (*selfNode->patternType->genCompareJNValuesFunction)(theEnv,selfNode,
|
940
|
+
referringNode,isNand);
|
941
|
+
}
|
942
|
+
|
943
|
+
/*===========================================================*/
|
944
|
+
/* If the patterns are of different types, then generate a */
|
945
|
+
/* join test by using the eq/neq function with its arguments */
|
946
|
+
/* being function calls to retrieve the appropriate values */
|
947
|
+
/* from the patterns. */
|
948
|
+
/*===========================================================*/
|
949
|
+
|
950
|
+
if (selfNode->negated) top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NEQ);
|
951
|
+
else top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_EQ);
|
952
|
+
|
953
|
+
top->argList = (*selfNode->patternType->genGetJNValueFunction)(theEnv,selfNode,RHS);
|
954
|
+
top->argList->nextArg = (*referringNode->patternType->genGetJNValueFunction)(theEnv,referringNode,LHS);
|
955
|
+
|
956
|
+
return(top);
|
957
|
+
}
|
958
|
+
|
959
|
+
/*************************************************************/
|
960
|
+
/* GenPNVariableComparison: Generates a pattern network test */
|
961
|
+
/* for comparing two variables found in the same pattern. */
|
962
|
+
/*************************************************************/
|
963
|
+
static struct expr *GenPNVariableComparison(
|
964
|
+
Environment *theEnv,
|
965
|
+
struct lhsParseNode *selfNode,
|
966
|
+
struct lhsParseNode *referringNode)
|
967
|
+
{
|
968
|
+
if (selfNode->patternType->genComparePNValuesFunction != NULL)
|
969
|
+
{
|
970
|
+
return (*selfNode->patternType->genComparePNValuesFunction)(theEnv,selfNode,referringNode);
|
971
|
+
}
|
972
|
+
|
973
|
+
return NULL;
|
974
|
+
}
|
975
|
+
|
976
|
+
/************************************************************/
|
977
|
+
/* AllVariablesInPattern: Determines if all of the variable */
|
978
|
+
/* references in a field constraint can be referenced */
|
979
|
+
/* within thepattern in which the field is contained. */
|
980
|
+
/************************************************************/
|
981
|
+
static bool AllVariablesInPattern(
|
982
|
+
struct lhsParseNode *orField,
|
983
|
+
int pattern)
|
984
|
+
{
|
985
|
+
struct lhsParseNode *andField;
|
986
|
+
|
987
|
+
/*=========================================*/
|
988
|
+
/* Loop through each of the | constraints. */
|
989
|
+
/*=========================================*/
|
990
|
+
|
991
|
+
for (;
|
992
|
+
orField != NULL;
|
993
|
+
orField = orField->bottom)
|
994
|
+
{
|
995
|
+
/*=========================================*/
|
996
|
+
/* Loop through each of the & constraints. */
|
997
|
+
/*=========================================*/
|
998
|
+
|
999
|
+
for (andField = orField;
|
1000
|
+
andField != NULL;
|
1001
|
+
andField = andField->right)
|
1002
|
+
{
|
1003
|
+
/*========================================================*/
|
1004
|
+
/* If a variable is found, make sure the pattern in which */
|
1005
|
+
/* the variable was previously bound is the same as the */
|
1006
|
+
/* pattern being checked. */
|
1007
|
+
/*========================================================*/
|
1008
|
+
|
1009
|
+
if ((andField->pnType == SF_VARIABLE_NODE) || (andField->pnType == MF_VARIABLE_NODE))
|
1010
|
+
{ if (andField->referringNode->pattern != pattern) return false; }
|
1011
|
+
|
1012
|
+
/*========================================================*/
|
1013
|
+
/* Check predicate and return value constraints to see */
|
1014
|
+
/* that all variables can be referenced from the pattern. */
|
1015
|
+
/*========================================================*/
|
1016
|
+
|
1017
|
+
else if ((andField->pnType == PREDICATE_CONSTRAINT_NODE) ||
|
1018
|
+
(andField->pnType == RETURN_VALUE_CONSTRAINT_NODE))
|
1019
|
+
{
|
1020
|
+
if (AllVariablesInExpression(andField->expression,pattern) == false)
|
1021
|
+
{ return false; }
|
1022
|
+
}
|
1023
|
+
}
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
/*=====================================*/
|
1027
|
+
/* All variables in the field can be */
|
1028
|
+
/* referenced from within the pattern. */
|
1029
|
+
/*=====================================*/
|
1030
|
+
|
1031
|
+
return true;
|
1032
|
+
}
|
1033
|
+
|
1034
|
+
/**************************************************************************/
|
1035
|
+
/* AllVariablesInExpression: Determines if all of the variable references */
|
1036
|
+
/* in an expression can be referenced within the pattern in which the */
|
1037
|
+
/* expression is contained. */
|
1038
|
+
/**************************************************************************/
|
1039
|
+
static bool AllVariablesInExpression(
|
1040
|
+
struct lhsParseNode *theExpression,
|
1041
|
+
int pattern)
|
1042
|
+
{
|
1043
|
+
/*==========================================*/
|
1044
|
+
/* Check all expressions in the right link. */
|
1045
|
+
/*==========================================*/
|
1046
|
+
|
1047
|
+
for (;
|
1048
|
+
theExpression != NULL;
|
1049
|
+
theExpression = theExpression->right)
|
1050
|
+
{
|
1051
|
+
/*========================================================*/
|
1052
|
+
/* If a variable is found, make sure the pattern in which */
|
1053
|
+
/* the variable is bound is the same as the pattern being */
|
1054
|
+
/* checked. */
|
1055
|
+
/*========================================================*/
|
1056
|
+
|
1057
|
+
if ((theExpression->pnType == SF_VARIABLE_NODE) ||
|
1058
|
+
(theExpression->pnType == MF_VARIABLE_NODE))
|
1059
|
+
{ if (theExpression->referringNode->pattern != pattern) return false; }
|
1060
|
+
|
1061
|
+
/*=======================================================*/
|
1062
|
+
/* Recursively check all expressions in the bottom link. */
|
1063
|
+
/*=======================================================*/
|
1064
|
+
|
1065
|
+
if (AllVariablesInExpression(theExpression->bottom,pattern) == false)
|
1066
|
+
{ return false; }
|
1067
|
+
}
|
1068
|
+
|
1069
|
+
/*========================================*/
|
1070
|
+
/* All variables in the expression can be */
|
1071
|
+
/* referenced from within the pattern. */
|
1072
|
+
/*========================================*/
|
1073
|
+
|
1074
|
+
return true;
|
1075
|
+
}
|
1076
|
+
|
1077
|
+
#endif /* (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT */
|
1078
|
+
|
1079
|
+
|