home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / ai / alsdsgn.doc next >
Encoding:
Text File  |  1988-05-03  |  90.3 KB  |  2,704 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.                          C2 Support Software in Ada(R)
  19.  
  20.  
  21.  
  22.  
  23.                          Top Level Design Specification
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.                                  SAE-DC-85-R001
  34.  
  35.  
  36.                                 January 27, 1986
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.                    Software Architecture & Engineering, Inc.
  46.                         1500 Wilson Boulevard, Suite 800
  47.                            Arlington, Virginia  22209
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.           (R) Ada is a registered trademark of the U.S. Government -
  58.                             Ada Joint Program Office
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.           1.  Introduction
  75.  
  76.                Recognition is growing rapidly of the potential appli-
  77.           cations of Artifical Intelligence (AI) technology in Depart-
  78.           ment of Defense (DOD) Command and Control (C2) and mission
  79.           critical systems.  AI techniques will play key roles in many
  80.           of these systems in the near future.  One factor that will
  81.           slow this trend is the fact that most currently successful
  82.           AI applications are implemented, either directly or
  83.           indirectly, in LISP.  Ada is the required language for new
  84.           DOD (embedded) application software.  The creation of a
  85.           package library to aid in the development of AI applica-
  86.           tions, along with tools that allow efficient translation of
  87.           existing LISP-based AI applications into Ada, will allow the
  88.           DOD to take advantage of the opportunities offerred by AI
  89.           technology.
  90.  
  91.                Logic programming is an important development in AI
  92.           programming techniques.  Its implementation in the form of
  93.           PROLOG has produced a language of tremendous potential, par-
  94.           ticularly in the area of knowledge-based expert systems.
  95.           The development of a logic programming capability within
  96.           Ada, again through a package library, will allow programmers
  97.           to capitalize on this emerging technology within new AI
  98.           applications.
  99.  
  100.  
  101.  
  102.           1.1.  Purpose
  103.  
  104.                The capabilities offerred by a synthesis of the conven-
  105.           tional software engineering technology supported by Ada in
  106.           combination with symbolic computation and logic programming
  107.           techniques will produce a C2 programming support environment
  108.           of impressive power.  This document describes the top-level
  109.           design of a collection of Ada packages sufficient to provide
  110.           such capabilities for developers of C2 applications in Ada,
  111.           and to provide the basis for translation of LISP-based AI
  112.           applications into Ada.
  113.  
  114.                This document is the final delivery of CDRL A002
  115.           (Informal Technical Information) for contract N66001-85-C-
  116.           0039 between Software Architecture and Engineering, Inc.,
  117.           and the Naval Oceans Systems Center, 271 Catalina Boulevard,
  118.           Building A33, San Diego, CA  92152.
  119.  
  120.  
  121.  
  122.           1.2.  Scope
  123.  
  124.                AI technology, and, more specifically, knowledge-based
  125.           expert systems, are proving to be of value in decision sup-
  126.           port, target classification, indications and warning, and
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.           many other C2-related areas.  AI offers the opportunity to
  141.           vastly increase the amount of information that can be
  142.           analyzed in a timely fashion, information that might other-
  143.           wise go unused due to the sheer volume generated by present
  144.           day sensors and intelligence systems.  This volume will only
  145.           grow, as these systems evolve, without some type of filter-
  146.           ing agent.  The effective use of AI techniques can have the
  147.           effect of significantly increasing the power of our current
  148.           C2 systems by providing that filtering mechanism.
  149.  
  150.                Today, LISP (of some type) is the most prevalent
  151.           language used to implement AI applications.  The reason for
  152.           this is that the major current LISP dialects provide power-
  153.           ful symbolic processing facilities not provided by the
  154.           majority of modern, block-structured, higher-order, conven-
  155.           tional programming languages.  These conventional languages
  156.           do not exclude symbolic processing, they just do not provide
  157.           language-based facilities for such manipulations.  As a
  158.           result, the AI design paradigms used with LISP are not
  159.           easily implemented in languages like Ada.  Ada can be used
  160.           to implement AI applications if it is augmented with capa-
  161.           bilities which emulate some of the unique aspects of the
  162.           symbolic manipulation facilities of LISP.  This can be
  163.           accomplished through specially designed Ada packages.
  164.  
  165.                Logic programming systems are a direct implementation,
  166.           in the form of a programming language, of the general con-
  167.           cept of a production system, discussed in detail later in
  168.           this document.  Logic programming languages, like PROLOG and
  169.           the OPS family, are directly useful in implementing
  170.           knowledge-based expert systems where knowledge is primarily
  171.           representable in the form of rules.  However, in general,
  172.           the use of a logic programming facility provides a powerful,
  173.           yet extraordinarily concise, technique for developing appli-
  174.           cations which must do any kind of symbolic reasoning, that
  175.           is, reasoning about logical relationships among symbolic
  176.           data items.  LISP-based AI applications which need to per-
  177.           form this function implement reasoning functions and data
  178.           structures tailored to the application.  Rather than require
  179.           an application developer to invent unique reasoning systems,
  180.           Ada provides the mechanism to augment the language with fun-
  181.           damental logic programming facilities.  These facilities can
  182.           then support the development of generalized reasoning sys-
  183.           tems fully integrated with the symbolic processing package.
  184.  
  185.                Software A & E will implement a library of Ada packages
  186.           to support such capabilites.  The effort is limited in this
  187.           first phase to the minimal required support for many LISP-
  188.           based and logic programming applications.  Follow-on efforts
  189.           could expand the base provided by this first increment to
  190.           include conversion aid tools, enhanced logic programming
  191.           paradigms, and additional low level AI component packages.
  192.  
  193.  
  194.  
  195.                                        2
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.           1.3.  References
  207.  
  208.           ANSI/MIL-STD-1815A, 1983.  Ada Programming Language.  U. S.
  209.           Government, Washington, DC.
  210.  
  211.           Barr, A., and Feigenbaum, E. A. (Eds.) 1981.  The Handbook
  212.           of Artificial Intelligence (Vol. 1 & 2). Los Altos, CA: Wil-
  213.           liam Kaufmann, Inc.
  214.  
  215.           Booch, G. 1983.  Software Engineering with Ada.  Menlo Park,
  216.           CA: Benjamin/Cummings Publishing Co.
  217.  
  218.           Campbell, J. A. (Ed.) 1984.  Implementations of PROLOG.  New
  219.           York, NY: Halstead Press.
  220.  
  221.           Charniak, E., Reisbeck, C. K., and McDermott, D. V. 1980.
  222.           Artificial Intelligence Programming.  Hillsdale, NJ:
  223.           Lawrence Erlbaum Associates.
  224.  
  225.           Knowledge Engineering System, Knowledge Base Author's Refer-
  226.           ence Manual.  1983. Software Architecture and Engineering,
  227.           Inc.
  228.  
  229.           Kowalski, R. 1979.  Logic for Problem Solving.  New York,
  230.           NY: Elsevier Science Publishing Co., Inc.
  231.  
  232.           Nilsson, N. J. 1980.  Priciples of Artificial Intelligence.
  233.           Palo Alto, CA: Tioga Publishing Co.
  234.  
  235.           Parnas, D. L. 1972.  On the Criteria to be used in Decompos-
  236.           ing Systems into Modules.  CACM 15:12, pp 1053-1058.
  237.  
  238.           Schwartz, R. L., and Melliar-Smith, P. M. 1980.  The Suita-
  239.           bility of Ada for Artificial Intelligence Applications.
  240.           Menlo Park, CA: SRI International.
  241.  
  242.           Steel, G. L. 1984.  COMMON LISP, The Language.  Burlington,
  243.           MA: Digital Press.
  244.  
  245.           Winston, P. H., and Horn, B. K. P. 1984.  LISP, Second Edi-
  246.           tion.  Reading, MA: Addison-Wesley Publishing Co., Inc.
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.                                        3
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.           1.4.  Overview
  273.  
  274.                An AI support environment for Ada would ultimately con-
  275.           sist of the following categories of components:
  276.  
  277.           (a)  LISP-capability emulation: packages which emulate the
  278.                symbolic manipulation capabilities of LISP that are not
  279.                directly available in Ada.
  280.  
  281.           (b)  Translation aids: packages that support syntactic and
  282.                semantic mapping of LISP-based programs into Ada con-
  283.                structs and facilities provided by the packages in
  284.                category (a).
  285.  
  286.           (c)  AI mechanisms: packages that represent commonly occur-
  287.                ring AI mechanisms, e.g.  a backward inferencing con-
  288.                trol strategy.
  289.  
  290.                Software A & E recommended an incremental approach to
  291.           development of the software in these three categories in the
  292.           contract proposal.  The first increment, a fundamental sub-
  293.           set of categories (a) and (c), is addressed by this docu-
  294.           ment.  This fundamental environment will consist of abstract
  295.           data types, objects, and associated operations commonly used
  296.           in AI applications, but not directly supported in Ada.
  297.  
  298.                The functional areas supported by the basic package to
  299.           be developed are briefly described in the Statement of Work
  300.           (SOW) as follows:
  301.  
  302.           (a)  AI data types: abstract data types will be developed
  303.                that characterize classes of symbolic data and associ-
  304.                ated operations commonly used in LISP-based AI applica-
  305.                tions;  these data types will provide a common base for
  306.                symbolic computation to be shared by AI applications
  307.                without concern for details of representation.
  308.  
  309.           (b)  Dynamic storage management: a typical AI program is
  310.                characterized by the highly dynamic way in which large
  311.                numbers of primitive data objects are created and dis-
  312.                carded; facilities for management of dynamic allocation
  313.                and reuse of object storage space are required to sup-
  314.                port this.
  315.  
  316.                In addition to this basic functionality, the SOW
  317.           requires the following:
  318.  
  319.           (c)  Generic AI objects: in general, flexibility can be
  320.                attained in AI programs through an object oriented view
  321.                of data that allows the details of object representa-
  322.                tion and typing to be hidden; packages will be
  323.                developed to provide definitions of objects generally
  324.                found useful in LISP-based AI programs.
  325.  
  326.  
  327.                                        4
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.           1.4.1.  Product Goals
  339.  
  340.           (a)  The product will support production development of AI
  341.                applications, as opposed to the evolutionary develop-
  342.                ment that is typical of AI research programming in
  343.                LISP.  The emphasis here is on decisions made during
  344.                application construction as part of various application
  345.                life-cycle methodologies for specification, design,
  346.                implementation, and revision of large software systems.
  347.  
  348.           (b)  The product will provide a collection of abstract data
  349.                objects (with operations) that is both necessary and
  350.                sufficient to support object-oriented design and imple-
  351.                mentation of AI applications in Ada.  These objects
  352.                should be arbitrarily composable with each other and
  353.                with the predefined objects of Ada in the same manner
  354.                that the Ada primitive objects are composable.  These
  355.                object types should not duplicate predefined objects of
  356.                Ada unnecessarily.
  357.  
  358.           (c)  Ada is a language of strong static typing and strong
  359.                dynamic sub-typing, and the facilities implemented by
  360.                the product should adhere to the same design princi-
  361.                ples.  The product should build upon a (collection of)
  362.                basic data type(s).  These should be the minimum addi-
  363.                tion to Ada's predefined data types that will give an
  364.                Ada programmer the means to manipulate dynamic objects
  365.                in a strongly typed environment.  The intent is not to
  366.                build a LISP or PROLOG environment on top of Ada, but
  367.                rather to support the AI application development para-
  368.                digms of these environments in the style of Ada.
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.                                        5
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.           2.  General Description
  405.  
  406.           2.1.  Product Perspective
  407.  
  408.                Artificial intelligence is the part of computer science
  409.           concerned with designing computer systems that exhibit
  410.           characteristics commonly associated with intelligence in
  411.           humans: problem solving, logical reasoning, language syn-
  412.           thesis and understanding, learning, expertise and vision.
  413.           Recently, the area of expert systems has begun to emerge as
  414.           a tool for developing practical applications of AI tech-
  415.           niques.  Typical examples of current expert systems interact
  416.           with a human user in a dialog in a manner similar to the way
  417.           the user would interact with a human expert.  Such consulta-
  418.           tion systems have achieved high levels of performance in
  419.           tasks which are amenable to this approach, such as geologi-
  420.           cal data analysis and medical diagnosis.  The next step in
  421.           the evolution of such systems is to embed them within other
  422.           application systems in such a way that the application sys-
  423.           tem, as the user, can interact with the expert system to
  424.           solve problems.
  425.  
  426.                The ability to behave with intelligence is usually
  427.           described in terms of knowledge.  Since AI involves the
  428.           design of computer systems that exhibit intelligent
  429.           behavior, knowledge representation is an important issue.  A
  430.           representation of knowledge is some combination of data
  431.           structures and procedures which lead to such intelligent
  432.           behavior when used in an appropriate manner.  Work on
  433.           knowledge representation has involved the design of several
  434.           classes of data structures for storing information as well
  435.           as the development of procedures that allow manipulation of
  436.           these data structures to make intelligent deductions.
  437.  
  438.  
  439.  
  440.           2.1.1.  Production Systems
  441.  
  442.                A common type of knowledge representation system is the
  443.           production system, which is a modular scheme finding
  444.           increasing popularity.   The major components of such a sys-
  445.           tem are a data base, a knowledge base, and a control stra-
  446.           tegy.  The data base is actually a temporary working storage
  447.           area used during construction of the solution of a specific
  448.           problem.  A production system operates by manipulating the
  449.           data base using the operations defined in the knowledge base
  450.           under the control of the control strategy.  The operations
  451.           defined by the knowledge base in a production system are in
  452.           the form of rules.  Each rule has a pre-condition that is
  453.           either satisfied or not by the data base.  If the pre-
  454.           condition is satisfied, the rule can be applied.  Applica-
  455.           tion of a rule changes the data base.  The choice of which
  456.           applicable rule to actually apply is done by the control
  457.  
  458.  
  459.                                        6
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.           strategy, which also has the responsibility of recognizing a
  471.           termination condition on the data base after each rule is
  472.           applied.  The primary task of a production system is to
  473.           infer (sometimes, deduce or prove) goals from the initial
  474.           contents of the data base using the rules.
  475.  
  476.                In a conventional production system, the data base,
  477.           knowledge base and control strategy are each globally
  478.           defined for the application.  The control strategy is usu-
  479.           ally a standard predefined component of a generalized pro-
  480.           duction system, which is supplied with an application-
  481.           specific knowledge base.  There is no notion of a local sub-
  482.           set of the data base accessible by a subset of the knowledge
  483.           base.  In fact, the data base is the only medium of communi-
  484.           cation between rules, which do not "call" one another.  This
  485.           results in an application structure which is extremely modu-
  486.           lar in its knowledge base part, but which is otherwise rela-
  487.           tively unstructured.  In general, the ordering of the appli-
  488.           cation of rules is irrelevant, which allows changes to the
  489.           knowledge base to be made relatively independently of each
  490.           other.
  491.  
  492.                There are two basic types of control strategy:
  493.  
  494.           (a)  irrevocable - an application rule is selected and
  495.                applied without provision for reconsideration.  Irrevo-
  496.                cable control strategies are only used when there is
  497.                infallible knowledge about how to proceed toward a goal
  498.                from a state of the computation.
  499.  
  500.           (b)  tentative - an applicable rule is selected (either
  501.                arbitrarily or using some heuristics), the rule is
  502.                applied, but provision is made to undo the effects of
  503.                the selection and subsequent computations and apply
  504.                some other rule.  The most common tentative control
  505.                strategy is backtracking.  Backtracking is the process
  506.                whereby, if a subsequent computation fails, the state
  507.                of the computation reverts to a prior state, the
  508.                choices made at that prior state are discarded, and new
  509.                choices are made.  The states at which backtracking can
  510.                return to are points in the computation determined by
  511.                the control strategy.  Typically, the selection of a
  512.                rule from a set of applicable rules is established as a
  513.                backtracking point.
  514.  
  515.                AI applications require knowledge of the problem domain
  516.           in three basic categories in order to achieve efficient
  517.           operations.  These categories are assertional, procedural,
  518.           and control knowledge.  Assertional knowledge expresses
  519.           explicit knowledge about a problem or problem domain; pro-
  520.           cedural knowledge expresses rules for manipulating the
  521.           assertional knowledge; control knowledge expresses knowledge
  522.           about the problem solving process for the problem domain,
  523.  
  524.  
  525.                                        7
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.           that is, the appropriate control strategy.  Production sys-
  537.           tems are generally accepted as a convenient and natural
  538.           mechanism for expressing assertional and procedural
  539.           knowledge.  Production systems have been found to be useful
  540.           mechanisms for controlling the interaction between asser-
  541.           tional and procedural knowledge.  Assertional knowledge is
  542.           separable into the two sub-categories of rules and facts,
  543.           whereas procedural knowledge is expressed only by rules.
  544.           Rules are usually stated in the form of implications:
  545.  
  546.                                   if A then B
  547.                                        or
  548.                                      A => B
  549.  
  550.           and can express generalized knowledge, while facts are sim-
  551.           ple non-implicational statements expressing specific
  552.           knowledge.  In an implication, the pre-condition, or if-
  553.           part, is called the antecedent, while the result, or then-
  554.           part, is called the consequent.  The general form of the
  555.           antecedent and consequent of a rule is a sequence of terms
  556.           joined by conjunction (AND) and/or disjunction (OR) opera-
  557.           tors.  A term is usually expressed in functional notation as
  558.           a predicate with arguments, which may be arbitrary symbolic
  559.           expressions.  Control knowledge will be discussed later.
  560.  
  561.                An inference is either antecedent driven or consequent
  562.           driven.  In an antecedent driven inference, the occurrence
  563.           of a fact in the data base which matches the antecedent of a
  564.           rule makes that rule applicable.  In a consequent driven
  565.           inference, the system attempts to obtain a specific goal by
  566.           locating a rule whose consequent matches that goal, and then
  567.           attempts to obtain the antecedent of that rule as a sub-
  568.           goal.  Antecedent driven inferencing is usually referred to
  569.           as forward inferencing, while consequent driven inferencing
  570.           is usually referred to as backward inferencing, since the
  571.           coventional interpretation of the "flow" of an implication
  572.           is from the antecedent to the consequent.  Conventional pro-
  573.           duction systems typically employ control strategies which
  574.           are either strictly forward or strictly backward inferencing
  575.           systems.  Although a combined forward and backward control
  576.           strategy is certainly possible, it is inherently more com-
  577.           plicated due to the global nature of the structure of these
  578.           conventional production systems.
  579.  
  580.                In forward inferencing systems, the rules of the
  581.           knowledge base are applied to a data base (initialized with
  582.           a given set of facts) until a termination condition involv-
  583.           ing a goal defined by the particular problem is reached.
  584.           Termination occurs when at least one term of the goal
  585.           expression is inferred.  In backward inferencing systems,
  586.           the rules of the knowledge base are applied to a data base
  587.           (initialized with a goal expression) until a termination
  588.           condition involving facts in the knowledge base is reached.
  589.  
  590.  
  591.                                        8
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.           Termination occurs when the goal expression is composed of
  603.           facts.
  604.  
  605.                In order to use control knowledge in a production sys-
  606.           tem, there must be a suitable representation for it.  Vari-
  607.           ous approaches have been considered, such as treating the
  608.           control strategy as a series of problems to be solved by
  609.           another (meta) production system, embedding control
  610.           knowledge into discrimination functions supplied to a gen-
  611.           eral control strategy, or embedding control knowledge into
  612.           the rules themselves.  This latter approach is taken by the
  613.           "logic programming" languages, such as PROLOG or the OPS
  614.           family.
  615.  
  616.                The general logic programming paradigm is to treat a
  617.           rule like a subprogram of a conventional programming
  618.           language.  The control strategy invokes rules only when new
  619.           goals or facts are infered, depending on the inferencing
  620.           mechanism used.  A simple control strategy, similar to that
  621.           found in PROLOG, is to select all applicable rules whenever
  622.           a new goal is created and invoke the first one selected.  An
  623.           "executing" rule may assert new facts, goals, or even rules,
  624.           which may cause the "executing" rule to be suspended if new
  625.           rules are invoked.  A rule terminates either with success or
  626.           failure, depending on whether its sub-goals can be inferred
  627.           or not.  In either case, control is returned to the invoking
  628.           rule, but in the failure case, backtracking occurs and a new
  629.           rule is invoked.
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.                                        9
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.           2.1.2.  Logic Programming
  669.  
  670.                Logic programming systems are an important development
  671.           in the AI field.  These languages, in their pure form, use
  672.           assertions about logical relationships between data elements
  673.           to specify programs, rather that specifying procedurally how
  674.           operations are to be performed.  Logic programming permits
  675.           extraordinarily concise programs because its statements are
  676.           declarative rather than prescriptive.  Unfortunately, this
  677.           programming conciseness is not without costs.  In PROLOG,
  678.           for example, the control strategy works by generating virtu-
  679.           ally all possible implications of a given initial data base
  680.           configuration, whether or not they are relevant.  Further,
  681.           PROLOG, in its pure form, is not deterred from searching for
  682.           more than one inference sequence for the same goal.  Most
  683.           PROLOG implementations have been augmented with control
  684.           strategy directives to constrain a program's search path.
  685.           PROLOG is a language of tremendous potential which it has,
  686.           to date, failed to realize, in many cases, due to a number
  687.           of questionable design decisions.  One of these is the
  688.           choice of backtracking as the sole control structure of the
  689.           language.  This paradigm fits certain problems well, but
  690.           yields programs that are inefficient as well as incomprehen-
  691.           sible when confronted with the many situations for which
  692.           backtracking is unsuited.
  693.  
  694.                The great power conferred by the availability of a
  695.           logic programming capability strongly argues for its inclu-
  696.           sion in the AI programming environment.  The combination of
  697.           a logic processing facility and a symbolic processing facil-
  698.           ity, both interfacing smoothly with each other and with the
  699.           Ada host language, produces a facility of impressive power.
  700.           This situation is provided by having such a logic program-
  701.           ming facility available to be invoked as needed embedded in
  702.           the Ada host language and interfacing with the symbolic com-
  703.           putation tools.  In particular, since the control structures
  704.           of the Ada language are available, the difficulties engen-
  705.           dered by being confined to backtracking are obviated, and
  706.           efficient logic programming becomes possible.
  707.  
  708.                There is no reason to restrict a programmer in the same
  709.           manner as is done in conventional production systems to a
  710.           single knowledge base, a single working storage data base,
  711.           and a single control strategy.  Given Ada's capabilities, it
  712.           is straightforward to define logic programming control stra-
  713.           tegy operations which take a data base and a knowledge base
  714.           as arguments.  Furthermore, facilities could easily be pro-
  715.           vided implementing both backward inferencing, as in PROLOG,
  716.           as well as forward inferencing, as in the OPS language fam-
  717.           ily, control strategies.  With the support for concurrent
  718.           task implementations provided by Ada, it may even be possi-
  719.           ble to ultimately provide implementations of concurrent
  720.           inferencing control strategies.
  721.  
  722.  
  723.                                        10
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734.           2.2.  Product Functions
  735.  
  736.           2.2.1.  Symbolic Expressions
  737.  
  738.                The essential capability that has allowed LISP to
  739.           retain its dominant position as an AI programming language
  740.           is its ability to perform abstract manipulations on dynami-
  741.           cally shaped data structures.  This unconstrained form of
  742.           data structuring is an important characteristic of AI pro-
  743.           gramming languages, as it allows data structures of
  744.           unpredictable size and shape to be conveniently constructed
  745.           and manipulated.  The data structures are, at this level of
  746.           LISP, interpreted only in a structural fashion by the opera-
  747.           tors which manipulate them.  Interpretations of the elemen-
  748.           tary data items, and interpretations of their structural
  749.           composition as representations for relationships between
  750.           them, is left up to the individual application program.  A
  751.           disadvantage of the LISP approach to data structuring is
  752.           that there is no built-in mechanism to enforce any
  753.           application-specific constraints on the size and shape of
  754.           the structures, as determined by the intended interpreta-
  755.           tion.  COMMON LISP addresses this problem somewhat by defin-
  756.           ing facilities that allow a programmer to do explicit con-
  757.           straint checking for data types.  This approach to data pro-
  758.           cessing is usually referred to as symbolic computation, and
  759.           the data structures are usually referred to as symbolic
  760.           expressions.
  761.  
  762.                Most introductory LISP references talk about lists and
  763.           list processing when explaining the essential capabilities
  764.           of LISP.  This tends to obscure the real power behind LISP,
  765.           since the notion of a "list of components" is a particular
  766.           interpretation of a symbolic expression, where another
  767.           interpretation may be more appropriate in the specific
  768.           application, such as a "function with arguments."  Part of
  769.           the reason for the conventional approach to LISP is that the
  770.           procedural semantics of the LISP symbolic expressions are
  771.           defined in terms of operations on the representation of sym-
  772.           bolic expressions, with conventions that treat the represen-
  773.           tation as a linked list, even though it is actually a binary
  774.           tree structure.
  775.  
  776.                The fundamental characteristic of the LISP symbolic
  777.           expression is that it is a recursive data type, when viewed
  778.           as an abstraction independently of the all-too-visible
  779.           implementation details of LISP.  It is the recursive nature
  780.           of the type that gives LISP its expressive power.  The most
  781.           common characterization of a recursive data structure is the
  782.           tree structure.  There are a large number of concepts dealt
  783.           with in typical AI applications that can be easily
  784.           represented as tree structures, given an appropriate set of
  785.           access and construction operations.
  786.  
  787.  
  788.  
  789.                                        11
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.                The other important issue with respect to the specifi-
  801.           cation of the symbolic expression type is structure sharing.
  802.           Symbolic processing applications typically have large memory
  803.           requirements.  To lessen this burden on available storage,
  804.           symbolic expression structures will be shared.  That is, the
  805.           result of a symbolic processing operation will typically
  806.           return a reference to a specific portion of the input argu-
  807.           ment rather than returning a brand-new copy of the desired
  808.           result.  However, this raises a problem if destructive
  809.           operations such as LISP's replaca and replacd, are provided.
  810.           The solution is simply not to provide any of these destruc-
  811.           tive operations.  Thus, the choice of an internal implemen-
  812.           tation using sharing can not impact any user of the facil-
  813.           ity.  All operations defined on symbolic expressions will be
  814.           non-destructive or constructive (no existing values are cor-
  815.           rupted, and results of operations are defined as new
  816.           values).
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.  
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.                                        12
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866.           2.2.2.  Pattern Matching
  867.  
  868.                A pattern is a symbolic expression with special atomic
  869.           components referred to as variables.  Two patterns are said
  870.           to match if their variables can be replaced by values to
  871.           make both patterns identical, where multiple occurrences of
  872.           the same variable in a pattern must be substituted con-
  873.           sistently with the same value.
  874.  
  875.                The values which are matched with variables are usually
  876.           of interest to the application using the pattern matching
  877.           operation.  Consequently, the matching operations is usually
  878.           defined to return as a result the correspondences between
  879.           variables and values generated during a successful matching
  880.           operation.  The correspondence between a variable and its
  881.           matching value is referred to as the variable binding, and
  882.           the result of the matching operation is the variable binding
  883.           list.
  884.  
  885.                Pattern matching is typically implemented as a sequen-
  886.           tial operation which considers each corresponding pair of
  887.           components from the two patterns in turn, with a recursive
  888.           call to the matching operation occurring when a component is
  889.           non-atomic.  Under this approach, variable bindings are gen-
  890.           erated immediately upon the first match for each variable.
  891.           Subsequent occurrences of such a bound variable then use the
  892.           bound value rather than the variable itself in the component
  893.           matching test.  A variable can be bound only if it is
  894.           currently unbound, e.g., the value of a bound variable can-
  895.           not change.  Variables may be bound to other variables, in
  896.           which case the variables are said to be linked rather than
  897.           bound.  Linked variables remain candidates for binding until
  898.           one of the linked variables becomes bound, at which point
  899.           all variables linked to that bound variable become bound to
  900.           that same value.
  901.  
  902.                One restriction that is typically placed on this pro-
  903.           cess is that the scope of a pattern variable is a single
  904.           pattern.  In other words, a variable in a pattern is dis-
  905.           tinct from any variable in any other pattern, even if the
  906.           representation of the symbols used to denote two different
  907.           variables on an external device are the same.  Even with
  908.           this restriction, it is possible for a variable to become
  909.           linked to itself, or bound to an expression which includes
  910.           itself as a component.  This can occur when the variable is
  911.           matched against a variable of the other pattern which was
  912.           linked or bound at a previous component position.
  913.  
  914.                Linking a variable to itself causes no conceptual prob-
  915.           lems, but the case of binding a variable to an expression
  916.           which contains that same variable as a component causes cir-
  917.           cularity problems.  Detection of this situation requires a
  918.           potentially expensive check during each component match
  919.  
  920.  
  921.                                        13
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.  
  932.           step.  In this case, the match operation is usually defined
  933.           to fail, as it is difficult to deal with circular data
  934.           structures.  The checking required is called the occurs
  935.           check in the literature.
  936.  
  937.                If multiple copies of a pattern are used in pattern
  938.           matching operations simultaneously, it must be possible to
  939.           prevent binding conflicts between the various usages.  This
  940.           can occur as the result of using a global pattern in a
  941.           multi-tasking application, or in sequential processing
  942.           within a self-recursive subprogram.  This latter situation
  943.           is especially important to the product design, as patterns
  944.           will be the basis for the implementation of rules, and the
  945.           algorithms used for proving goals from rules are essentially
  946.           recursive pattern matching operations.  During a single
  947.           recursive search for a proof, the algorithm may utilize the
  948.           same rule multiple times at different levels of the recur-
  949.           sion.  The obvious solution is for the pattern matching
  950.           operations to systematically rename variables in each pat-
  951.           tern before attempting the match.  Optimization of this pro-
  952.           duction of variants of patterns is essential to an efficient
  953.           implementation.
  954.  
  955.                The classic implementation of variable binding is as a
  956.           list of pairs of variable name and bound value, accessed by
  957.           linear lookup on the variable name.  This is easy to imple-
  958.           ment and to understand, but the time to find the binding of
  959.           a variable is proportional to the number of bound variables.
  960.           The worst case behavior is terrible, but the normal case
  961.           behavior is reasonable for finding the binding of a bound
  962.           variable, since the binding list will typically be short.
  963.           Determination that a variable is unbound requires traversal
  964.           of the entire list, accentuated by the fact that long chains
  965.           of linked variables cause a list traversal for each link, as
  966.           the linking is represented as a binding pair with two vari-
  967.           able names.  In this case, an occurs check is needed to dis-
  968.           cover the situation of linking a variable to itself, which
  969.           will cause a circularity in this implementation.  For-
  970.           tunately, the check is simple in this special case.  The
  971.           matching operation is defined to succeed, but no binding
  972.           results.
  973.  
  974.                An alternative to using a single list representing all
  975.           bindings is to have a binding list associated with each pat-
  976.           tern.  The trick here is that, when a variable is bound to a
  977.           value, the binding is represented by a pair consisting of
  978.           the value and the binding list associated with the pattern
  979.           from which the value was extracted.  To discover the value
  980.           bound to a variable may require several list traversals in
  981.           the case of variable linking, but each list will typically
  982.           be quite small.  The major advantage of this scheme is that
  983.           the association of a binding list with each pattern can be
  984.           designed to implicitly take care of the renaming of
  985.  
  986.  
  987.                                        14
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.  
  998.           variables when a pattern is used multiple times con-
  999.           currently, provided that the association of binding lists
  1000.           with patterns is local to the location of usage so that each
  1001.           copy of the pattern in use has a unique binding list.
  1002.  
  1003.                An important issue is how to handle variable linking,
  1004.           especially within the context of using patterns to implement
  1005.           rules, as long chains of linked variables can result during
  1006.           a single attempt to prove a goal.  In the classic implemen-
  1007.           tation, this is represented by a binding a variable to
  1008.           another variable and repeatedly looking up the next binding
  1009.           until an unbound variable or a value is encountered.
  1010.  
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.                                        15
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.           2.2.3.  Logic Programming
  1065.  
  1066.                The major workhorse of a logic programming system is
  1067.           the unifier, which matches goals with consequents of asser-
  1068.           tions, possibly generating new sub-goals, which must be
  1069.           proved recursively.  Assertions represent both rules and
  1070.           facts, where facts are represented by rules with no
  1071.           antecedent (or sometimes with a literal representing true as
  1072.           the antecedent).  This allows uniform treatment of rules and
  1073.           facts.  If a (sub-)goal is matched with a fact consequent,
  1074.           then it is proved, while if it is matched with a rule conse-
  1075.           quent, then the antecedent of that rule must be proved as a
  1076.           sub-goal.  During this recursive matching process, the unif-
  1077.           ier binds variables matched to component expressions and
  1078.           uses those bindings during subsequent sub-goal processing.
  1079.           The initial goal is referred to as a query, and is usually
  1080.           represented as a rule with no consequent, so that the unif-
  1081.           ier is always matching antecedents representing (sub-)goals
  1082.           with consequents of assertions.  A general term referring to
  1083.           both assertions and queries is the rule.
  1084.  
  1085.                The unification algorithm matches a pair of arguments,
  1086.           which are generally components extracted from an antecedent
  1087.           of one rule and a consequent of some other rule, at each
  1088.           step, doing so within an environment which contains any
  1089.           current variable bindings.  As for the case of patterns,
  1090.           variables are required to be unique to each rule.  In addi-
  1091.           tion, variables within rules are generally interpreted as
  1092.           being universally quantified over the entire rule (e.g., the
  1093.           rule is interpreted as applying for any value of each vari-
  1094.           able).  If the unification succeeds for a (sub-)goal, it
  1095.           adds any new variable bindings to the environment, and
  1096.           returns the extended environment to the caller, which uses
  1097.           the new environment when attempting to prove additional
  1098.           sub-goals.  Since it is possible for an assertion to be used
  1099.           more than once during this recursive unification process, it
  1100.           is important to prevent binding conflicts in the environ-
  1101.           ment, which occur when the variables of an assertion are
  1102.           bound to different values for each use of that assertion.
  1103.           This is why the classical unification algorithm renames
  1104.           variables before using an assertion.  However, as mentioned
  1105.           during the discussion on pattern matching, there are ways to
  1106.           avoid this expensive operation.
  1107.  
  1108.                The binding of variables during unification has add-
  1109.           tional requirements beyond those for the simple case of pat-
  1110.           tern matching.  Symbolic expressions containing unbound
  1111.           variables can become bound to variables after unifying the
  1112.           consequent of an assertion with a (sub-)goal.  These unbound
  1113.           variables may later become bound (or not) while processing
  1114.           the antecedent of that assertion as a new sub-goal.  Conse-
  1115.           quently, the binding environment generated during unifica-
  1116.           tion cannot, in general, disappear until after the original
  1117.  
  1118.  
  1119.                                        16
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.           query has been proved.  At least that subset of the environ-
  1131.           ment which is required to keep track of such unbound vari-
  1132.           ables returned out of sub-goal unifications must be
  1133.           retained.  Variables can also become unbound during back-
  1134.           tracking when sub-goal unification fails to find a match.
  1135.  
  1136.                For this initial phase of the implementation, the prim-
  1137.           itive objects and operations necessary to implement a logic
  1138.           programming control strategy and to otherwise support the
  1139.           implementation of a logic programming facility are required.
  1140.           Additionally, a simple control strategy implementing essen-
  1141.           tially a PROLOG style of backward inferencing is necessary
  1142.           in order to demonstrate the fundamental facilities.  The
  1143.           required objects are, essentially, generalized rules and
  1144.           rulebases.  A rulebase object can be used to implement both
  1145.           knowledge bases and working storage data bases if goals and
  1146.           facts are treated as special cases of the generalized rules.
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.                                        17
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.           2.3.  General Constraints
  1197.  
  1198.           2.3.1.  Design Methodology
  1199.  
  1200.                Software A & E will use modern software engineering
  1201.           techniques in the implementation of this product.  In the
  1202.           design phase, the particular techniques employed will be
  1203.           information hiding and object-oriented design.
  1204.  
  1205.  
  1206.  
  1207.           2.3.1.1.  Information Hiding
  1208.  
  1209.                The decomposition criteria supporting step-wise refine-
  1210.           ment of a software system design due to Parnas, known as
  1211.           information hiding, is an important design technique.  The
  1212.           basic idea is to decompose a software system into modules in
  1213.           such a way that each module allows the implementation
  1214.           details of a single design aspect of the system to be hid-
  1215.           den.  This technique explicitly captures the design struc-
  1216.           ture of a software system in the software at the level at
  1217.           which each design decision was made.  The advantage of this
  1218.           design approach is that, if the need arises to modify the
  1219.           system, the effects of the modification should be localized
  1220.           to one module.
  1221.  
  1222.                An information hiding module defines a set of software
  1223.           functions while hiding the information about how the func-
  1224.           tions are actually implemented.  This technique supports the
  1225.           development of software which is designed for easily imple-
  1226.           mented enhancements and modifications.  One of the principle
  1227.           design goals of Ada was to allow exploitation of these pro-
  1228.           ductivity advantages.  One disadvantage of this approach is
  1229.           that the resulting application may suffer from the perfor-
  1230.           mance standpoint when compared to an equivalent application
  1231.           which has its functions coded inline.  Ada provides an
  1232.           elegant solution to this problem by allowing the developer
  1233.           to tell the compiler to compile certain functions as if they
  1234.           had been written inline.  It is a general design principle
  1235.           of Ada that the presence of expensive capabilities (in terms
  1236.           of performance) should not penalize the efficiency for usage
  1237.           of simple capabilities.
  1238.  
  1239.                A software system designed using this technique is
  1240.           organized into a hierarchy of modules.  Within the hierar-
  1241.           chy, a function of a module is only permitted to use func-
  1242.           tions of other modules which are beneath it in the hierarchy
  1243.           to perform its function.  The levels in the hierarchy can be
  1244.           viewed as abstract machines.  Each abstract machine provides
  1245.           functional capabilities to higher-level software components
  1246.           that are more powerful and application specific than the
  1247.           lower levels of abstraction.  Use of information hiding as
  1248.           the decomposition criteria fully supports incremental
  1249.  
  1250.  
  1251.                                        18
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260.  
  1261.  
  1262.           development, as each level of the hierarchy only depends on
  1263.           the visible functions provided by lower levels.  Unless the
  1264.           visible functions change, modifications are localized.
  1265.  
  1266.  
  1267.  
  1268.           2.3.1.2.  Object-oriented Design
  1269.  
  1270.                Object-oriented design is a methodology which attempts
  1271.           to map a solution to a problem directly to the solution's
  1272.           users' view of the problem.  The methodology is character-
  1273.           ized by its balanced treatment between the software com-
  1274.           ponents representing the objects of the problem space and
  1275.           the software operations representing the actions taken by or
  1276.           applied to these objects.  The software objects are viewed
  1277.           as actors, each with its own set of applicable operations.
  1278.           The basic approach is to initially develop an informal stra-
  1279.           tegy for the solution to a problem that parallels the world
  1280.           view of the users.  This solution strategy is expressed in
  1281.           terms of the concepts from this problem space.  Given this
  1282.           informal strategy, the objects and actions are identified,
  1283.           and the relationships among the objects are established.  At
  1284.           this point, a formal description of the visible interfaces
  1285.           to each object can be developed, which explicitly defines
  1286.           the operations that may be performed on or by each object.
  1287.           The scope and visibility of each entity is also defined.
  1288.  
  1289.                The object-oriented design methodology supports the
  1290.           principles of abstraction through information hiding.
  1291.           Abstractions are directly implemented from the problem
  1292.           space, providing a strategy for decomposing a system into
  1293.           modules in which design decisions are localized to match the
  1294.           "world view."
  1295.  
  1296.  
  1297.  
  1298.  
  1299.  
  1300.  
  1301.  
  1302.  
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.                                        19
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325.  
  1326.  
  1327.  
  1328.           2.3.2.  Dynamic Storage Management
  1329.  
  1330.                The concept of the name of an object is central to the
  1331.           design of a dynamic storage management mechanism.  A name is
  1332.           an access path to an object.  Variables occurring in the
  1333.           usual fashion in compiled programs are one kind of name, in
  1334.           this case the access path (at compile time) to the storage
  1335.           location allocated by the compiler for the variable at run-
  1336.           time.  A variable is a constant name;  an example of a
  1337.           dynamic name is the value of an Ada access type, which is
  1338.           the name of an object dynamically allocated at run-time.  An
  1339.           access to integer variable is the name of an access object,
  1340.           whose value is the name of an integer object whose value is
  1341.           an integer.  The problem of managing dynamically allocated
  1342.           storage is, at the level of Ada source code, a problem in
  1343.           the dynamic management of name values.
  1344.  
  1345.                A data object which is accessible via two different
  1346.           names is said to have aliases.  A simple example is seen
  1347.           with the Ada access type: if X contains an access value
  1348.           referencing an integer object, and X is assigned to Y
  1349.           (assuming both X and Y are assignment compatible), then both
  1350.           X and Y contain alias names for the same integer object.
  1351.           Changing the value of that integer object can be accom-
  1352.           plished using the value assigned either to X or to Y as its
  1353.           name.
  1354.  
  1355.                Alias names cause a problem when there is an operation
  1356.           which causes a dynamically allocated object to become deal-
  1357.           located.  A deallocated object is no longer in use, and so
  1358.           can be reused to satisfy another allocation request for
  1359.           dynamic storage space.  If a particular object has alias
  1360.           names, and one of those names is used as an argument to the
  1361.           operation which deallocates the object, then the alias names
  1362.           will reference a part of storage which is supposed to be
  1363.           currently inaccessible and available for reuse.  This situa-
  1364.           tion is referred to as dangling references.
  1365.  
  1366.                In order to address the dangling reference problem
  1367.           caused by alias names, there are various storage reclamation
  1368.           schemes which ensure that an object is not reused while
  1369.           there are outstanding names for the object.  The Ada stan-
  1370.           dard does not require an implementation to provide such a
  1371.           mechanism, although it is permitted.  The implementation of
  1372.           dynamic objects assumes that storage reclamation is not pro-
  1373.           vided.
  1374.  
  1375.                A storage reclamation scheme must either know the set
  1376.           of names referring to a particular object at all times, or
  1377.           else must know what names are available for referencing any
  1378.           object at all times and know the set of objects currently
  1379.           allocated.  The first alternative can be simplified to
  1380.           merely record the number of names for a particular object.
  1381.  
  1382.  
  1383.                                        20
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.           This is called reference counting, and permits incremental
  1395.           storage reclamation, since as soon as there are no names for
  1396.           an object, it can be deallocated.  The second alternative is
  1397.           referred to as garbage collection.  When the available free
  1398.           space for allocating new dynamic objects is exhausted, all
  1399.           objects accessible from the known set of available name
  1400.           values are marked as in use.  All dynamic objects not marked
  1401.           can then be reused.
  1402.  
  1403.                Either version of storage reclamation mentioned above
  1404.           is satisfactory within the run-time environment supporting
  1405.           either an interpreted language, such as LISP, or a compiled
  1406.           language, such as Ada.  Both an interpreter and a compiler
  1407.           can ensure that reference counting occurs where required,
  1408.           and both can ensure that the garbage collector knows the set
  1409.           of names which may reference dynamic storage.  Unfor-
  1410.           tunately, neither implementation is completely satisfactory
  1411.           if built on top of an interpreted or compiled language.  The
  1412.           reasons are discussed in the following subsections.
  1413.  
  1414.  
  1415.  
  1416.  
  1417.  
  1418.  
  1419.  
  1420.  
  1421.  
  1422.  
  1423.  
  1424.  
  1425.  
  1426.  
  1427.  
  1428.  
  1429.  
  1430.  
  1431.  
  1432.  
  1433.  
  1434.  
  1435.  
  1436.  
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.                                        21
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457.  
  1458.  
  1459.  
  1460.           2.3.2.1.  Reference Counting
  1461.  
  1462.                The reference counting scheme requires that a count of
  1463.           the number of different names by which a dynamic object can
  1464.           be referenced be maintained at all times.  In particular,
  1465.           this means that whenever a name value is assigned to a name
  1466.           variable, the reference count of the object named be incre-
  1467.           mented, and if the name variable originally referred to some
  1468.           other object, that object's reference count be decremented.
  1469.  
  1470.                Since the Ada assignment statement does not do this for
  1471.           us, an assignment operation must be defined and use of the
  1472.           Ada assignment statement should be prohibited.  Ada provides
  1473.           a mechanism for prohibiting the assignment statement by
  1474.           defining the type representing dynamic object names as lim-
  1475.           ited private.  Unfortunately, since assignment is a state-
  1476.           ment, overloading of the ":=" symbol is not permitted, so
  1477.           the assignment operation must be defined as a procedure.
  1478.           For any other symbolic expression operations, the internal
  1479.           implementation can maintain reference counts as required.
  1480.  
  1481.                If this were sufficient to reclaim all inaccessible
  1482.           dynamic object storage, the implementation would be
  1483.           extermely powerful and would hide all details of the recla-
  1484.           mation process from a programmer, even to the extent of hid-
  1485.           ing its existance.  The latter comment is significant, in
  1486.           that an implementation of symbolic expressions running on an
  1487.           Ada run-time system which supports automatic storage recla-
  1488.           mation could allow the run-time system to do the work, while
  1489.           an implementation running on a more restricted run-time sys-
  1490.           tem could take care of it, and the programmer would not have
  1491.           to consider the issue in his program.
  1492.  
  1493.                Nevertheless, the above approach is not without its
  1494.           problems.  While declaring types to be limited private does
  1495.           prevent the use of the assignment statement, this also has
  1496.           the unfortunate effect of prohibiting initializations, con-
  1497.           stants and default parameters and precludes a programmer
  1498.           from ignoring the storage management facilities if the Ada
  1499.           run-time system provides storage management.
  1500.  
  1501.                In addition, there are three important situations that
  1502.           arise when implementing reference counting on top of a run-
  1503.           time system which make it impossible to hide the fact that
  1504.           storage reclamation exists from a programmer.  These prob-
  1505.           lems affect the manner in which a programmer will have to
  1506.           write his code.  These situations are:
  1507.  
  1508.           (a)  Aliasing of names via subprogam parameters.
  1509.  
  1510.           (b)  Exit from the scope of a locally declared name vari-
  1511.                able.
  1512.  
  1513.  
  1514.  
  1515.                                        22
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.           (c)  Returning a name value as the result of a function.
  1527.  
  1528.                The real problem is that there is no compiler support
  1529.           for locating name values.  The only access to name values
  1530.           available to a Ada programmer is via name variables or name
  1531.           constants, whereas the compiler itself knows where all of
  1532.           the name values will be at run-time.
  1533.  
  1534.  
  1535.  
  1536.  
  1537.  
  1538.  
  1539.  
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550.  
  1551.  
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558.  
  1559.  
  1560.  
  1561.  
  1562.  
  1563.  
  1564.  
  1565.  
  1566.  
  1567.  
  1568.  
  1569.  
  1570.  
  1571.  
  1572.  
  1573.  
  1574.  
  1575.  
  1576.  
  1577.  
  1578.  
  1579.  
  1580.  
  1581.                                        23
  1582.  
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.  
  1591.  
  1592.           2.3.2.1.1.  Name Aliasing via Subprogram Parameters
  1593.  
  1594.                Within a subprogram with a parameter of the symbolic
  1595.           expression type, the formal parameter establishes a new
  1596.           alias for the object named by the actual parameter.  Since
  1597.           parameter passing is implemented below the level of storage
  1598.           management in this situation, the reference count of that
  1599.           object has not been properly adjusted.  If the programmer is
  1600.           allowed to use an operation on the formal parameter which
  1601.           adjusts the reference count downward, the dynamic object's
  1602.           reference count may reach zero prematurely, and be treated
  1603.           as inaccessible by the storage reclamation process.  At this
  1604.           point, the actual parameter may now contain a dangling
  1605.           reference.  On the other hand, if the actual parameter is a
  1606.           visible global (with respect to the subprogram) variable and
  1607.           this variable is used as an argument to an operation which
  1608.           adjusts the reference count downward, resulting in the
  1609.           object becoming reclaimed, the formal parameter name con-
  1610.           tains a dangling reference.  This latter case is a side
  1611.           effect that happens to be defined as an erroneous program by
  1612.           the Ada standard <6.2, 13>, since the standard then defines
  1613.           the formal parameter to have an undefined value.
  1614.  
  1615.                Assume that the symbolic expression type is defined as
  1616.           limited private in order to prevent use of the Ada assign-
  1617.           ment statement, forcing the type to be used only as a sub-
  1618.           program parameter of mode in.  If all operations which can
  1619.           have the internal effect of modifying a reference count have
  1620.           the appropriate parameters defined as mode in out, then the
  1621.           programmer will be prohibited from using these operations on
  1622.           subprogram formal parameters, thus enforcing the Ada
  1623.           interpretation of a formal parameter of mode in as a local
  1624.           constant.  This will force all operations which may reclaim
  1625.           object space to be applied only to variables.  This will not
  1626.           prevent the programmer from getting into the second situa-
  1627.           tion, unless the run-time system can enforce it.
  1628.  
  1629.                The disadvantage of this solution is that, since the
  1630.           programmer cannot pass symbolic expressions as output param-
  1631.           eters from a subprogram, it will encourage use of global
  1632.           variables, which tends to be discouraged by most of the
  1633.           recent program design methodologies.  This solution does, on
  1634.           the other hand, tend to encourage a functional programming
  1635.           style of program design, where the only way to get new
  1636.           values is as the returned value of a function subprogram
  1637.           with no side effects on function parameters.  Unfortunately,
  1638.           the process of returning a symbolic expression value from a
  1639.           function has its own problems, discussed later.
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.                                        24
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.  
  1657.  
  1658.           2.3.2.1.2.  Scope Exit for a Local Variable
  1659.  
  1660.                If a dynamic object is created and its name value
  1661.           assigned only to a name variable declared in a local
  1662.           declaration scope, then on exit from that scope, the dynamic
  1663.           object can be reclaimed since there are no longer any refer-
  1664.           ences to it.  However, with no interpreter/compiler support
  1665.           for object reclamation, the programmer must be relied upon
  1666.           to explicitly indicate this situation.  Therefore, he must
  1667.           be given a special operation to be used to indicate to the
  1668.           dynamic storage reclamation process that a name value is to
  1669.           be eliminated, causing the reference count of the named
  1670.           object to be decremented.
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.  
  1681.  
  1682.  
  1683.  
  1684.  
  1685.  
  1686.  
  1687.  
  1688.  
  1689.  
  1690.  
  1691.  
  1692.  
  1693.  
  1694.  
  1695.  
  1696.  
  1697.  
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.  
  1713.                                        25
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722.  
  1723.  
  1724.           2.3.2.1.3.  Returning a Value from a Function
  1725.  
  1726.                In order to conveniently manipulate dynamic objects,
  1727.           the objects themselves are seldom actually copied.  Instead,
  1728.           names of dynamic objects are manipulated as values (in Ada,
  1729.           as values of some access type).  As previously discussed,
  1730.           all formal parameters of the symbolic expression type will
  1731.           be local constant name values within a subprogram, and so
  1732.           cannot be used as name variables to construct a new symbolic
  1733.           expression value to return as a function result.  Also, the
  1734.           programmer must explicitly apply a deallocation operation to
  1735.           all local name variables before leaving a declaration scope,
  1736.           which includes the body of a subprogram.
  1737.  
  1738.                There are two aspects of this situation which cause
  1739.           problems, which are really the two sides of the more general
  1740.           issue of how to deal with a temporary name value.  On the
  1741.           one hand, a name value which is not currently assigned to
  1742.           any name variable needs to be treated as naming a dynamic
  1743.           object with reference count zero, so that when that value is
  1744.           assigned to a name variable, the assignment operation, which
  1745.           increments reference counts, will leave the reference count
  1746.           at one.  On the other hand, within the function body, the
  1747.           name value is most likely assigned to a local name variable
  1748.           which will be used as the expression of the Ada return
  1749.           statement to define the result value of the function call.
  1750.           Since the value is assigned to a variable, it has reference
  1751.           count equal to (at least) one, so the value of the function
  1752.           call, when assigned to a variable of the outer dynamic
  1753.           range, will have a reference count equal to (at least) two.
  1754.           In this situation, the dynamic object named appears to have
  1755.           more alias names than it actually has, so the dynamic object
  1756.           storage will never be reclaimed by the storage reclamation
  1757.           process.
  1758.  
  1759.                As additional problem arises if the returned value is
  1760.           never assigned to a variable, but rather is immediately
  1761.           passed as an actual parameter of some other subprogram call,
  1762.           which never internally assigns it to a variable.  In this
  1763.           situation, there is no name variable available with which to
  1764.           free the dynamic object.
  1765.  
  1766.                A function result can be arranged to have the appropri-
  1767.           ate reference count only if the programmer is given a spe-
  1768.           cial operation to be used only as the result expression of a
  1769.           return statement within a function subprogram which needs to
  1770.           get its return value from a local variable.  The parameter
  1771.           of this function could only be a name variable which con-
  1772.           tains the name value of the desired result of the function
  1773.           call.  Since there is no way to enforce proper use of this
  1774.           special operation, it would have to be up to the programmer
  1775.           to use it where it is required, and only where it is
  1776.           required, which is an undesirable but inescapable situation.
  1777.  
  1778.  
  1779.                                        26
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.  
  1787.  
  1788.  
  1789.  
  1790.           The problem arising from never assigning a name value
  1791.           returned from a function cannot be solved without explaining
  1792.           the situation to the programmer and leaving it up to him to
  1793.           do the right thing in each particular situation.  An easy
  1794.           convention would be, of course, to always assign the result
  1795.           of a function call to a variable.
  1796.  
  1797.                Alternatives considered, but abandoned as needlessly
  1798.           complex, included the following:
  1799.  
  1800.           (a)  Attach the names of all newly created dynamic objects,
  1801.                or those which are returned from a function via a spe-
  1802.                cial result operation with reference count equal to
  1803.                zero, to some globally known list of temporary values.
  1804.                The assignment operation applied to a name value on
  1805.                this list removes it from the list.  Name values left
  1806.                hanging around on this list must be reclaimed by a spe-
  1807.                cial operation invoked by the programmer when he knows
  1808.                that all possible temporary values are no longer
  1809.                required.
  1810.  
  1811.           (b)  Provide dynamic scope start and end operations.  All
  1812.                symbolic expression variables would have to be attached
  1813.                to some dynamic scope by use of a dynamic instantiation
  1814.                operation separate from the Ada declaration.  All tem-
  1815.                porary values not assigned to a variable are also
  1816.                attached to the current dynamic scope; values returned
  1817.                from functions via a special result operation with
  1818.                reference count equal to zero are attached to the
  1819.                dynamic scope enclosing the location of the function
  1820.                call.  On execution of the dynamic scope end operation,
  1821.                all values local to the dynamic scope are reclaimed.
  1822.  
  1823.  
  1824.  
  1825.  
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831.  
  1832.  
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.  
  1842.  
  1843.  
  1844.  
  1845.                                        27
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855.  
  1856.           2.3.2.2.  Garbage Collection
  1857.  
  1858.                Implementing a garbage collector is somewhat cumbersome
  1859.           in a language like Ada, since the only useful characteriza-
  1860.           tion of names is the name variable.  The only entity that
  1861.           knows about the locations of name values is the compiler.
  1862.           Therefore, name value tracking has to be implemented as name
  1863.           variable tracking, using some mechanism for maintaining a
  1864.           collection of dynamic name variables.  The approaches are
  1865.           all variations of the same basic theme of implementing the
  1866.           symbolic expression type as a reference to some dynamically
  1867.           allocated component of an object known to the storage allo-
  1868.           cation and reclamation operations.  Each such component is,
  1869.           or contains, a slot which is a name variable.
  1870.  
  1871.                Given this approach, whenever desired, the storage rec-
  1872.           lamation process knows where all of the name values for
  1873.           dynamic objects can be found, and, if it can also gain
  1874.           access to all allocated dynamic objects, it can mark all
  1875.           objects accessible from any name value and then locate all
  1876.           unmarked objects, which can be reclaimed.
  1877.  
  1878.                If each variable of type symbolic expression is allo-
  1879.           cated to a unique name variable in this global set of names,
  1880.           then the problems associated with aliasing via subprogram
  1881.           parameters, as discussed for reference counting, go away in
  1882.           the sense that side effects are consistently propagated to
  1883.           all aliases.  Operations which reclaim dynamic storage do
  1884.           not change the set of currently active names, so both
  1885.           aliases generated by an actual/formal parameter association
  1886.           always share the same dynamic object (or lack thereof).
  1887.           This has the disadvantage of potentially violating the
  1888.           spirit of Ada's parameter mode in, since a formal parameter
  1889.           could be modified and thus modify the actual parameter even
  1890.           in this mode.
  1891.  
  1892.                The problems associated with exit from the scope of a
  1893.           locally declared symbolic expression variable and with
  1894.           returning a symbolic expression as the result of a function
  1895.           call are essentially unchanged, requiring the same basic
  1896.           solutions, which are not repeated here.
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  1911.                                        28
  1912.  
  1913.  
  1914.  
  1915.  
  1916.  
  1917.  
  1918.  
  1919.  
  1920.  
  1921.  
  1922.           2.3.2.3.  Summary
  1923.  
  1924.                Based upon the previous discussion, two subprograms
  1925.           will be provided for each AI data type to assist in storage
  1926.           management.
  1927.  
  1928.           (a)  A procedure to indicate that a variable is at the end
  1929.                of its scope and that its contents should be deallo-
  1930.                cated.
  1931.  
  1932.           (b)  A function which can decrement the reference count of a
  1933.                variable which is used to return a value from a func-
  1934.                tion.
  1935.  
  1936.                In addition, it has been determined that the use of
  1937.           limited private types will not provide sufficient assistance
  1938.           with storage management to overcome the disadvantages they
  1939.           impose.  Therefore, it has been decided that the AI data
  1940.           types developed in these packages be declared as private to
  1941.           provide sufficient data encapsulation without undue restric-
  1942.           tions.
  1943.  
  1944.  
  1945.  
  1946.  
  1947.  
  1948.  
  1949.  
  1950.  
  1951.  
  1952.  
  1953.  
  1954.  
  1955.  
  1956.  
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.                                        29
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.  
  1988.           2.3.3.  Multi-Tasking Synchronization
  1989.  
  1990.                Ada provides a powerful and general multi-tasking
  1991.           mechanism as an integral part of the language.  A task is an
  1992.           independent flow of control which interfaces in a discip-
  1993.           lined way with other flows of control, each with its own
  1994.           internal data.  The tasking constructs provide intertask
  1995.           communication using message passing.  The fact that tasks
  1996.           provide a high-level synchronization capability, and are the
  1997.           only Ada data type to provide such a capability, means that
  1998.           there will be many situations in which tasks will be used
  1999.           purely as a synchronizing mechanism to implement other con-
  2000.           trol abstractions, such as co-routines.
  2001.  
  2002.                In addition to high-level communication constructs,
  2003.           tasks provide high-level access to facilities commonly pro-
  2004.           vided in a machine-dependent fashion in other languages.
  2005.           For example, the delay statement enables a task to suspend
  2006.           its execution until at least the specified time interval has
  2007.           elapsed, allowing a program to control the frequency of its
  2008.           execution.
  2009.  
  2010.                Once the use of tasks as a primitive construct out of
  2011.           which more complex abstractions are built becomes common-
  2012.           place, complex applications composed of explicitly con-
  2013.           current or parallel processes will become readily accepted
  2014.           solutions.  Under these conditions, the problems of effi-
  2015.           ciently synchronizing access to shared global data must be
  2016.           dealt with.  This will become especially important when, for
  2017.           example, expert systems technology is applied to airborne
  2018.           applications and is installed within embedded computers in a
  2019.           multi-tasking environment.  Expecting that synchronization
  2020.           can be efficiently accomplished outside of the implementa-
  2021.           tion package for symbolic expressions is probably naive.
  2022.           This is especially true if the implementation of symbolic
  2023.           expressions includes hidden structure sharing.  It is more
  2024.           reasonable to expect that a version of the symbolic expres-
  2025.           sion package will be available which provides, internally,
  2026.           the proper synchronization efficiently tailored to the par-
  2027.           ticular implementation.
  2028.  
  2029.                The initial implementation will not provide such inter-
  2030.           nal synchronization mechanisms.  However, the interface to
  2031.           the symbolic expression facilities will be designed to allow
  2032.           such synchronization to be installed at the lowest implemen-
  2033.           tation levels within another version of the product without
  2034.           requiring changes to the visible interface.
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.                                        30
  2044.  
  2045.  
  2046.  
  2047.  
  2048.  
  2049.  
  2050.  
  2051.  
  2052.  
  2053.  
  2054.           3.  Functional Specifications
  2055.  
  2056.                All visible Ada type identifiers which represent the
  2057.           visible objects defined below will be defined as private.
  2058.           This will ensure that only the provided operations will be
  2059.           used to manipulate these objects.
  2060.  
  2061.           3.1.  Rulebases
  2062.  
  2063.           3.1.1.  Introduction
  2064.  
  2065.                The two major design decisions for rules are how to
  2066.           represent them and where to put them for fast retrieval.
  2067.           Retrieval of rules is independent of rule representation, so
  2068.           the approach taken is to encapsulate the retrieval issues
  2069.           within objects representing rulebases.  The representation
  2070.           issues for rules will be deferred to a lower level of
  2071.           abstraction.
  2072.  
  2073.                The term rulebase, as used here, refers to a collection
  2074.           of rules and facts representing a knowledge base, or to a
  2075.           temporary collection of facts, rules and a query represent-
  2076.           ing the current state of computation for a problem.
  2077.  
  2078.                Structure sharing is an important criteria for this
  2079.           implementation in order to avoid generating an exploding
  2080.           requirement for storage when rule data bases are manipulated
  2081.           with set operations which may be used to implement certain
  2082.           control strategies.
  2083.  
  2084.                An obvious solution to the requirement for fast
  2085.           retrieval is to provide some type of internal indexing of
  2086.           the rules present in a data base.  Since it is assumed that
  2087.           the structure of a rule is a set of terms in predicate form,
  2088.           separated by ANDs and ORs, a simple approach would be to
  2089.           build a hash table indexing the predicate symbols of each of
  2090.           the terms in a rule.
  2091.  
  2092.  
  2093.  
  2094.           3.1.2.  Objects
  2095.  
  2096.           (a)  Rulebase, which provides associative access, or content
  2097.                addressing, for its contents.  Retrieval of the con-
  2098.                tents is achieved by pattern-directed retrieval, which
  2099.                will allow access of the data base contents by partial
  2100.                specification of the desired content of a retrieval.
  2101.                Rulebase variables will allow implementation of
  2102.                extremely flexible control strategies for expert system
  2103.                and logic programming implementation.  For example,
  2104.                conditional execution of subsets of rules can be imple-
  2105.                mented by separating rules into individual rulebases
  2106.                which are selected for use at each unification step
  2107.  
  2108.  
  2109.                                        31
  2110.  
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118.  
  2119.  
  2120.                using Ada's conditional control structures.  The set of
  2121.                rulebases could be implemented as an array of rule-
  2122.                bases.  This would provide a powerful mixture of non-
  2123.                procedural programming with the more conventional pro-
  2124.                cedural facilities of Ada.  This also eliminates the
  2125.                restriction to a single knowledge base common to con-
  2126.                ventional logic programming and production systems.
  2127.  
  2128.           (b)  The null rulebase, a constant representing a rulebase
  2129.                which has no rules.
  2130.  
  2131.  
  2132.  
  2133.           3.1.3.  Operations
  2134.  
  2135.           3.1.3.1.  Rulebase Operations
  2136.  
  2137.           (a)  Determine if a rulebase is empty.
  2138.  
  2139.           (b)  Determine if two rulebases are equivalent.
  2140.  
  2141.           (c)  Convert a rulebase to a symbolic expression.
  2142.  
  2143.           (d)  Convert a symbolic expression to a rulebase.
  2144.  
  2145.           (e)  Assign values to variables of type rulebase.
  2146.  
  2147.           (f)  Delete an unused rulebase.
  2148.  
  2149.           (g)  Return a rulebase bound to a local variable as the
  2150.                value of a function.
  2151.  
  2152.           (h)  Add a rule to a rulebase.
  2153.  
  2154.           (i)  Delete a rule from a rulebase.
  2155.  
  2156.           (j)  Associative retrieval using a rule as a query, yielding
  2157.                a symbolic expression containing instantiated values
  2158.                which satisfy the query.
  2159.  
  2160.           (k)  Set operations on rulebases - union ("and"), intersec-
  2161.                tion ("or"), difference ("-") and exclusive union
  2162.                ("xor").
  2163.  
  2164.           (l)  Input/output operations for rulebases.
  2165.  
  2166.                The conversion from/to symbolic exrepssions provides a
  2167.           primitive inteface between the symbolic computation facility
  2168.           and the logic programming facility.  The control strategies
  2169.           for logic programming all need some form of matching with
  2170.           variable binding, which suggests that the antecedent and
  2171.           consequent of a generalized rule should be implemented using
  2172.           patterns with pattern matching operations defined.  It is
  2173.  
  2174.  
  2175.                                        32
  2176.  
  2177.  
  2178.  
  2179.  
  2180.  
  2181.  
  2182.  
  2183.  
  2184.  
  2185.  
  2186.           intended that the contents of a rulebase are uninstantiated
  2187.           rules.
  2188.  
  2189.  
  2190.  
  2191.  
  2192.  
  2193.  
  2194.  
  2195.  
  2196.  
  2197.  
  2198.  
  2199.  
  2200.  
  2201.  
  2202.  
  2203.  
  2204.  
  2205.  
  2206.  
  2207.  
  2208.  
  2209.  
  2210.  
  2211.  
  2212.  
  2213.  
  2214.  
  2215.  
  2216.  
  2217.  
  2218.  
  2219.  
  2220.  
  2221.  
  2222.  
  2223.  
  2224.  
  2225.  
  2226.  
  2227.  
  2228.  
  2229.  
  2230.  
  2231.  
  2232.  
  2233.  
  2234.  
  2235.  
  2236.  
  2237.  
  2238.  
  2239.  
  2240.  
  2241.                                        33
  2242.  
  2243.  
  2244.  
  2245.  
  2246.  
  2247.  
  2248.  
  2249.  
  2250.  
  2251.  
  2252.           3.2.  Rules
  2253.  
  2254.           3.2.1.  Introduction
  2255.  
  2256.                The representation of rules depends primarily upon how
  2257.           variables are represented.  We will implement rules in terms
  2258.           of patterns and defer this issue to a lower level in the
  2259.           abstraction hierarchy.
  2260.  
  2261.  
  2262.  
  2263.           3.2.2.  Objects
  2264.  
  2265.                Other than as stated below, no interpretation is
  2266.           imposed by this level of abstraction on the contents of a
  2267.           rule.  Rules are represented as a data structure consisting
  2268.           of a template and a (possibly null) binding context.  The
  2269.           template is a pattern consisting of two sub-patterns which
  2270.           represent the (possibly null) antecedent and consequent
  2271.           parts.  When a rule is created, the two sub-patterns are
  2272.           treated as a single pattern so that the variable binding
  2273.           context is shared by both components of the rule template.
  2274.           This allows variable bindings to apply across an entire
  2275.           rule.
  2276.  
  2277.           (a)  Rules, which are a subtype of rule composed of a conse-
  2278.                quent, or head, and an antecedent, or body;  the
  2279.                interpretation of a rule is that the truth of the
  2280.                antecedent implies the truth of the consequent;
  2281.  
  2282.           (b)  Facts, which are a subtype of rule composed of a conse-
  2283.                quent only;  the interpretation of a fact is that the
  2284.                truth of the consequent does not depend on anything;
  2285.  
  2286.           (c)  Querys, which are a subtype of rule composed of an
  2287.                antecedent only;  the interpretation of a query is that
  2288.                the truth of the antecedent is unknown, but may be
  2289.                inferred from some collection of facts and rules with
  2290.                an appropriate inference mechanism;
  2291.  
  2292.           (d)  Variable binding context, which are associated with an
  2293.                instance of a rule during rule matching operations, and
  2294.                keep track of variable bindings.
  2295.  
  2296.           (e)  The null rule, a constant representing a rule which has
  2297.                a null antecedent, consequent and binding context.
  2298.  
  2299.  
  2300.  
  2301.           3.2.3.  Operations
  2302.  
  2303.           (a)  Determine if a rule is null.
  2304.  
  2305.  
  2306.  
  2307.                                        34
  2308.  
  2309.  
  2310.  
  2311.  
  2312.  
  2313.  
  2314.  
  2315.  
  2316.  
  2317.  
  2318.           (b)  Determine if one rule is equal to another.
  2319.  
  2320.           (c)  Determine if a rule is a fact, query or general rule.
  2321.  
  2322.           (d)  Create a rule by conversion from a symbolic expression.
  2323.  
  2324.           (e)  Convert a rule back to a symbolic expression.
  2325.  
  2326.           (f)  Extract the antecedent or consequent from a rule as a
  2327.                pattern.  The variable binding context of the extracted
  2328.                component is shared with the original rule.
  2329.  
  2330.           (g)  Extract the variable binding context from a rule.
  2331.  
  2332.           (h)  Associate a specific variable binding context with a
  2333.                rule.
  2334.  
  2335.           (i)  Match two rules, retaining variable bindings in the
  2336.                associated variable binding contexts.
  2337.  
  2338.           (j)  Instantiate a rule, yielding a symbolic expression with
  2339.                all variables replaced by the values to which they are
  2340.                bound.
  2341.  
  2342.           (k)  Make a rule unique by uniquely renaming all variables
  2343.                within the rule.
  2344.  
  2345.           (l)  Assign values to variables of type rule.
  2346.  
  2347.           (m)  Delete an unused rule value or rule instance value.
  2348.  
  2349.           (n)  Return a rule value bound to a local variable as the
  2350.                value of a function.
  2351.  
  2352.           (o)  Input/output operations for rules.
  2353.  
  2354.  
  2355.  
  2356.  
  2357.  
  2358.  
  2359.  
  2360.  
  2361.  
  2362.  
  2363.  
  2364.  
  2365.  
  2366.  
  2367.  
  2368.  
  2369.  
  2370.  
  2371.  
  2372.  
  2373.                                        35
  2374.  
  2375.  
  2376.  
  2377.  
  2378.  
  2379.  
  2380.  
  2381.  
  2382.  
  2383.  
  2384.           3.3.  Patterns
  2385.  
  2386.           3.3.1.  Introduction
  2387.  
  2388.                The representation of patterns depends upon how vari-
  2389.           ables are to be represented.  Our approach is based upon
  2390.           structure sharing of the literals of a pattern (the tem-
  2391.           plate) with binding list which is unique to each instance of
  2392.           a pattern.
  2393.  
  2394.           3.3.2.  Objects
  2395.  
  2396.           (a)  Pattern variables, which are special atomic components
  2397.                of a symbolic expression used to indicate component
  2398.                positions in an expression which will match an arbi-
  2399.                trary component of another expression.
  2400.  
  2401.           (b)  Patterns, which are symbolic expressions consisting of
  2402.                a pattern (possibly null) template and a (possibly
  2403.                null) binding context.
  2404.  
  2405.           (c)  Variable binding contexts, a collection of variable
  2406.                binding associations used to hold the result of a match
  2407.                operation for variables of a given pattern. Variable
  2408.                binding contexts are unique to a particular pattern,
  2409.                but may be shared by a pattern which is extracted from
  2410.                some other pattern.
  2411.  
  2412.           (d)  The null pattern, a constant representing a pattern
  2413.                with a null template and binding context.
  2414.  
  2415.  
  2416.  
  2417.           3.3.3.  Operations
  2418.  
  2419.           (a)  Determine if a pattern is null.
  2420.  
  2421.           (b)  Determine if one pattern is equal to another.
  2422.  
  2423.           (c)  Create a pattern by conversion from a symbolic expres-
  2424.                sion.
  2425.  
  2426.           (d)  Convert a pattern back to a symbolic expression.
  2427.  
  2428.           (e)  Extract the first component from a pattern.  The vari-
  2429.                able binding context of the extracted component is
  2430.                shared with the original pattern.
  2431.  
  2432.           (f)  Extract all components except the first from a pattern.
  2433.                The variable binding context of the extracted com-
  2434.                ponents is shared with the original pattern.
  2435.  
  2436.  
  2437.  
  2438.  
  2439.                                        36
  2440.  
  2441.  
  2442.  
  2443.  
  2444.  
  2445.  
  2446.  
  2447.  
  2448.  
  2449.  
  2450.           (g)  Extract the variable binding context from a pattern.
  2451.  
  2452.           (h)  Associate a specific variable binding context with a
  2453.                pattern.
  2454.  
  2455.           (i)  Match two patterns, retaining variable bindings in the
  2456.                associated variable binding contexts.
  2457.  
  2458.           (j)  Instantiate a pattern, yielding a symbolic expression
  2459.                with all variables replaced by the values to which they
  2460.                are bound.
  2461.  
  2462.           (k)  Make a pattern unique by uniquely renaming all vari-
  2463.                ables within the pattern.
  2464.  
  2465.           (l)  Assign values to variables of type pattern.
  2466.  
  2467.           (m)  Delete an unused pattern.
  2468.  
  2469.           (n)  Return a pattern bound to a local variable as the value
  2470.                of a function.
  2471.  
  2472.           (o)  Input/output operations for patterns.
  2473.  
  2474.  
  2475.  
  2476.  
  2477.  
  2478.  
  2479.  
  2480.  
  2481.  
  2482.  
  2483.  
  2484.  
  2485.  
  2486.  
  2487.  
  2488.  
  2489.  
  2490.  
  2491.  
  2492.  
  2493.  
  2494.  
  2495.  
  2496.  
  2497.  
  2498.  
  2499.  
  2500.  
  2501.  
  2502.  
  2503.  
  2504.  
  2505.                                        37
  2506.  
  2507.  
  2508.  
  2509.  
  2510.  
  2511.  
  2512.  
  2513.  
  2514.  
  2515.  
  2516.           3.4.  Symbolic Expressions
  2517.  
  2518.           3.4.1.  Introduction
  2519.  
  2520.                A symbolic expression is either null, or is a single
  2521.           atomic component, or is an ordered collection of components,
  2522.           each of which is itself a symbolic expression.
  2523.  
  2524.                At each level of recursion in a symbolic expression,
  2525.           the components are ordered sequentially.  Consequently, it
  2526.           is easiest to deal with symbolic expressions in terms of
  2527.           this sequential component ordering.  A non-atomic symbolic
  2528.           expression is considered to have a first, component, which
  2529.           can be extracted directly.  The only other primitive access
  2530.           operation is to extract everything except the first com-
  2531.           ponent, that is, to extract the rest of the symbolic expres-
  2532.           sion.  The primitive construction operation prefix is the
  2533.           direct inverse of these two access operations, and makes two
  2534.           symbolic expressions into the first and rest components of a
  2535.           new symbolic expression.  Most of the other symbolic expres-
  2536.           sion manipulation operations are provided for efficiency and
  2537.           ease-of-use only, as they can all be defined in terms of
  2538.           these primitives.
  2539.  
  2540.  
  2541.  
  2542.           3.4.2.  Objects
  2543.  
  2544.           (a)  Atomic expressions, which contain values of some
  2545.                application-defined type.  It is assumed that, for any
  2546.                AI production program, the values of an atomic expres-
  2547.                sion are from at most a finite set of types.  The
  2548.                application developer can define the atomic type as a
  2549.                record with variant part encompassing the set of types
  2550.                if there is more than one atomic type required.
  2551.  
  2552.           (b)  Non-atomic expressions, which consist of an ordered
  2553.                collection of components, each of which is itself a
  2554.                symbolic expression.
  2555.  
  2556.           (c)  The null symbolic expression, which may be considered
  2557.                either atomic or non-atomic, depending on the context.
  2558.  
  2559.                The actual structure of a symbolic expression will be
  2560.           hidden from the user.
  2561.  
  2562.           3.4.3.  Operations
  2563.  
  2564.           (a)  Determine if a symbolic expression is null.
  2565.  
  2566.           (b)  Determine if a symbolic expression is atomic.
  2567.  
  2568.  
  2569.  
  2570.  
  2571.                                        38
  2572.  
  2573.  
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580.  
  2581.  
  2582.           (c)  Determine if a symbolic expression is non-atomic.
  2583.  
  2584.           (d)  Determine if a symbolic expression is a variable.
  2585.  
  2586.           (e)  Determine if one symbolic expression is equal to
  2587.                another.
  2588.  
  2589.           (f)  Determine if one symbolic expression is a member of
  2590.                another.
  2591.  
  2592.           (g)  Create a symbolic expression from a user-supplied
  2593.                atomic value.
  2594.  
  2595.           (h)  Create a symbolic expression variable with a given
  2596.                name.
  2597.  
  2598.           (i)  Set the tag associated with a symbolic expression vari-
  2599.                able.
  2600.  
  2601.           (j)  Extract the user-supplied atomic value from a given
  2602.                atomic symbolic expression.
  2603.  
  2604.           (k)  Extract the name from a given symbolic expression vari-
  2605.                able.
  2606.  
  2607.           (l)  Extract the tag from a given symbolic expression vari-
  2608.                able.
  2609.  
  2610.           (m)  Assign values to variables of type symbolic expression.
  2611.  
  2612.           (n)  Delete an unused symbolic expression.
  2613.  
  2614.           (o)  Return a symbolic expression bound to a local variable
  2615.                as the value of a function.
  2616.  
  2617.           (p)  Prefix one symbolic expression onto another.
  2618.  
  2619.           (q)  Append one symbolic expression onto another.
  2620.  
  2621.           (r)  Determine the length (number of top-level components)
  2622.                of a symbolic expression.
  2623.  
  2624.           (s)  Extract the first component of a symbolic expression.
  2625.  
  2626.           (t)  Extract all components except the first of a symbolic
  2627.                expression.
  2628.  
  2629.           (u)  Extract the last component of a symbolic expression.
  2630.  
  2631.           (v)  Extract the nth component of a symbolic expression.
  2632.  
  2633.           (w)  Extract the first component of a symbolic expression n
  2634.                times using the result of the previous extraction as
  2635.  
  2636.  
  2637.                                        39
  2638.  
  2639.  
  2640.  
  2641.  
  2642.  
  2643.  
  2644.  
  2645.  
  2646.  
  2647.  
  2648.                the new argument.
  2649.  
  2650.           (x)  Extract all components except the first of a symbolic
  2651.                expression n times using the result of the previous
  2652.                extraction as the new argument.
  2653.  
  2654.           (y)  Reverse the order of components within a symbolic
  2655.                expression.
  2656.  
  2657.           (z)  Delete all top-level occurrences of one symbolic
  2658.                expression from another.
  2659.  
  2660.           (aa) Replace all top-level occurrences of one symbolic
  2661.                expression within another with a new symbolic expres-
  2662.                sion.
  2663.  
  2664.           (bb) Flatten a symbolic expression by extracting all non-
  2665.                atomic components while retaining all atomic components
  2666.                of the given symbolic expression.
  2667.  
  2668.           (cc) Set operations on symbolic expressions - union ("and"),
  2669.                intersection ("or"), difference ("-") and exclusive
  2670.                union ("xor").
  2671.  
  2672.           (dd) Extract either the first or all the non-atomic com-
  2673.                ponents of a symbolic expression whose first component
  2674.                matches a given symbolic expression.
  2675.  
  2676.           (ee) Input/output operations for symbolic expressions.
  2677.  
  2678.  
  2679.  
  2680.  
  2681.  
  2682.  
  2683.  
  2684.  
  2685.  
  2686.  
  2687.  
  2688.  
  2689.  
  2690.  
  2691.  
  2692.  
  2693.  
  2694.  
  2695.  
  2696.  
  2697.  
  2698.  
  2699.  
  2700.  
  2701.  
  2702.  
  2703.                                        40
  2704.