home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume3 / trc / part3 < prev    next >
Encoding:
Text File  |  1986-11-30  |  45.1 KB  |  1,466 lines

  1. Newsgroups: mod.sources
  2. Subject: TRC - expert system building tool (part 3 of 8)
  3. Approved: jpn@panda.UUCP
  4.  
  5. Mod.sources:  Volume 3, Issue 111
  6. Submitted by: ihnp4!dicomed!ndsuvax!nckary (Daniel D. Kary)
  7.  
  8. This is NOT a shell archive.  Simply delete everything up to and including
  9. the cut mark and save the result as reference.1.doc.
  10.  
  11. Dan Kary
  12. ihnp4!dicomed!ndsuvax!nckary
  13.  
  14. -------------- cut here ---------------
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.                   The TRC Reference Manual
  24.  
  25.  
  26.                        Daniel D. Kary
  27.  
  28.                North Dakota State University
  29.                 Computer Science Department
  30.                       300 Minard Hall
  31.                      Fargo, ND   58102
  32.  
  33.  
  34.                           _A_B_S_T_R_A_C_T
  35.  
  36.  
  37.           The syntax of TRC is formally  defined.   The
  38.      output of TRC is elucidated.
  39.  
  40.  
  41.  
  42.             TABLE OF CONTENTS
  43.  
  44.      PART ONE - INPUT
  45.            1. INTRODUCTION
  46.            2. OVERVIEW
  47.            3. LEXICAL ELEMENTS
  48.            4. DEFINITIONS
  49.            5. SHORT TERM MEMORY
  50.            6. LONG TERM MEMORY
  51.            7. OPTIMIZER
  52.  
  53.      PART TWO - OUTPUT
  54.            8. OVERVIEW
  55.            9. COMMON PROCEDURES
  56.           10. DATA OBJECTS
  57.           11. MANIPULATING THE DATA
  58.           12. TRANSLATING RULES
  59.           13. OPTIONS
  60.  
  61.      APPENDICES
  62.            A. TRC GRAMMAR
  63.            B. ERROR MESSAGES
  64.            C. STYLE NOTES
  65.            D. SAMPLE PROGRAM
  66.  
  67.  
  68. _1.  _I_N_T_R_O_D_U_C_T_I_O_N
  69.  
  70.      TRC is a programming language that is useful for build-
  71. ing expert systems.  It is presumed that the reader is fami-
  72. liar with expert systems in general and has  used  at  least
  73. one expert system building tool.  Some terms that are widely
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.                            - 2 -
  84.  
  85.  
  86. used in describing expert  systems  have  specific  meanings
  87. when used to describe TRC and will be defined now.
  88.  
  89.      The set  of  situation-action  rules  that  embody  the
  90. knowledge  an expert uses to solve a problem are referred to
  91. as Long Term Memory (LTM).  The information  that  may  vary
  92. with  each  instance  of the problem is referred to as Short
  93. Term Memory (STM).  The code which determines if the  situa-
  94. tion part of a rule is true will be called a pattern matcher
  95. or a matcher.  The  code  which  determines  which  rule  to
  96. activate  will  be  called  an inference engine and includes
  97. both the matcher and the LTM.  The input to the TRC compiler
  98. is called a specification.
  99.  
  100.      The input to the TRC compiler is a rule based language.
  101. The  output is a set of C language files.  The procedures in
  102. the C language files output by the TRC compiler collectively
  103. implement  the  inference engine.  An inference engine is to
  104. an expert system as a parser is to a compiler: it is of cen-
  105. tral  importance  but it does not comprise a complete imple-
  106. mentation.  TRC does not provide code for  interaction  with
  107. the  user, but does permit the programmer to easily add this
  108. code.
  109.  
  110.      This document is divided into two parts and  a  set  of
  111. appendices.  The  first part presents a formal definition of
  112. the input language with examples of each  language  feature.
  113. The second part describes the output of the TRC compiler and
  114. includes some important insight on integrating TRC generated
  115. code with other C language code.  The appendices include the
  116. complete TRC grammar, a listing and explanation of  all  the
  117. error  messages that TRC might produce and a sample specifi-
  118. cation.
  119.  
  120.  
  121.                       PART ONE - INPUT
  122.  
  123.  
  124. _2.  _O_V_E_R_V_I_E_W
  125.  
  126.      Every specification file consists of five sections, the
  127. header,  definitions,  short  term  memory (data base), long
  128. term memory (rules) and the  trailer.   These  sections  are
  129. separated  by double percent characters.  The form of a full
  130. specification is illustrated below.   The  header,  STM  and
  131. trailer are optional so the minimum specification would con-
  132. tain only the definitions and LTM.  All of  the  "%%"  marks
  133. must be present in each specification file.
  134.  
  135.  
  136.      header
  137.      %%
  138.      definitions
  139.      %%
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.                            - 3 -
  150.  
  151.  
  152.      STM
  153.      %%
  154.      LTM
  155.      %%
  156.      trailer
  157.  
  158.  
  159.      The purpose of the header and trailer  sections  is  to
  160. permit  the  inclusion  of C language code in the specifica-
  161. tion.  The header and trailer are each composed of a  single
  162. lexical  element called a c-code which is defined in section
  163. 3.  Separate sections are devoted to each of  the  remaining
  164. parts of a TRC specification.
  165.  
  166. _3.  _L_E_X_I_C_A_L _E_L_E_M_E_N_T_S
  167.  
  168.      A program consists of a  single  file.   A  file  is  a
  169. sequence  of lexical elements composed of characters.  Char-
  170. acters may be one of these classes; (1)  upper-case-letters,
  171. (2)  lower-case-letters,  (3) digits, (4) special characters
  172. (5) separators (6) embedded characters and (7) other charac-
  173. ters.
  174.  
  175.      (1) upper-case-letters
  176.           A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
  177.  
  178.      (2) lower-case-letters
  179.           a b c d e f g h i j k l m n o p q r s t u v w x y z
  180.  
  181.      (3) digits
  182.           0 1 2 3 4 5 6 7 8 9
  183.  
  184.      (4) special characters
  185.           " ( ) : ; = < > ! ^ _ $ . { } / * %
  186.  
  187.      (5) separators
  188.           space tab newline
  189.  
  190.      (6) embedded characters
  191.           \n   embedded-newline
  192.           \t   embedded-tab
  193.           \b   embedded-backspace
  194.           \r   embedded-carriage-return
  195.           \f   embedded-form-feed
  196.           \\   embedded-back-slash
  197.           \"   embedded-quote
  198.  
  199.      (7) other characters
  200.           @ # & + [ ] ` ~ ' | , ?
  201.  
  202. The following names are used when referring to special characters:
  203.  
  204.      Symbol    Name      Symbol    Name
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.                            - 4 -
  216.  
  217.  
  218.      "    quote               :    colon
  219.      ;    semicolon      =    equal
  220.      !    exclamation         ^    hat
  221.      _    underscore          $    dollar
  222.      <    less-than      >    greater-than
  223.      (    left-paren          )    right-paren
  224.      {    left-bracket        }    right-bracket
  225.      *    asterisk       %    percent
  226.      -    minus
  227.  
  228.  
  229.      A lexical element is a either a delimiter, an  identif-
  230. ier,  an integer literal, a floating point literal, a string
  231. literal, a comment or a c_code.  In some cases  a  separator
  232. is  required  between  lexical  elements,  specifically when
  233. adjacent lexical elements could be interpreted as  a  single
  234. lexical  element.   A separator is any of space, tab or new-
  235. line.  One or more separators are permitted between any  two
  236. lexical  element, before the first lexical element and after
  237. the last lexical element.
  238.  
  239. _3._1.  _D_E_L_I_M_I_T_E_R_S
  240.  
  241.      A delimiter may be one of the following special charac-
  242. ters:
  243.  
  244.      : ; " . ^ - ( ) { } < >
  245.  
  246.      A delimiter may be one of the following compound delim-
  247. iters.  Each  compound delimiter is composed of two adjacent
  248. special characters.
  249.  
  250.      => %% != == >= <=
  251.  
  252.      The following names are used when referring to compound
  253. delimiters:
  254.  
  255.      Delimiter Name
  256.  
  257.      =>        arrow
  258.      %%        delim
  259.      !=        not-equal
  260.      ==        equality
  261.      >=        greater-than-or-equal
  262.      >=        less-than-or-equal
  263.  
  264. _3._2.  _I_D_E_N_T_I_F_I_E_R_S
  265.  
  266.      Identifiers are used as tokens and as  reserved  words.
  267. Separators are not allowed in an identifier.  The underscore
  268. character is the only special character that may be part  of
  269. an identifier.
  270.  
  271.      identifier  ::=  letter { underscore | letter | digit}
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.                            - 5 -
  282.  
  283.  
  284.      letter      ::=  upper-case-letter | lower-case-letter
  285.  
  286. Examples:
  287.  
  288.      PENNY          Get_Stuff x1
  289.      ThisOne        WrZ_123        etc_
  290.  
  291. The identifiers that are reserved words are:
  292.  
  293.      ADD            MARK      PROFILE
  294.      BACKTRACK NORECURS  RECURS
  295.      DUMP      NOT            SAVE
  296.      EMPTY          OPTIMIZE       STRING
  297.      FLOAT          POINTER        TRACE
  298.      INT            PREFIX         ZERO
  299.  
  300. _3._3.  _N_U_M_E_R_I_C _L_I_T_E_R_A_L_S
  301.  
  302.      There are two  classes  of  numeric  literals,  integer
  303. literals  and  floating  point  literals.  The presence of a
  304. decimal point distinguishes  floating  point  literals  from
  305. integer literals.
  306.  
  307.      floating-point-literal  ::=  [ minus ] digits dot digits
  308.      integer-literal             ::=  [ minus ] digits
  309.      digits              ::=  digit { digit }
  310.  
  311. Example integer literals:
  312.  
  313.      1   -33   187
  314.  
  315. Example floating point literals:
  316.  
  317.      0.5   -3.14159    6.0
  318.  
  319. _3._4.  _S_T_R_I_N_G _L_I_T_E_R_A_L_S
  320.  
  321.      A string literal is formed by a sequence of  characters
  322. (possibly  zero)  enclosed between quote characters.  Any of
  323. the six classes of characters may be embedded in a string.
  324.  
  325.      string-literal  ::=  quote { [ character ] } quote
  326.  
  327. Examples:
  328.      ""
  329.      "\"recursion\""
  330.      "these characters can be in a string $, ! => etc_\n"
  331.  
  332. _3._5.  _C_O_M_M_E_N_T_S
  333.  
  334.      Comments may be included anywhere  in  the  input  file
  335. that  separators  or  delimiters may occur.  Comments follow
  336. the style of comments in the C language.  Comments  may  not
  337. be  nested  within  comments.   Any  of  the  six classes of
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.                            - 6 -
  348.  
  349.  
  350. characters may be embedded in a comment.
  351.  
  352. comment  ::= slash asterisk { [ character ] } asterisk slash
  353.  
  354. Examples:
  355.      /*  a simple comment */
  356.  
  357.      /*
  358.        a multi-line
  359.        comment
  360.      */
  361.  
  362.      /*******************
  363.       * A Fancy Comment *
  364.       *******************/
  365.  
  366. _3._6.  _C__C_O_D_E
  367.  
  368.      A c_code is a fragment  of  C  language  code  that  is
  369. embedded  in  the input file.  A c_code is recognized by the
  370. scanner as a single lexical item.  The C language itself  is
  371. not  parsed by TRC.  A c-code may not contain a procedure or
  372. function.
  373.  
  374. c_code   ::=  left-bracket { [character] | [c_code] } right-bracket
  375.  
  376. Example:
  377.  
  378.      {
  379.           if(condition){
  380.                action(argument);
  381.                another_action();
  382.           }
  383.      }
  384.  
  385. _4.  _D_E_F_I_N_I_T_I_O_N_S
  386.  
  387.      Each entity that can be referred to by a TRC rule  must
  388. be  defined  in the definition section.  Each entity that is
  389. defined is called an _o_b_j_e_c_t.  Objects may  have  numeric  or
  390. string values associated with them.  These associated values
  391. are called _e_l_e_m_e_n_t_s of the object.  There are two  forms  of
  392. definitions.   There is a simple form for objects which have
  393. no elements and an extended form for objects that have asso-
  394. ciated elements.
  395.  
  396.      definition  ::=  identifier
  397.      definition  ::=  identifier left-paren item-list right-paren
  398.      item-list   ::=  { [ item ] }
  399.      item        ::=  identifier colon type
  400.      type     ::=  INT | FLOAT | STRING | POINTER
  401.  
  402.      For each object there  will  be  an  associated  object
  403. count  in  the  output  code, which represents the number of
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.                            - 7 -
  414.  
  415.  
  416. objects of that type that exist at any point in  time.   For
  417. each  object  with  at  least  one element, there will be an
  418. associated structure and list of objects of that type in the
  419. output  code.  The  set  of  object  counts and object lists
  420. defined in the definition section represent the STM that the
  421. system of rules may refer to.
  422.  
  423.      Each element that is defined for a  given  object  must
  424. have  a  data  type  specified.   Strong  type  checking  is
  425. enforced throughout TRC.   Comparisons  and  assignments  of
  426. elements must involve elements or literals of the same type.
  427. There is no coercion of types.  The INT, FLOAT,  STRING  and
  428. POINTER types are described in section 10.  The POINTER type
  429. is a pointer to a structure of the type of the  object  that
  430. contains it.
  431.  
  432. Examples:
  433.  
  434.      A
  435.      b_b (This : INT)
  436.      CAST ( THAT      : INT
  437.             The_Other : FLOAT)
  438.  
  439. _5.  _S_H_O_R_T _T_E_R_M _M_E_M_O_R_Y
  440.  
  441.      The short term memory (stm) section  of  the  input  is
  442. where  the initial state of the working memory is specified.
  443. The intention of this  section  is  to  permit  the  working
  444. memory  to be initialized to some state that may be required
  445. for each invocation  of  the  expert  system.   It  is  also
  446. intended  to  serve as a way of entering test data while the
  447. expert system is being developed,  before  data  entry  pro-
  448. cedures are developed.
  449.  
  450.      stm        ::=  { [ entry ] }
  451.      entry      ::=  [ integer-literal ] identifier
  452.      entry      ::=  [ integer-literal ] identifier
  453.                left-paren { [ init-item ] } right-paren
  454.      init-item  ::=  identifier arrow value
  455.      value      ::=  integer-literal
  456.      value      ::=  floating-point-literal
  457.      value      ::=  string-literal
  458.  
  459.      The short term memory section is a list of objects that
  460. are to be entered into the working memory.  If an object has
  461. one or more elements, those elements can be  initialized  to
  462. user  specified  values.  Numeric values that are not speci-
  463. fied are initialized to zero and string values that are  not
  464. specified  are initialized to an empty string.  The integer-
  465. literal that may precede the name (identifier) of the object
  466. specifies  how  many objects of that type are to be added to
  467. working memory with the given element values, e.g.:
  468.  
  469.                       /* definition part */
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.                            - 8 -
  480.  
  481.  
  482.      A (A1 : STRING
  483.         A2 : FLOAT)
  484.      B (B1 : STRING
  485.         B2 : FLOAT)
  486.      %%
  487.                       /* short term memory */
  488.        A ( A1 => "string")  /* It is not necessary to
  489.                             initialize all the elements
  490.                       in an object.
  491.                       */
  492.      2 A ( A2 => 3.34
  493.            A1 => "thing")   /* Nor is it necessary to
  494.                       initialize elements in the
  495.                       order they were declared.
  496.                       */
  497.      3 B              /* It is not necessary to
  498.                       initialize the elements
  499.                       at all.
  500.                       */
  501.      %%
  502.  
  503.  
  504.  
  505.  
  506. _6.  _L_O_N_G _T_E_R_M _M_E_M_O_R_Y
  507.  
  508.      Long   term   memory   is   the   section   where   the
  509. situation/action  rules  are  enumerated.   This section may
  510. begin with a listing of options that are to  be  turned  on.
  511. All options in this section can also be specified by command
  512. line flags.  Since the syntax for the long term memory  sec-
  513. tion is more complex than for the other sections, it will be
  514. presented in several parts.
  515.  
  516. _6._1.  _O_P_T_I_O_N_S
  517.  
  518.      The long term memory is composed of two  sections,  the
  519. options and the rules.
  520.  
  521.      ltm     ::=  { [option] } { rule }
  522.      option  ::=  ZERO  |  PROFILE  |  BACKTRACK
  523.             |  DUMP  |  RECURS  |  NORECURS
  524.             |  SAVE  |  TRACE  |  PREFIX identifier
  525.  
  526. _6._1._1.  _Z_E_R_O
  527.  
  528.      The ZERO option directs the compiler to generate a pro-
  529. cedure  that  will free all the dynamic structures allocated
  530. by TRC generated code.  This feature is useful when develop-
  531. ing  inference  engines that will be entered more than once.
  532. It is often necessary to remove the 'leftovers' from a  pre-
  533. vious execution before beginning a new execution.
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.                            - 9 -
  546.  
  547.  
  548. _6._1._2.  _P_R_O_F_I_L_E
  549.  
  550.      The PROFILE option directs  the  compiler  to  generate
  551. code  to profile the execution of the inference engine and a
  552. procedure to print a summary of that profile.  The profiling
  553. code counts the number of times that each rule searches some
  554. part of STM and how many times each rule is fired.
  555.  
  556. _6._1._3.  _B_A_C_K_T_R_A_C_K
  557.  
  558.      The BACKTRACK option directs the compiler  to  generate
  559. an  inference  engine  that  will  backtrack when no rule is
  560. true.  Backtracking is accomplished by undoing  the  actions
  561. of  the last rule that fired and continuing to test rules as
  562. if the undone rule had never fired.
  563.  
  564. _6._1._4.  _D_U_M_P
  565.  
  566.      The DUMP option directs the compiler to  generate  pro-
  567. cedures  that will print the contents of STM on the standard
  568. output.  The intention of this option  is  to  simplify  the
  569. process  of  developing  and debugging rules.  By having the
  570. DUMP  procedures  generated  automatically,  the   knowledge
  571. engineer  is freed of the mundane task of writing procedures
  572. to display the current state of  the  STM.   The  DUMP  pro-
  573. cedures are not intended to serve as the output of an expert
  574. system.   Appropriate  output  routines  will  have  to   be
  575. developed  by  the  knowledge  engineer after the rules have
  576. been written.
  577.  
  578. _6._1._5.  _R_E_C_U_R_S
  579.  
  580.      TRC will generate code that uses one of two  strategies
  581. for  searching  STM.   These strategies (detailed in section
  582. 6.3.3) are called LINEAR and RECURSIVE.  The LINEAR strategy
  583. is  the  default.   The  RECURS directive in the option part
  584. directs the compiler to use the RECURSIVE  strategy  as  the
  585. default.   It  is  possible to override the default on a per
  586. rule basis.  Overriding the default is discussed in  section
  587. 6.3.3.
  588.  
  589. _6._1._6.  _N_O_R_E_C_U_R_S
  590.  
  591.      The NORECURS option directs the  compiler  to  use  the
  592. LINEAR  search  strategy  in  all  rules,  unless  otherwise
  593. directed.  Since this is the default condition,  it  is  not
  594. necessary to use this option.
  595.  
  596. _6._1._7.  _S_A_V_E
  597.  
  598.      The SAVE option directs the compiler to  generate  pro-
  599. cedures  to save all objects which are dynamically allocated
  600. by TRC code on a file.  The compiler will also generate pro-
  601. cedures   which   can   restore  the  dynamically  allocated
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.                            - 10 -
  612.  
  613.  
  614. structures from the previously written files.  The intention
  615. of this option is to simplify the development of expert sys-
  616. tems with checkpointing and  restarting  capabilities.   The
  617. procedures  generated  by  this  option and the use of those
  618. procedures is described in section 13.6 and Appendix C.
  619.  
  620. _6._1._8.  _T_R_A_C_E
  621.  
  622.      The TRACE option directs the compiler to trace the exe-
  623. cution  of the inference engine by maintaining a list of the
  624. rules that have been fired in the  order  they  were  fired.
  625. This  list  can  be  used  to produce an explaination of the
  626. actions taken by the expert system.
  627.  
  628. _6._1._9.  _P_R_E_F_I_X
  629.  
  630.      The PREFIX option directs the compiler to use the iden-
  631. tifier  that  follows the reserved word 'PREFIX' as a prefix
  632. for all data objects and procedures generated by  TRC.   The
  633. intention  of  this  option is to facilitate building expert
  634. systems that have more than one inference engine.  Supplying
  635. different  prefixes  for  each inference engine insures that
  636. there will be no name conflicts between  separate  inference
  637. engines, e.g.:
  638.  
  639.      PREFIX X_
  640.  
  641.  
  642. _6._2.  _R_U_L_E_S
  643.  
  644.      The second section if LTM is the list of  rules.   Each
  645. rule  has  a  label,  which can be supplied or automatically
  646. generated by TRC.  The label is used whenever it  is  neces-
  647. sary  or convenient to refer to the rule by name.  The label
  648. is followed by the situation part  (described  in  the  next
  649. section).   The  situation part is a list of statements fol-
  650. lowed by the arrow delimiter.  The action part (described in
  651. the section following the description of the situation part)
  652. follows the arrow delimiter and is itself a list  of  state-
  653. ments.   The  action  part  is followed by a semicolon which
  654. terminates the rule.
  655.  
  656.      rule   ::=  label situation arrow action semicolon
  657.      label  ::=  identifier colon  |  colon
  658.  
  659. _6._3.  _S_I_T_U_A_T_I_O_N
  660.  
  661.      The situation part specifies how STM is to be  searched
  662. and what must be present in STM for the situation part to be
  663. true.
  664.  
  665.  
  666.      situation   ::=  { [ s-option ] } { [ match ] }
  667.      s-option    ::=  EMPTY identifier identifier
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.                            - 11 -
  678.  
  679.  
  680.      s-option    ::=  RECURS  |  NORECURS
  681.      match       ::=  [ integer-literal ] identifier
  682.      match       ::=  NOT identifier
  683.      match       ::=  [ integer-literal ] left-paren name
  684.                 match-list right-paren
  685.      match       ::=  c-code
  686.      name     ::=  hat identifier identifier
  687.      match-list  ::=  { match-item }
  688.      match-item  ::=  identifier dot identifier relop literal
  689.      match-item  ::=  identifier dot identifier relop
  690.                       identifier dot identifier
  691.      relop       ::=  equality  |  not-equal  |  less-than
  692.      relop       ::=  greater-than  |  greater-than-or-equal
  693.      relop       ::=  less-than-or-equal
  694.  
  695. _6._3._1.  _M_A_T_C_H_I_N_G
  696.  
  697.      It is necessary to understand how matching is specified
  698. before  the  s-option part can be explained.  A match, which
  699. will also be referred to as a test, is a statement  of  what
  700. the  inference  engine  is to search for in STM.  Assume the
  701. following objects were defined in the definition section:
  702.  
  703.      %%
  704.      A (A1 : INT
  705.         A3 : INT
  706.         A2 : STRING)
  707.      B (B1 : INT
  708.         B2 : STRING)
  709.      %%
  710.  
  711.      The simplest match specifies only the object that  must
  712. be  present.   A  search  for  one  object of type A and one
  713. object of type B can be specified as follows:
  714.  
  715.      A  B
  716.  
  717.      A search for two objects of type A and two  objects  of
  718. type  B  can be specified in many ways, including these four
  719. equivalent ways:
  720.  
  721.           A A B B
  722.  
  723.           2A 2 B
  724.  
  725.           A B A B
  726.  
  727.           A A 2B
  728.  
  729.      The objects can be listed in any order and may be  pre-
  730. ceded  by  an integer literal.  The integer literal specifys
  731. how many objects of the named type are to be search for.  In
  732. one  of  the examples there is a space between the count and
  733. the object name and in other  examples  there  is  no  space
  734.  
  735.  
  736.  
  737.  
  738.  
  739.  
  740.  
  741.  
  742.  
  743.                            - 12 -
  744.  
  745.  
  746. between  the count and the object.  Spaces are required only
  747. when there would be a conflict without a space.   Since  the
  748. string  "2A"  (for  example)  begins  with  a  digit,  it is
  749. presumed to be a numeric literal.  Since "A" is not a digit,
  750. the  numeric  literal ends at that point.  Since the numeric
  751. literal contained  no  decimal  point,  it  is  an  integer-
  752. literal.  The string is therefore lexically equivalent to "2
  753. A".
  754.  
  755.      The reserved word NOT is used to explicitly test for an
  756. empty  list.   The following match statement will be true if
  757. there are no objects of type A in STM:
  758.  
  759.      NOT A
  760.  
  761.      Any rule which contains a search for an  object  and  a
  762. test  for that same list being empty can never be true.  TRC
  763. generates an error message in this  situation  because  even
  764. though  it  is syntactically correct, it is in fact meaning-
  765. less, e.g.:
  766.  
  767.      A
  768.      NOT A
  769.  
  770.      Very often it is necessary to search STM based not only
  771. on  the  type of object, but also based on the values of the
  772. elements of the object.  This is specified by placing a list
  773. of the element values after the element name.
  774.  
  775.      (A.A1 == 2)
  776.      (B.B1 != 3
  777.       B.B2 <= "THIS")
  778.      (A.A2 == "HERE"  A.A1 > 6)
  779.  
  780.      These three statements can be  translated  as  follows:
  781. First  search  the  A list for an object whose element A1 is
  782. equal to two, then search the B list  for  an  object  whose
  783. element  B1  is  not  equal to three and whose element B2 is
  784. less than or equal to "THIS", finally search the A list  for
  785. an object whose element A2 is equal to "HERE" and whose ele-
  786. ment A1 is greater than six.  This situation part  would  be
  787. true  if  all  three objects were found in STM, otherwise it
  788. would be false.  In the first match only the value of A1  is
  789. specified.  Only the elements that are specified are tested,
  790. the values of any other elements that the object may contain
  791. are  not  considered.  Association of parameters is by name,
  792. so it is not necessary to list elements in  the  order  they
  793. were  declared.   The  third  match statement in the example
  794. above lists the value of element A2 first, even though  ele-
  795. ment A1 was declared first.
  796.  
  797.      The final case that must  be  considered  is  the  case
  798. where it is necessary to search STM for an object whose ele-
  799. ments are to be tested against the result of  some  previous
  800.  
  801.  
  802.  
  803.  
  804.  
  805.  
  806.  
  807.  
  808.  
  809.                            - 13 -
  810.  
  811.  
  812. search.  To do this it is first necessary to name the object
  813. that is being searched for so that it may later be  referred
  814. to, e.g.:
  815.  
  816.      (^A FIRST
  817.        A.A1 == 2)
  818.      (B.B1 == FIRST.A3)
  819.      (A.A1 != A.A3)
  820.  
  821.      The first statement begins with a hat character.   This
  822. indicates  that this object is to be named.  The hat charac-
  823. ter is followed by the object type and it's name.  The  name
  824. is followed by a list of the elements to search for, in this
  825. case a search for element A1  equal  to  two  is  specified.
  826. This  statement  can  be translated as follows: Search the A
  827. list for an object whose element A1 is equal to two and name
  828. that  object "FIRST". A name that is applied to an object is
  829. called a free variable.  The scope of a free variable is the
  830. current  rule.   Free variable names can be reused in subse-
  831. quent rules.
  832.  
  833.      The second statement specifys that the B list is to  be
  834. searched for an element B1 whose value is equal to the value
  835. of the element A3 found in the previous statement.  The free
  836. variable name makes it possible to refer to previously found
  837. elements.
  838.  
  839.      The third statement, while looking innocent enough,  is
  840. radically  different from all previous examples.  In all the
  841. previous examples the exact value that  was  being  searched
  842. for  was  known  before  the  search  began.  That value was
  843. expressed as either a literal, or the value of some  element
  844. that  was found in a previous test.  In the third statement,
  845. the A list is being searched for an object whose elements A1
  846. and  A3 are not equal to one another.  The values these ele-
  847. ments are to have are not specified, only their relationship
  848. to one another.  This can be further complicated:
  849.  
  850.      (^A Second
  851.        A.A1 == 3)
  852.      (A.A1 < Second.A3
  853.       A.A3 < A.A1)
  854.  
  855.      In the second match statement of  this  example  A1  is
  856. being  compared  to  the  value  of  A3  in the object named
  857. "Second" and it is being compared to the value of  the  ele-
  858. ment  A3  in  the  object  that contains it.  An element may
  859. appear on the left hand side of the relational operator only
  860. once in a given match statement.  It is now possible to con-
  861. sider the effects of the options.
  862.  
  863.  
  864.  
  865.  
  866.  
  867.  
  868.  
  869.  
  870.  
  871.  
  872.  
  873.  
  874.  
  875.                            - 14 -
  876.  
  877.  
  878. _6._3._2.  _O_P_T_I_O_N_S
  879.  
  880.      The situation part begins with a (possibly empty)  list
  881. of  options.   The  reserved  words  RECURS  or NORECURS may
  882. appear in the option part of the situation.  The  appearance
  883. of  one  of these words causes the named strategy to be used
  884. rather than the current default strategy. It is not an error
  885. to  explicitly  specify  the  default  strategy,  but  it is
  886. unnecessary.  The option part  of  the  situation  may  also
  887. include  EMPTY  statements.   An EMPTY statement is a static
  888. object declaration.  The intention of the EMPTY statement is
  889. to  provide  a means of passing data from STM to embedded c-
  890. code and from embedded c-code to STM.  Examples  in  section
  891. 12 will illustrate these actions.
  892.  
  893. _6._3._3.  _S_E_A_R_C_H _S_T_R_A_T_E_G_I_E_S
  894.  
  895.      A small example provides an easy way to illustrate  the
  896. two  search  strategys.   This  example  is  a  complete TRC
  897. specification, though not useful for anything other than  as
  898. an example.
  899.  
  900.      %%
  901.      PENNY (MINT : STRING  DATE : INT)
  902.      %%
  903.      PENNY (MINT => "DENVER"
  904.             DATE => 1964)
  905.      PENNY (DATE => 1966)
  906.      %%
  907.      R1:
  908.           (^PENNY First)
  909.           (PENNY.DATE <= First.DATE)
  910.           =>
  911.           MARK PENNY
  912.           ;
  913.      %%
  914.  
  915.      STM will be initialized to contain two objects of  type
  916. PENNY, the first minted in Denver in 1964, the second minted
  917. in an unspecified location in 1966.  Since the reserved word
  918. RECURS does not appear in either option section, the default
  919. LINEAR search strategy will be used.
  920.  
  921.      In the LINEAR strategy, STM is  searched  in  a  linear
  922. fashion  for  each  object  specified in the situation part.
  923. Objects are searched for in the order they are  listed.   In
  924. this  example,  the  object named "First" will be associated
  925. with the first object in the list.  Since the values of  the
  926. elements  are  not  specified, any object of type PENNY will
  927. match.  This object is then temporarily marked as being  "in
  928. use" and can not be used to match any subsequent tests.  The
  929. list will then be searched for an object of type PENNY whose
  930. DATE  element  is  less than or equal to the DATE element of
  931. the "First" object.  The only other object in the list has a
  932.  
  933.  
  934.  
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.                            - 15 -
  942.  
  943.  
  944. DATE  element  of  1966  which  is not less than or equal to
  945. 1964, so the rule fails.  In the LINEAR strategy,  when  any
  946. test  in  the  situation  part  fails, the entire rule fails
  947. immediately, no further tests are made.
  948.  
  949.      It should be obvious that this  rule  would  have  been
  950. true  if  "First" had been associated with the second object
  951. in the PENNY list.  This is precisely  the  purpose  of  the
  952. RECURSIVE  search  strategy.   In the RECURSIVE search stra-
  953. tegy, when a test fails, the previous test  is  redone.   To
  954. redo  a  test,  the  object  that  was marked as "in use" is
  955. unmarked, and the list is searched from that  point  for  an
  956. object that will match the test.  The RECURSIVE search fails
  957. when a single test fails and it is  no  longer  possible  to
  958. undo  the previous test (this occurs when there is no previ-
  959. ous test).  The RECURSIVE search strategy is a powerful pat-
  960. tern matching tool, but it can be expensive in terms of exe-
  961. cution time.
  962.  
  963. _6._3._4.  _E_M_B_E_D_D_E_D _C_O_D_E
  964.  
  965.      Arbitrary C language code may be embedded in the situa-
  966. tion  part anywhere a match may occur.  Recall that embedded
  967. code (c-code) is recognized as a single lexical  element  by
  968. the  scanner,  the  C  language itself is not parsed by TRC.
  969. Errors in embedded code will not be detected  by  TRC.   The
  970. intention  of permitting embedded code in the situation part
  971. is to make it possible to include tests that may not fit the
  972. context of a match against STM.
  973.  
  974.      In order to integrate an embedded code  test  with  the
  975. existing  match statements, it is necessary to have a way to
  976. refer to objects in embedded code.  In  order  for  embedded
  977. code to have the same functionality as a match statement, it
  978. is necessary to have a way to cause a rule to  fail  in  the
  979. embedded code.  Each of these facilities are provided.
  980.  
  981. _6._3._5.  _E_M_P_T_Y _O_B_J_E_C_T_S
  982.  
  983.      The purpose of the EMPTY statement is to create a named
  984. object  that  can  be  referred  to  by match statements and
  985. embedded code, without having to exist in STM.  One  of  the
  986. capabilities  that  results  is  the  ability  to  have  STM
  987. searched on the basis of the result of  some  external  pro-
  988. cedure, e.g.:
  989.  
  990.      R1:
  991.      EMPTY PENNY SPARE   /* this creates an object of
  992.                        type PENNY that is named
  993.                        SPARE.  This object exists
  994.                        separately from STM and it's
  995.                        elements are not initialized. */
  996.          {
  997.           /* this embedded C code precedes
  998.  
  999.  
  1000.  
  1001.  
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007.                            - 16 -
  1008.  
  1009.  
  1010.              any search of STM
  1011.           */
  1012.           if(($SPARE.DATE = external-procedure()) <= 1920){
  1013.               $FAIL.
  1014.           }
  1015.          }
  1016.          (PENNY.DATE == SPARE.DATE)
  1017.          =>
  1018.          MARK PENNY
  1019.          ;
  1020.  
  1021.      Several things are happening in this example.  First an
  1022. object  of  type  PENNY is created and given the name SPARE.
  1023. This object exists separately from STM and will  exist  only
  1024. during  the  current  rule.   It is useful only as something
  1025. that can be referred to in other statements.  A  section  of
  1026. embedded  code  precedes  the  only  match statement in this
  1027. rule.  When the code produced by TRC is  compiled  and  run,
  1028. that  embedded code will be executed before STM is searched,
  1029. by virtue of the fact that it precedes the match statement.
  1030.  
  1031.      The embedded code contains an "if" statement which con-
  1032. tains  an  embedded  assignment and function call as part of
  1033. it's condition.  The left-hand-side of the embedded  assign-
  1034. ment,  "$SPARE.DATE" is not syntactically correct C language
  1035. code.  The dollar character is a flag to TRC that  indicates
  1036. a  reference to a named object.  The identifier that follows
  1037. the dollar character will be translated by  TRC  during  the
  1038. output  phase.  This translation is described in section 12.
  1039. The statement "$FAIL." is translated by  TRC  into  whatever
  1040. statements are required to make this rule fail.  The defini-
  1041. tion of failure depends on  the  search  strategy.   If  the
  1042. LINEAR  strategy is being used, "$FAIL." will cause the rule
  1043. to stop searching STM and continue with the next  rule.   If
  1044. the  RECURSIVE  strategy  is being used, "$FAIL." will cause
  1045. the rule to undo and then redo the previous match statement.
  1046.  
  1047.      An object name preceded by  the  dollar  character  may
  1048. occur  in  the  embedded  code  anywhere a variable name may
  1049. occur, since that is what it will actually be translated to.
  1050. Embedded  code  may  also refer to objects that exist in STM
  1051. using the same dollar character translation technique:
  1052.  
  1053.      R1:
  1054.      RECURS
  1055.           (^PENNY NEW
  1056.             PENNY.MINT == "DENVER)
  1057.           {
  1058.                if(some-function($NEW.DATE))
  1059.                 $FAIL.
  1060.                else
  1061.                 $NEW.DATE = 0;
  1062.           }
  1063.           (PENNY.DATE == 1921)
  1064.  
  1065.  
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071.  
  1072.  
  1073.                            - 17 -
  1074.  
  1075.  
  1076.           =>
  1077.           MARK PENNY
  1078.           ;
  1079.  
  1080.      The "else" part of the  embedded  code  illustrates  an
  1081. assignment  to  an  element  of  the  object named NEW.  The
  1082. object that is being called  NEW  exists  in  STM  and  this
  1083. assignment  to  it's  DATE element is permanent.  Since this
  1084. rule is recursive, it is possible that  this  embedded  code
  1085. will  set the DATE element of every object in the PENNY list
  1086. to zero.  These modifications are made  before  it  is  even
  1087. known that the situation part is true.  Modifying STM in the
  1088. situation part of a rule would be  a  major  departure  from
  1089. traditional expert system implementation techniques.  Furth-
  1090. ermore, the BACKTRACKing option is unaware of  changes  made
  1091. in  STM by embedded code.  The BACKTRACKing option is unable
  1092. to correctly undo this rule.
  1093.  
  1094. _6._4.  _A_C_T_I_O_N
  1095.  
  1096.      The ACTION part specifies what is to  be  done  if  the
  1097. situation  part is true.  The actions that can be taken pri-
  1098. marily involve adding objects to  STM  or  deleting  objects
  1099. from  STM.  Recall that the non-terminal 'entry' was defined
  1100. in section 4.
  1101.  
  1102.      action      ::=  statements c-code
  1103.      statements  ::=  { [statement] }
  1104.      statement   ::=  MARK mark-list
  1105.      statement   ::=  ADD  add-list
  1106.      statement   ::=  OPTIMIZE identifier
  1107.      mark-list   ::=  { [ mark-item ] }
  1108.      mark-item   ::=  [ integer-literal ] identifier
  1109.      add-list    ::=  { [ entry ] }
  1110.  
  1111. _6._4._1.  _M_A_R_K
  1112.  
  1113.      The MARK statement is used to delete objects from  STM.
  1114. Only  objects  that  were found in the situation part may be
  1115. deleted.  The reason for this constraint is  that  only  the
  1116. objects  found in the situation part are definitely known to
  1117. exist in STM.  STM is searched only in the  situation  part,
  1118. there  is  no  searching in the action part.  Objects may be
  1119. deleted by name or in the order they were found, e.g. (using
  1120. the definitions from section 6.3.1):
  1121.  
  1122.      R1:
  1123.           (A.A1 != A.A3)
  1124.           (^A FIRST
  1125.             A.A1 == 2)
  1126.           (B.B1 == FIRST.A3)
  1127.           =>
  1128.           MARK A
  1129.           ;
  1130.  
  1131.  
  1132.  
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.                            - 18 -
  1140.  
  1141.  
  1142.      This MARK statement will delete the  object  in  the  A
  1143. list that met the test (A.A1 != A.A3).  In some instances it
  1144. may be desirable to delete an object that was not the  first
  1145. object that was found, e.g.:
  1146.  
  1147.      R1:
  1148.           (A.A1 != A.A3)
  1149.           (^A FIRST
  1150.             A.A1 == 2)
  1151.           (B.B1 == FIRST.A3)
  1152.           =>
  1153.           MARK FIRST
  1154.           ;
  1155.  
  1156.      The A list object named 'FIRST' is the second object of
  1157. type A to be found.  It is specified as the object to delete
  1158. by using it's free variable  name.   A  MARK  statement  can
  1159. specify  a  count of how many objects of a given type are to
  1160. be deleted.  A MARK statement may list any number of objects
  1161. to delete, and each object to be deleted can have a separate
  1162. MARK statement if desired.  In no case can more  objects  be
  1163. deleted  than were found in the situation part.  Each of the
  1164. following examples is equivalent:
  1165.  
  1166.      R1:
  1167.           (A.A1 != A.A3)
  1168.           (^A FIRST
  1169.             A.A1 == 2)
  1170.           (B.B1 == FIRST.A3)
  1171.           =>
  1172.           MARK B FIRST A
  1173.           ;
  1174.  
  1175.      R1:
  1176.           (A.A1 != A.A3)
  1177.           (^A FIRST
  1178.             A.A1 == 2)
  1179.           (B.B1 == FIRST.A3)
  1180.           =>
  1181.           MARK 2A
  1182.           MARK B
  1183.           ;
  1184.  
  1185.      R1:
  1186.           (A.A1 != A.A3)
  1187.           (^A FIRST
  1188.             A.A1 == 2)
  1189.           (B.B1 == FIRST.A3)
  1190.           =>
  1191.           MARK FIRST
  1192.           MARK A
  1193.           MARK B
  1194.           ;
  1195.  
  1196.  
  1197.  
  1198.  
  1199.  
  1200.  
  1201.  
  1202.  
  1203.  
  1204.  
  1205.                            - 19 -
  1206.  
  1207.  
  1208. _6._4._2.  _A_D_D
  1209.  
  1210.      The ADD statement is used to add new  objects  to  STM.
  1211. As  in  the MARK statement, an ADD statement can specify one
  1212. or several objects to add to STM.  The value of each element
  1213. of each object can be specified as in the STM section of the
  1214. specification.  Each object is inserted at the head  of  the
  1215. appropriate  list.   The insertions are actually made in the
  1216. opposite order that they are listed, the net effect is  that
  1217. the objects appear at the head of the list in the order they
  1218. are specified.  ADD and MARK statements may be intermixed in
  1219. any order, e.g.:
  1220.  
  1221.      R1:
  1222.           (A.A1 != A.A3)
  1223.           (^A FIRST
  1224.             A.A1 == 2)
  1225.           (B.B1 == FIRST.A3)
  1226.           =>
  1227.           MARK FIRST
  1228.           ADD A (A.A1 => 6
  1229.                  A.A3 => FIRST.A3)
  1230.           ADD B (B.B2 => FIRST.A2
  1231.                  B.B1 => 9)
  1232.           MARK B
  1233.           ;
  1234.  
  1235.      All the ADD statements will be executed before any MARK
  1236. statements  are  executed  regardless  of  the  order of the
  1237. statements in the action part.  The statements  are  ordered
  1238. by  the  compiler  to  insure that an ADD statement does not
  1239. refer to an object that has already  been  MARKed.   In  the
  1240. example  above, the first ADD statement refers to the object
  1241. named 'FIRST'.  The object named 'FIRST' is  MARKed  in  the
  1242. previous statement.  If the code were executed in the speci-
  1243. fied order, the element 'FIRST.A3' would not exist when  the
  1244. ADD statement was executed.
  1245.  
  1246. _6._4._3.  _O_P_T_I_M_I_Z_E
  1247.  
  1248.      The OPTIMIZE statement is named for it's primary  func-
  1249. tion,  hand  optimization  of LTM.  There is also a built in
  1250. optimizer that can be invoked.  Optimization is discussed in
  1251. detail  in section 7.  The OPTIMIZE statement can be thought
  1252. of as an unconditional GOTO statement.  In normal execution,
  1253. after  a  rule fires the rules are tested from the beginning
  1254. of LTM for the next  rule  that  will  fire.   The  OPTIMIZE
  1255. statement can specify a point other than the start of LTM to
  1256. begin testing rules.  In addition to optimization, it can be
  1257. used  to impose a customized control structure on the set of
  1258. rules.
  1259.  
  1260.      One example of the use of the OPTIMIZE statement is  to
  1261. implement a search for the absence of some object(s) in STM,
  1262.  
  1263.  
  1264.  
  1265.  
  1266.  
  1267.  
  1268.  
  1269.  
  1270.  
  1271.                            - 20 -
  1272.  
  1273.  
  1274. which is not otherwise supported by the  TRC  language.   To
  1275. search  for  the  absence  of some object(s), use two rules.
  1276. The first rule searches for the presence of the object(s) in
  1277. question,  if  the  rule  is true then the object(s) are not
  1278. absent.  If the rule fails, the object(s) are absent, e.g.:
  1279.  
  1280.      R1:
  1281.           /* effectively search for the
  1282.              absence of an object A with
  1283.              element A1 == 2 */
  1284.  
  1285.           (A.A1 == 2)
  1286.           =>
  1287.           /* If this rule is true, branch
  1288.              around the next rule */
  1289.           OPTIMIZE R3
  1290.           ;
  1291.  
  1292.      R2:
  1293.           /* If R1 fails, then there is
  1294.              no object A with element
  1295.              A1 == 2.  An empty situation
  1296.              part such as this always
  1297.              evaluates to true */
  1298.           =>
  1299.           /* whatever you wish to do in response
  1300.              to the absence of A1 == 2 */
  1301.           ;
  1302.  
  1303.      R3:
  1304.           /* continue here if R1 is true */
  1305.           . . .
  1306.  
  1307.  
  1308. _6._4._4.  _C-_C_O_D_E
  1309.  
  1310.      A c-code may follow the MARK, ADD and  OPTIMIZE  state-
  1311. ments.  This is user code that is to be executed when a rule
  1312. fires.  C-code may not appear between MARK, ADD or  OPTIMIZE
  1313. statements.   If  it is necessary to refer to an object that
  1314. is being MARKed in c-code, it should be done in  the  situa-
  1315. tion  part.   A  c-code  may  precede  the arrow symbol that
  1316. separates the situation and action parts.   C-code  in  this
  1317. position  is  equivalent  to  c-code  in  the situation part
  1318. preceding the MARK, etc. statements, e.g.:
  1319.  
  1320.      R1:
  1321.           (^A FIRST)
  1322.           {
  1323.                /* this c-code follows all
  1324.                   situation tests.  It is
  1325.                   effectively in the action
  1326.                   part since it will execute
  1327.                   only if the situation is
  1328.  
  1329.  
  1330.  
  1331.  
  1332.  
  1333.  
  1334.  
  1335.  
  1336.  
  1337.                            - 21 -
  1338.  
  1339.  
  1340.                   true */
  1341.  
  1342.                some_procedure($FIRST.A1);
  1343.           }
  1344.           =>
  1345.           MARK FIRST
  1346.           ;
  1347.  
  1348.  
  1349. _7.  _O_P_T_I_M_I_Z_E_R
  1350.  
  1351.      The optimizer does not produce code that is optimum  in
  1352. any sense.  What it does is to perform a single, very useful
  1353. code modification that can have a very  positive  impact  on
  1354. execution time.
  1355.  
  1356.      Consider the execution of an  inference  engine.   Each
  1357. rule  is  tested  until  one who's situation part is true is
  1358. found.  This rule's action  part  is  then  executed.   When
  1359. rules  are being tested the problem space is being searched.
  1360. When an action part is executed a step is taken in the solu-
  1361. tion of the problem.  Searching the problem space is clearly
  1362. part of the solution, but the action part is where  the  the
  1363. results occur.
  1364.  
  1365.      The goal, which is  not  attained,  is  to  reduce  the
  1366. search time to zero.  To attain this goal it would be neces-
  1367. sary to know each time a rule fires  which  rule  will  fire
  1368. next.   This is generally not known.  In particular when the
  1369. inference engine begins execution, the contents of  STM  are
  1370. not  known,  any rule can be the first rule to fire.  Once a
  1371. rule has fired and each time any rule fires a great deal  of
  1372. implicit  knowledge  about  the contents of STM is obtained.
  1373. It is known that no rule previous to  the  current  rule  is
  1374. true  and  no  rule previous to the current rule can be true
  1375. after the execution of the current rule unless  the  current
  1376. rule  modifies  STM  in  such a way as to make some previous
  1377. rule true.  This simple fact is  the  entire  basis  of  the
  1378. optimizer, which attempts to reduce the number of rules that
  1379. are tested by deducing which rules can not possibly fire.
  1380.  
  1381.      Three tests must be performed to determine a  candidate
  1382. next  rule, which is the first rule in LTM that can possibly
  1383. fire after the current rule  fires.   The  three  tests  are
  1384. called the NOT test, the ADD test and the MARK test.
  1385.  
  1386.      The first case to be considered is the case of  a  rule
  1387. which contains a NOT statement in the situation part.  A NOT
  1388. test is an explicit test for an empty  list.   When  a  rule
  1389. that fires contains an ADD statement it will not be possible
  1390. for any previous rule with a NOT statement referring to that
  1391. list  to be the next rule to fire.  Likewise, if a rule that
  1392. fires contains a MARK statement and no ADD statement  refer-
  1393. ring  to  that  same list, it is possible that the list will
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  
  1402.  
  1403.                            - 22 -
  1404.  
  1405.  
  1406. become empty making it possible for the rule  with  the  NOT
  1407. statement  that  previously failed to become true.  If it is
  1408. determined that it is possible for a rule to fire after  the
  1409. NOT  test,  that  rule  becomes  the  candidate  rule and no
  1410. further testing is done.
  1411.  
  1412.      Consider the case of a rule with no NOT statements that
  1413. recursively  searches  STM  for  a  situation.  If this rule
  1414. fails, it will continue to fail until something is added  to
  1415. STM  to make it true.  If all rules searched STM recursively
  1416. it would be known when a rule fires that of the  rules  that
  1417. precede  the  current rule, only those rules that search for
  1418. something added to STM by the current rule can possibly fire
  1419. in the next pass.
  1420.  
  1421.      If the current rule  adds  something  to  STM,  control
  1422. could  continue  with  the first rule that searches for that
  1423. something rather than the first rule in  LTM.   If  no  rule
  1424. prior to the current rule searches for those things added to
  1425. STM by the current rule or if the current rule adds  nothing
  1426. to  STM  then no prior rule can execute.  Control could con-
  1427. tinue with the current rule rather than at the beginning  of
  1428. LTM.   By causing control to continue with a rule later than
  1429. the first rule the amount of searching is reduced.
  1430.  
  1431.      The case of a rule that performs only a  linear  search
  1432. on  STM  must  also  be considered.  The previous conclusion
  1433. about items being added to STM is still true;  a  rule  that
  1434. adds  something  to  STM  can  cause a linear search rule to
  1435. become true.  With linear search it is also possible that  a
  1436. rule  will become true if something is removed from STM.  If
  1437. a linear rule searches for several similar items  which  are
  1438. present  but  not  correctly ordered it is possible for this
  1439. linear search to fail where a  recursive  search  would  not
  1440. have  failed.   If there were excess items,  removing one or
  1441. more may cause a different  linear  assignment  which  could
  1442. make  a  linear rule true.  This is the MARK test.  Examples
  1443. of this situation are non-trivial, but where correctness  is
  1444. an issue these cases can not be overlooked.
  1445.  
  1446.      The TRC optimizer selects a continuation point for each
  1447. rule  based  on  what  the  rule adds to or deletes from STM
  1448. rather than testing each rule from  the  beginning  of  LTM.
  1449. The  continuation  point  is  the first rule that could fire
  1450. based on the NOT and ADD tests for all rules, and  the  MARK
  1451. test  for linear rules.  The TRC optimizer is somewhat naive
  1452. in that it considers only items added or  deleted  with  the
  1453. ADD  and  MARK  statements.  The optimizer is unaware of any
  1454. changes that may have been made to STM by  user  code.   The
  1455. caveat  is if STM is modified in user code the optimizer may
  1456. produce incorrect code. The optimizer, which can be  invoked
  1457. with  a  command line option (-O), tests each rule individu-
  1458. ally and ignores those rules that were hand optimized in the
  1459. specification.
  1460.  
  1461.  
  1462.  
  1463.  
  1464.  
  1465.  
  1466.