home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / ai / alsptech.doc < prev    next >
Encoding:
Text File  |  1988-05-03  |  124.5 KB  |  3,829 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.                          Top Level Design Specification
  22.                                       and
  23.                              Final Technical Report
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.                                  SAE-DC-85-R001
  34.  
  35.  
  36.                                  March 17, 1986
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.                    Software Architecture & Engineering, Inc.
  46.                         1600 Wilson Boulevard, Suite 500
  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.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.                          Top-Level Design Specification
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.           1.  Introduction
  141.  
  142.                Recognition is growing rapidly of the potential appli-
  143.           cations of Artifical Intelligence (AI) technology in Depart-
  144.           ment of Defense (DOD) Command and Control (C2) and mission
  145.           critical systems.  AI techniques will play key roles in many
  146.           of these systems in the near future.  One factor that will
  147.           slow this trend is the fact that most currently successful
  148.           AI applications are implemented, either directly or
  149.           indirectly, in LISP.  Ada is the required language for new
  150.           DOD (embedded) application software.  The creation of a
  151.           package library to aid in the development of AI applica-
  152.           tions, along with tools that allow efficient translation of
  153.           existing LISP-based AI applications into Ada, will allow the
  154.           DOD to take advantage of the opportunities offerred by AI
  155.           technology.
  156.  
  157.                Logic programming is an important development in AI
  158.           programming techniques.  Its implementation in the form of
  159.           PROLOG has produced a language of tremendous potential, par-
  160.           ticularly in the area of knowledge-based expert systems.
  161.           The development of a logic programming capability within
  162.           Ada, again through a package library, will allow programmers
  163.           to capitalize on this emerging technology within new AI
  164.           applications.
  165.  
  166.  
  167.  
  168.           1.1.  Purpose
  169.  
  170.                The capabilities offerred by a synthesis of the conven-
  171.           tional software engineering technology supported by Ada in
  172.           combination with symbolic computation and logic programming
  173.           techniques will produce a C2 programming support environment
  174.           of impressive power.  This document describes the top-level
  175.           design of a collection of Ada packages sufficient to provide
  176.           such capabilities for developers of C2 applications in Ada,
  177.           and to provide the basis for translation of LISP-based AI
  178.           applications into Ada.
  179.  
  180.                This document, the Top-Level Design Specification, is
  181.           part one of two of the final delivery of CDRL A002 (Informal
  182.           Technical Information) for contract N66001-85-C-0039 between
  183.           Software Architecture and Engineering, Inc., and Naval Ocean
  184.           Systems Center, 271 Catalina Boulevard, Building A33, San
  185.           Diego, CA  92152.
  186.  
  187.  
  188.  
  189.           1.2.  Scope
  190.  
  191.                AI technology, and, more specifically, knowledge-based
  192.           expert systems, are proving to be of value in decision
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.           support, target classification, indications and warning, and
  207.           many other C2-related areas.  AI offers the opportunity to
  208.           vastly increase the amount of information that can be
  209.           analyzed in a timely fashion, information that might other-
  210.           wise go unused due to the sheer volume generated by present
  211.           day sensors and intelligence systems.  This volume will only
  212.           grow, as these systems evolve, without some type of filter-
  213.           ing agent.  The effective use of AI techniques can have the
  214.           effect of significantly increasing the power of our current
  215.           C2 systems by providing that filtering mechanism.
  216.  
  217.                Today, LISP (of some type) is the most prevalent
  218.           language used to implement AI applications.  The reason for
  219.           this is that the major current LISP dialects provide power-
  220.           ful symbolic processing facilities not provided by the
  221.           majority of modern, block-structured, higher-order, conven-
  222.           tional programming languages.  These conventional languages
  223.           do not exclude symbolic processing, they just do not provide
  224.           language-based facilities for such manipulations.  As a
  225.           result, the AI design paradigms used with LISP are not
  226.           easily implemented in languages like Ada.  Ada can be used
  227.           to implement AI applications if it is augmented with capa-
  228.           bilities which emulate some of the unique aspects of the
  229.           symbolic manipulation facilities of LISP.  This can be
  230.           accomplished through specially designed Ada packages.
  231.  
  232.                Logic programming systems are a direct implementation,
  233.           in the form of a programming language, of the general con-
  234.           cept of a production system, discussed in detail later in
  235.           this document.  Logic programming languages, like PROLOG and
  236.           the OPS family, are directly useful in implementing
  237.           knowledge-based expert systems where knowledge is primarily
  238.           representable in the form of rules.  However, in general,
  239.           the use of a logic programming facility provides a powerful,
  240.           yet extraordinarily concise, technique for developing appli-
  241.           cations which must do any kind of symbolic reasoning, that
  242.           is, reasoning about logical relationships among symbolic
  243.           data items.  LISP-based AI applications which need to per-
  244.           form this function implement reasoning functions and data
  245.           structures tailored to the application.  Rather than require
  246.           an application developer to invent unique reasoning systems,
  247.           Ada provides the mechanism to augment the language with fun-
  248.           damental logic programming facilities.  These facilities can
  249.           then support the development of generalized reasoning sys-
  250.           tems fully integrated with the symbolic processing package.
  251.  
  252.                Software A & E will implement a library of Ada packages
  253.           to support such capabilites.  The effort is limited in this
  254.           first phase to the minimal required support for many LISP-
  255.           based and logic programming applications.  Follow-on efforts
  256.           could expand the base provided by this first increment to
  257.           include conversion aid tools, enhanced logic programming
  258.           paradigms, and additional low level AI component packages.
  259.  
  260.  
  261.                                        2
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.           1.3.  References
  273.  
  274.           ANSI/MIL-STD-1815A, 1983.  Ada Programming Language.  U. S.
  275.           Government, Washington, DC.
  276.  
  277.           Barr, A., and Feigenbaum, E. A. (Eds.) 1981.  The Handbook
  278.           of Artificial Intelligence (Vol. 1 & 2). Los Altos, CA: Wil-
  279.           liam Kaufmann, Inc.
  280.  
  281.           Booch, G. 1983.  Software Engineering with Ada.  Menlo Park,
  282.           CA: Benjamin/Cummings Publishing Co.
  283.  
  284.           Campbell, J. A. (Ed.) 1984.  Implementations of PROLOG.  New
  285.           York, NY: Halstead Press.
  286.  
  287.           Charniak, E., Reisbeck, C. K., and McDermott, D. V. 1980.
  288.           Artificial Intelligence Programming.  Hillsdale, NJ:
  289.           Lawrence Erlbaum Associates.
  290.  
  291.           Knowledge Engineering System, Knowledge Base Author's Refer-
  292.           ence Manual.  1983. Software Architecture and Engineering,
  293.           Inc.
  294.  
  295.           Kowalski, R. 1979.  Logic for Problem Solving.  New York,
  296.           NY: Elsevier Science Publishing Co., Inc.
  297.  
  298.           Nilsson, N. J. 1980.  Priciples of Artificial Intelligence.
  299.           Palo Alto, CA: Tioga Publishing Co.
  300.  
  301.           Parnas, D. L. 1972.  On the Criteria to be used in Decompos-
  302.           ing Systems into Modules.  CACM 15:12, pp 1053-1058.
  303.  
  304.           Schwartz, R. L., and Melliar-Smith, P. M. 1980.  The Suita-
  305.           bility of Ada for Artificial Intelligence Applications.
  306.           Menlo Park, CA: SRI International.
  307.  
  308.           Steel, G. L. 1984.  COMMON LISP, The Language.  Burlington,
  309.           MA: Digital Press.
  310.  
  311.           Winston, P. H., and Horn, B. K. P. 1984.  LISP, Second Edi-
  312.           tion.  Reading, MA: Addison-Wesley Publishing Co., Inc.
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.                                        3
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.           1.4.  Overview
  339.  
  340.                An AI support environment for Ada would ultimately con-
  341.           sist of the following categories of components:
  342.  
  343.           (a)  LISP-capability emulation: packages which emulate the
  344.                symbolic manipulation capabilities of LISP that are not
  345.                directly available in Ada.
  346.  
  347.           (b)  Translation aids: packages that support syntactic and
  348.                semantic mapping of LISP-based programs into Ada con-
  349.                structs and facilities provided by the packages in
  350.                category (a).
  351.  
  352.           (c)  AI mechanisms: packages that represent commonly occur-
  353.                ring AI mechanisms, e.g.  a backward inferencing con-
  354.                trol strategy.
  355.  
  356.                Software A & E recommended an incremental approach to
  357.           development of the software in these three categories in the
  358.           contract proposal.  The first increment, a fundamental sub-
  359.           set of categories (a) and (c), is addressed by this docu-
  360.           ment.  This fundamental environment will consist of abstract
  361.           data types, objects, and associated operations commonly used
  362.           in AI applications, but not directly supported in Ada.
  363.  
  364.                The functional areas supported by the basic package to
  365.           be developed are briefly described in the Statement of Work
  366.           (SOW) as follows:
  367.  
  368.           (a)  AI data types: abstract data types will be developed
  369.                that characterize classes of symbolic data and associ-
  370.                ated operations commonly used in LISP-based AI applica-
  371.                tions;  these data types will provide a common base for
  372.                symbolic computation to be shared by AI applications
  373.                without concern for details of representation.
  374.  
  375.           (b)  Dynamic storage management: a typical AI program is
  376.                characterized by the highly dynamic way in which large
  377.                numbers of primitive data objects are created and dis-
  378.                carded; facilities for management of dynamic allocation
  379.                and reuse of object storage space are required to sup-
  380.                port this.
  381.  
  382.                In addition to this basic functionality, the SOW
  383.           requires the following:
  384.  
  385.           (c)  Generic AI objects: in general, flexibility can be
  386.                attained in AI programs through an object oriented view
  387.                of data that allows the details of object representa-
  388.                tion and typing to be hidden; packages will be
  389.                developed to provide definitions of objects generally
  390.                found useful in LISP-based AI programs.
  391.  
  392.  
  393.                                        4
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.           1.4.1.  Product Goals
  405.  
  406.           (a)  The product will support production development of AI
  407.                applications, as opposed to the evolutionary develop-
  408.                ment that is typical of AI research programming in
  409.                LISP.  The emphasis here is on decisions made during
  410.                application construction as part of various application
  411.                life-cycle methodologies for specification, design,
  412.                implementation, and revision of large software systems.
  413.  
  414.           (b)  The product will provide a collection of abstract data
  415.                objects (with operations) that is both necessary and
  416.                sufficient to support object-oriented design and imple-
  417.                mentation of AI applications in Ada.  These objects
  418.                should be arbitrarily composable with each other and
  419.                with the predefined objects of Ada in the same manner
  420.                that the Ada primitive objects are composable.  These
  421.                object types should not duplicate predefined objects of
  422.                Ada unnecessarily.
  423.  
  424.           (c)  Ada is a language of strong static typing and strong
  425.                dynamic sub-typing, and the facilities implemented by
  426.                the product should adhere to the same design princi-
  427.                ples.  The product should build upon a (collection of)
  428.                basic data type(s).  These should be the minimum addi-
  429.                tion to Ada's predefined data types that will give an
  430.                Ada programmer the means to manipulate dynamic objects
  431.                in a strongly typed environment.  The intent is not to
  432.                build a LISP or PROLOG environment on top of Ada, but
  433.                rather to support the AI application development para-
  434.                digms of these environments in the style of Ada.
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.                                        5
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.           2.  General Description
  471.  
  472.           2.1.  Product Perspective
  473.  
  474.                Artificial intelligence is the part of computer science
  475.           concerned with designing computer systems that exhibit
  476.           characteristics commonly associated with intelligence in
  477.           humans: problem solving, logical reasoning, language syn-
  478.           thesis and understanding, learning, expertise and vision.
  479.           Recently, the area of expert systems has begun to emerge as
  480.           a tool for developing practical applications of AI tech-
  481.           niques.  Typical examples of current expert systems interact
  482.           with a human user in a dialog in a manner similar to the way
  483.           the user would interact with a human expert.  Such consulta-
  484.           tion systems have achieved high levels of performance in
  485.           tasks which are amenable to this approach, such as geologi-
  486.           cal data analysis and medical diagnosis.  The next step in
  487.           the evolution of such systems is to embed them within other
  488.           application systems in such a way that the application sys-
  489.           tem, as the user, can interact with the expert system to
  490.           solve problems.
  491.  
  492.                The ability to behave with intelligence is usually
  493.           described in terms of knowledge.  Since AI involves the
  494.           design of computer systems that exhibit intelligent
  495.           behavior, knowledge representation is an important issue.  A
  496.           representation of knowledge is some combination of data
  497.           structures and procedures which lead to such intelligent
  498.           behavior when used in an appropriate manner.  Work on
  499.           knowledge representation has involved the design of several
  500.           classes of data structures for storing information as well
  501.           as the development of procedures that allow manipulation of
  502.           these data structures to make intelligent deductions.
  503.  
  504.  
  505.  
  506.           2.1.1.  Production Systems
  507.  
  508.                A common type of knowledge representation system is the
  509.           production system, which is a modular scheme finding
  510.           increasing popularity.   The major components of such a sys-
  511.           tem are a data base, a knowledge base, and a control stra-
  512.           tegy.  The data base is actually a temporary working storage
  513.           area used during construction of the solution of a specific
  514.           problem.  A production system operates by manipulating the
  515.           data base using the operations defined in the knowledge base
  516.           under the control of the control strategy.  The operations
  517.           defined by the knowledge base in a production system are in
  518.           the form of rules.  Each rule has a pre-condition that is
  519.           either satisfied or not by the data base.  If the pre-
  520.           condition is satisfied, the rule can be applied.  Applica-
  521.           tion of a rule changes the data base.  The choice of which
  522.           applicable rule to actually apply is done by the control
  523.  
  524.  
  525.                                        6
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.           strategy, which also has the responsibility of recognizing a
  537.           termination condition on the data base after each rule is
  538.           applied.  The primary task of a production system is to
  539.           infer (sometimes, deduce or prove) goals from the initial
  540.           contents of the data base using the rules.
  541.  
  542.                In a conventional production system, the data base,
  543.           knowledge base and control strategy are each globally
  544.           defined for the application.  The control strategy is usu-
  545.           ally a standard predefined component of a generalized pro-
  546.           duction system, which is supplied with an application-
  547.           specific knowledge base.  There is no notion of a local sub-
  548.           set of the data base accessible by a subset of the knowledge
  549.           base.  In fact, the data base is the only medium of communi-
  550.           cation between rules, which do not "call" one another.  This
  551.           results in an application structure which is extremely modu-
  552.           lar in its knowledge base part, but which is otherwise rela-
  553.           tively unstructured.  In general, the ordering of the appli-
  554.           cation of rules is irrelevant, which allows changes to the
  555.           knowledge base to be made relatively independently of each
  556.           other.
  557.  
  558.                There are two basic types of control strategy:
  559.  
  560.           (a)  irrevocable - an application rule is selected and
  561.                applied without provision for reconsideration.  Irrevo-
  562.                cable control strategies are only used when there is
  563.                infallible knowledge about how to proceed toward a goal
  564.                from a state of the computation.
  565.  
  566.           (b)  tentative - an applicable rule is selected (either
  567.                arbitrarily or using some heuristics), the rule is
  568.                applied, but provision is made to undo the effects of
  569.                the selection and subsequent computations and apply
  570.                some other rule.  The most common tentative control
  571.                strategy is backtracking.  Backtracking is the process
  572.                whereby, if a subsequent computation fails, the state
  573.                of the computation reverts to a prior state, the
  574.                choices made at that prior state are discarded, and new
  575.                choices are made.  The states at which backtracking can
  576.                return to are points in the computation determined by
  577.                the control strategy.  Typically, the selection of a
  578.                rule from a set of applicable rules is established as a
  579.                backtracking point.
  580.  
  581.                AI applications require knowledge of the problem domain
  582.           in three basic categories in order to achieve efficient
  583.           operations.  These categories are assertional, procedural,
  584.           and control knowledge.  Assertional knowledge expresses
  585.           explicit knowledge about a problem or problem domain; pro-
  586.           cedural knowledge expresses rules for manipulating the
  587.           assertional knowledge; control knowledge expresses knowledge
  588.           about the problem solving process for the problem domain,
  589.  
  590.  
  591.                                        7
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.           that is, the appropriate control strategy.  Production sys-
  603.           tems are generally accepted as a convenient and natural
  604.           mechanism for expressing assertional and procedural
  605.           knowledge.  Production systems have been found to be useful
  606.           mechanisms for controlling the interaction between asser-
  607.           tional and procedural knowledge.  Assertional knowledge is
  608.           separable into the two sub-categories of rules and facts,
  609.           whereas procedural knowledge is expressed only by rules.
  610.           Rules are usually stated in the form of implications:
  611.  
  612.                                   if A then B
  613.                                        or
  614.                                      A => B
  615.  
  616.           and can express generalized knowledge, while facts are sim-
  617.           ple non-implicational statements expressing specific
  618.           knowledge.  In an implication, the pre-condition, or if-
  619.           part, is called the antecedent, while the result, or then-
  620.           part, is called the consequent.  The general form of the
  621.           antecedent and consequent of a rule is a sequence of terms
  622.           joined by conjunction (AND) and/or disjunction (OR) opera-
  623.           tors.  A term is usually expressed in functional notation as
  624.           a predicate with arguments, which may be arbitrary symbolic
  625.           expressions.  Control knowledge will be discussed later.
  626.  
  627.                An inference is either antecedent driven or consequent
  628.           driven.  Antecedent driven inferencing is usually referred
  629.           to as forward inferencing since this method begins at the
  630.           problem's starting state (usually a set of facts) and
  631.           proceeds forward toward the desired goal (usually a set of
  632.           conclusions) by generating all the possibilities which can
  633.           be concluded from the given set of facts.  Consequent driven
  634.           inferencing is known as backward inferencing due to the fact
  635.           that the inferencing process begins with the desired goal
  636.           state and proceeds backward toward the given starting state
  637.           by determining if the conclusion satisfies the given set of
  638.           facts.  In either case, the final result will be a method
  639.           for moving from the starting state to the goal state.  How-
  640.           ever, although the antecedent and consequent driven methods
  641.           of inference are functionally equivalent, there an number of
  642.           criteria to be considered when choosing an inference method.
  643.  
  644.                If one is attempting to verify (or deny) a particular
  645.           conclusion, backward inferencing is recommended because it
  646.           is easier to determine if one conclusion satisfies the given
  647.           set of facts than to generate all the possibilities which
  648.           can be concluded from a given set of facts and then deter-
  649.           mine if the desired conclusion is among these possibilities.
  650.           If one is trying to determine all conclusions which can be
  651.           drawn from a given set of facts, forward inferencing is
  652.           recommended.
  653.  
  654.  
  655.  
  656.  
  657.                                        8
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.                A general example of this would be one involving a set
  669.           of animals and a set of observed characteristics such as
  670.           color, flying or non-flying, fur-bearing or feathered, spot-
  671.           ted or striped, etc.   These characteristics will generally
  672.           be shared by more than one animal.  If the problem to be
  673.           solved was that of identifying a particular animal, backward
  674.           inferencing would be the recommended method because it is
  675.           easier to choose each animal in the goal state and determine
  676.           if the animal has all the observed characteristics rather
  677.           than generating a number of sets of animals (where each set
  678.           contained all animals which shared a particular characteris-
  679.           tic) and then taking the intersection of these sets.  How-
  680.           ever, if the problem to be solved was to create a set con-
  681.           taining all animals which had one or more of the given
  682.           characteristics, forward inferencing would be recommended.
  683.  
  684.                The methods of inference mentioned above are imple-
  685.           mented in the following manner.  In systems which operate by
  686.           forward inferencing, the occurrence of a fact in the data
  687.           base which matches the antecedent of a rule makes that rule
  688.           applicable; that is, the contents of its consequent becomes
  689.           a part of the data base.  Therefore, the inference process
  690.           in these systems consists of applying the rules of the
  691.           knowledge base to the data base (which has been initialized
  692.           with a given set of facts) until a termination condition
  693.           involving a goal defined by the particular problem is
  694.           reached.   In backward inferencing systems, the occurrence
  695.           of a goal in the data base which matches the consequent of a
  696.           rule makes that rule applicable; that is, the contents of
  697.           the rule's antecedent becomes a part of the data base.
  698.           Therefore, the inference process in backward inferencing
  699.           systems consists of applying the rules of the knowledge base
  700.           to the data base (which has been initialized with a goal
  701.           expression) until a termination condition involving facts in
  702.           the knowledge base is reached.
  703.  
  704.                In order to use control knowledge in a production sys-
  705.           tem, there must be a suitable representation for it.  Vari-
  706.           ous approaches have been considered, such as treating the
  707.           control strategy as a series of problems to be solved by
  708.           another (meta) production system, embedding control
  709.           knowledge into discrimination functions supplied to a gen-
  710.           eral control strategy, or embedding control knowledge into
  711.           the rules themselves.  This latter approach is taken by the
  712.           "logic programming" languages, such as PROLOG or the OPS
  713.           family.
  714.  
  715.                The general logic programming paradigm is to treat a
  716.           rule like a subprogram of a conventional programming
  717.           language.  The control strategy invokes rules only when new
  718.           goals or facts are infered, depending on the inferencing
  719.           mechanism used.  A simple control strategy, similar to that
  720.           found in PROLOG, is to select all applicable rules whenever
  721.  
  722.  
  723.                                        9
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734.           a new goal is created and invoke the first one selected.  An
  735.           "executing" rule may assert new facts, goals, or even rules,
  736.           which may cause the "executing" rule to be suspended if new
  737.           rules are invoked.  A rule terminates either with success or
  738.           failure, depending on whether its sub-goals can be inferred
  739.           or not.  In either case, control is returned to the invoking
  740.           rule, but in the failure case, backtracking occurs and a new
  741.           rule is invoked.
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.                                        10
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.           2.1.2.  Logic Programming
  801.  
  802.                Logic programming systems are an important development
  803.           in the AI field.  These languages, in their pure form, use
  804.           assertions about logical relationships between data elements
  805.           to specify programs, rather that specifying procedurally how
  806.           operations are to be performed.  Logic programming permits
  807.           extraordinarily concise programs because its statements are
  808.           declarative rather than prescriptive.  Unfortunately, this
  809.           programming conciseness is not without costs.  In PROLOG,
  810.           for example, the control strategy works by generating virtu-
  811.           ally all possible implications of a given initial data base
  812.           configuration, whether or not they are relevant.  Further,
  813.           PROLOG, in its pure form, is not deterred from searching for
  814.           more than one inference sequence for the same goal.  Most
  815.           PROLOG implementations have been augmented with control
  816.           strategy directives to constrain a program's search path.
  817.           PROLOG is a language of tremendous potential which it has,
  818.           to date, failed to realize, in many cases, due to a number
  819.           of questionable design decisions.  One of these is the
  820.           choice of backtracking as the sole control structure of the
  821.           language.  This paradigm fits certain problems well, but
  822.           yields programs that are inefficient as well as incomprehen-
  823.           sible when confronted with the many situations for which
  824.           backtracking is unsuited.
  825.  
  826.                The great power conferred by the availability of a
  827.           logic programming capability strongly argues for its inclu-
  828.           sion in the AI programming environment.  The combination of
  829.           a logic processing facility and a symbolic processing facil-
  830.           ity, both interfacing smoothly with each other and with the
  831.           Ada host language, produces a facility of impressive power.
  832.           This situation is provided by having such a logic program-
  833.           ming facility available to be invoked as needed embedded in
  834.           the Ada host language and interfacing with the symbolic com-
  835.           putation tools.  In particular, since the control structures
  836.           of the Ada language are available, the difficulties engen-
  837.           dered by being confined to backtracking are obviated, and
  838.           efficient logic programming becomes possible.
  839.  
  840.                There is no reason to restrict a programmer in the same
  841.           manner as is done in conventional production systems to a
  842.           single knowledge base, a single working storage data base,
  843.           and a single control strategy.  Given Ada's capabilities, it
  844.           is straightforward to define logic programming control stra-
  845.           tegy operations which take a data base and a knowledge base
  846.           as arguments.  Furthermore, facilities could easily be pro-
  847.           vided implementing both backward inferencing, as in PROLOG,
  848.           as well as forward inferencing, as in the OPS language fam-
  849.           ily, control strategies.  With the support for concurrent
  850.           task implementations provided by Ada, it may even be possi-
  851.           ble to ultimately provide implementations of concurrent
  852.           inferencing control strategies.
  853.  
  854.  
  855.                                        11
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866.           2.2.  Product Functions
  867.  
  868.           2.2.1.  Symbolic Expressions
  869.  
  870.                The essential capability that has allowed LISP to
  871.           retain its dominant position as an AI programming language
  872.           is its ability to perform abstract manipulations on dynami-
  873.           cally shaped data structures.  This unconstrained form of
  874.           data structuring is an important characteristic of AI pro-
  875.           gramming languages, as it allows data structures of
  876.           unpredictable size and shape to be conveniently constructed
  877.           and manipulated.  The data structures are, at this level of
  878.           LISP, interpreted only in a structural fashion by the opera-
  879.           tors which manipulate them.  Interpretations of the elemen-
  880.           tary data items, and interpretations of their structural
  881.           composition as representations for relationships between
  882.           them, is left up to the individual application program.  A
  883.           disadvantage of the LISP approach to data structuring is
  884.           that there is no built-in mechanism to enforce any
  885.           application-specific constraints on the size and shape of
  886.           the structures, as determined by the intended interpreta-
  887.           tion.  COMMON LISP addresses this problem somewhat by defin-
  888.           ing facilities that allow a programmer to do explicit con-
  889.           straint checking for data types.  This approach to data pro-
  890.           cessing is usually referred to as symbolic computation, and
  891.           the data structures are usually referred to as symbolic
  892.           expressions.
  893.  
  894.                Most introductory LISP references talk about lists and
  895.           list processing when explaining the essential capabilities
  896.           of LISP.  This tends to obscure the real power behind LISP,
  897.           since the notion of a "list of components" is a particular
  898.           interpretation of a symbolic expression, where another
  899.           interpretation may be more appropriate in the specific
  900.           application, such as a "function with arguments."  Part of
  901.           the reason for the conventional approach to LISP is that the
  902.           procedural semantics of the LISP symbolic expressions are
  903.           defined in terms of operations on the representation of sym-
  904.           bolic expressions, with conventions that treat the represen-
  905.           tation as a linked list, even though it is actually a binary
  906.           tree structure.
  907.  
  908.                The fundamental characteristic of the LISP symbolic
  909.           expression is that it is a recursive data type, when viewed
  910.           as an abstraction independently of the all-too-visible
  911.           implementation details of LISP.  It is the recursive nature
  912.           of the type that gives LISP its expressive power.  The most
  913.           common characterization of a recursive data structure is the
  914.           tree structure.  There are a large number of concepts dealt
  915.           with in typical AI applications that can be easily
  916.           represented as tree structures, given an appropriate set of
  917.           access and construction operations.
  918.  
  919.  
  920.  
  921.                                        12
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.  
  932.                The other important issue with respect to the specifi-
  933.           cation of the symbolic expression type is structure sharing.
  934.           Symbolic processing applications typically have large memory
  935.           requirements.  To lessen this burden on available storage,
  936.           symbolic expression structures will be shared.  That is, the
  937.           result of a symbolic processing operation will typically
  938.           return a reference to a specific portion of the input argu-
  939.           ment rather than returning a brand-new copy of the desired
  940.           result.  However, this raises a problem if destructive
  941.           operations such as LISP's replaca and replacd, are provided.
  942.           The solution is simply not to provide any of these destruc-
  943.           tive operations.  Thus, the choice of an internal implemen-
  944.           tation using sharing can not impact any user of the facil-
  945.           ity.  All operations defined on symbolic expressions will be
  946.           non-destructive or constructive (no existing values are cor-
  947.           rupted, and results of operations are defined as new
  948.           values).
  949.  
  950.  
  951.  
  952.  
  953.  
  954.  
  955.  
  956.  
  957.  
  958.  
  959.  
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.                                        13
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.  
  998.           2.2.2.  Pattern Matching
  999.  
  1000.                A pattern is a symbolic expression with special atomic
  1001.           components referred to as variables.  Two patterns are said
  1002.           to match if their variables can be replaced by values to
  1003.           make both patterns identical, where multiple occurrences of
  1004.           the same variable in a pattern must be substituted con-
  1005.           sistently with the same value.
  1006.  
  1007.                The values which are matched with variables are usually
  1008.           of interest to the application using the pattern matching
  1009.           operation.  Consequently, the matching operations is usually
  1010.           defined to return as a result the correspondences between
  1011.           variables and values generated during a successful matching
  1012.           operation.  The correspondence between a variable and its
  1013.           matching value is referred to as the variable binding, and
  1014.           the result of the matching operation is the variable binding
  1015.           list.
  1016.  
  1017.                Pattern matching is typically implemented as a sequen-
  1018.           tial operation which considers each corresponding pair of
  1019.           components from the two patterns in turn, with a recursive
  1020.           call to the matching operation occurring when a component is
  1021.           non-atomic.  Under this approach, variable bindings are gen-
  1022.           erated immediately upon the first match for each variable.
  1023.           Subsequent occurrences of such a bound variable then use the
  1024.           bound value rather than the variable itself in the component
  1025.           matching test.  A variable can be bound only if it is
  1026.           currently unbound, e.g., the value of a bound variable can-
  1027.           not change.  Variables may be bound to other variables, in
  1028.           which case the variables are said to be linked rather than
  1029.           bound.  Linked variables remain candidates for binding until
  1030.           one of the linked variables becomes bound, at which point
  1031.           all variables linked to that bound variable become bound to
  1032.           that same value.
  1033.  
  1034.                One restriction that is typically placed on this pro-
  1035.           cess is that the scope of a pattern variable is a single
  1036.           pattern.  In other words, a variable in a pattern is dis-
  1037.           tinct from any variable in any other pattern, even if the
  1038.           representation of the symbols used to denote two different
  1039.           variables on an external device are the same.  Even with
  1040.           this restriction, it is possible for a variable to become
  1041.           linked to itself, or bound to an expression which includes
  1042.           itself as a component.  This can occur when the variable is
  1043.           matched against a variable of the other pattern which was
  1044.           linked or bound at a previous component position.
  1045.  
  1046.                Linking a variable to itself causes no conceptual prob-
  1047.           lems, but the case of binding a variable to an expression
  1048.           which contains that same variable as a component causes cir-
  1049.           cularity problems.  Detection of this situation requires a
  1050.           potentially expensive check during each component match
  1051.  
  1052.  
  1053.                                        14
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.           step.  In this case, the match operation is usually defined
  1065.           to fail, as it is difficult to deal with circular data
  1066.           structures.  The checking required is called the occurs
  1067.           check in the literature.
  1068.  
  1069.                If multiple copies of a pattern are used in pattern
  1070.           matching operations simultaneously, it must be possible to
  1071.           prevent binding conflicts between the various usages.  This
  1072.           can occur as the result of using a global pattern in a
  1073.           multi-tasking application, or in sequential processing
  1074.           within a self-recursive subprogram.  This latter situation
  1075.           is especially important to the product design, as patterns
  1076.           will be the basis for the implementation of rules, and the
  1077.           algorithms used for proving goals from rules are essentially
  1078.           recursive pattern matching operations.  During a single
  1079.           recursive search for a proof, the algorithm may utilize the
  1080.           same rule multiple times at different levels of the recur-
  1081.           sion.  The obvious solution is for the pattern matching
  1082.           operations to systematically rename variables in each pat-
  1083.           tern before attempting the match.  Optimization of this pro-
  1084.           duction of variants of patterns is essential to an efficient
  1085.           implementation.
  1086.  
  1087.                The classic implementation of variable binding is as a
  1088.           list of pairs of variable name and bound value, accessed by
  1089.           linear lookup on the variable name.  This is easy to imple-
  1090.           ment and to understand, but the time to find the binding of
  1091.           a variable is proportional to the number of bound variables.
  1092.           The worst case behavior is terrible, but the normal case
  1093.           behavior is reasonable for finding the binding of a bound
  1094.           variable, since the binding list will typically be short.
  1095.           Determination that a variable is unbound requires traversal
  1096.           of the entire list, accentuated by the fact that long chains
  1097.           of linked variables cause a list traversal for each link, as
  1098.           the linking is represented as a binding pair with two vari-
  1099.           able names.  In this case, an occurs check is needed to dis-
  1100.           cover the situation of linking a variable to itself, which
  1101.           will cause a circularity in this implementation.  For-
  1102.           tunately, the check is simple in this special case.  The
  1103.           matching operation is defined to succeed, but no binding
  1104.           results.
  1105.  
  1106.                An alternative to using a single list representing all
  1107.           bindings is to have a binding list associated with each pat-
  1108.           tern.  The trick here is that, when a variable is bound to a
  1109.           value, the binding is represented by a pair consisting of
  1110.           the value and the binding list associated with the pattern
  1111.           from which the value was extracted.  To discover the value
  1112.           bound to a variable may require several list traversals in
  1113.           the case of variable linking, but each list will typically
  1114.           be quite small.  The major advantage of this scheme is that
  1115.           the association of a binding list with each pattern can be
  1116.           designed to implicitly take care of the renaming of
  1117.  
  1118.  
  1119.                                        15
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.           variables when a pattern is used multiple times con-
  1131.           currently, provided that the association of binding lists
  1132.           with patterns is local to the location of usage so that each
  1133.           copy of the pattern in use has a unique binding list.
  1134.  
  1135.                An important issue is how to handle variable linking,
  1136.           especially within the context of using patterns to implement
  1137.           rules, as long chains of linked variables can result during
  1138.           a single attempt to prove a goal.  In the classic implemen-
  1139.           tation, this is represented by a binding a variable to
  1140.           another variable and repeatedly looking up the next binding
  1141.           until an unbound variable or a value is encountered.
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  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.                                        16
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.           2.2.3.  Logic Programming
  1197.  
  1198.                The major workhorse of a logic programming system is
  1199.           the unifier, which matches goals with consequents of asser-
  1200.           tions, possibly generating new sub-goals, which must be
  1201.           proved recursively.  Assertions represent both rules and
  1202.           facts, where facts are represented by rules with no
  1203.           antecedent (or sometimes with a literal representing true as
  1204.           the antecedent).  This allows uniform treatment of rules and
  1205.           facts.  If a (sub-)goal is matched with a fact consequent,
  1206.           then it is proved, while if it is matched with a rule conse-
  1207.           quent, then the antecedent of that rule must be proved as a
  1208.           sub-goal.  During this recursive matching process, the unif-
  1209.           ier binds variables matched to component expressions and
  1210.           uses those bindings during subsequent sub-goal processing.
  1211.           The initial goal is referred to as a query, and is usually
  1212.           represented as a rule with no consequent, so that the unif-
  1213.           ier is always matching antecedents representing (sub-)goals
  1214.           with consequents of assertions.  A general term referring to
  1215.           both assertions and queries is the rule.
  1216.  
  1217.                The unification algorithm matches a pair of arguments,
  1218.           which are generally components extracted from an antecedent
  1219.           of one rule and a consequent of some other rule, at each
  1220.           step, doing so within an environment which contains any
  1221.           current variable bindings.  As for the case of patterns,
  1222.           variables are required to be unique to each rule.  In addi-
  1223.           tion, variables within rules are generally interpreted as
  1224.           being universally quantified over the entire rule (e.g., the
  1225.           rule is interpreted as applying for any value of each vari-
  1226.           able).  If the unification succeeds for a (sub-)goal, it
  1227.           adds any new variable bindings to the environment, and
  1228.           returns the extended environment to the caller, which uses
  1229.           the new environment when attempting to prove additional
  1230.           sub-goals.  Since it is possible for an assertion to be used
  1231.           more than once during this recursive unification process, it
  1232.           is important to prevent binding conflicts in the environ-
  1233.           ment, which occur when the variables of an assertion are
  1234.           bound to different values for each use of that assertion.
  1235.           This is why the classical unification algorithm renames
  1236.           variables before using an assertion.  However, as mentioned
  1237.           during the discussion on pattern matching, there are ways to
  1238.           avoid this expensive operation.
  1239.  
  1240.                The binding of variables during unification has add-
  1241.           tional requirements beyond those for the simple case of pat-
  1242.           tern matching.  Symbolic expressions containing unbound
  1243.           variables can become bound to variables after unifying the
  1244.           consequent of an assertion with a (sub-)goal.  These unbound
  1245.           variables may later become bound (or not) while processing
  1246.           the antecedent of that assertion as a new sub-goal.  Conse-
  1247.           quently, the binding environment generated during unifica-
  1248.           tion cannot, in general, disappear until after the original
  1249.  
  1250.  
  1251.                                        17
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260.  
  1261.  
  1262.           query has been proved.  At least that subset of the environ-
  1263.           ment which is required to keep track of such unbound vari-
  1264.           ables returned out of sub-goal unifications must be
  1265.           retained.  Variables can also become unbound during back-
  1266.           tracking when sub-goal unification fails to find a match.
  1267.  
  1268.                For this initial phase of the implementation, the prim-
  1269.           itive objects and operations necessary to implement a logic
  1270.           programming control strategy and to otherwise support the
  1271.           implementation of a logic programming facility are required.
  1272.           Additionally, a simple control strategy implementing essen-
  1273.           tially a PROLOG style of backward inferencing is necessary
  1274.           in order to demonstrate the fundamental facilities.  The
  1275.           required objects are, essentially, generalized rules and
  1276.           rulebases.  A rulebase object can be used to implement both
  1277.           knowledge bases and working storage data bases if goals and
  1278.           facts are treated as special cases of the generalized rules.
  1279.  
  1280.  
  1281.  
  1282.  
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293.  
  1294.  
  1295.  
  1296.  
  1297.  
  1298.  
  1299.  
  1300.  
  1301.  
  1302.  
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.                                        18
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325.  
  1326.  
  1327.  
  1328.           2.3.  General Constraints
  1329.  
  1330.           2.3.1.  Design Methodology
  1331.  
  1332.                Software A & E will use modern software engineering
  1333.           techniques in the implementation of this product.  In the
  1334.           design phase, the particular techniques employed will be
  1335.           information hiding and object-oriented design.
  1336.  
  1337.  
  1338.  
  1339.           2.3.1.1.  Information Hiding
  1340.  
  1341.                The decomposition criteria supporting step-wise refine-
  1342.           ment of a software system design due to Parnas, known as
  1343.           information hiding, is an important design technique.  The
  1344.           basic idea is to decompose a software system into modules in
  1345.           such a way that each module allows the implementation
  1346.           details of a single design aspect of the system to be hid-
  1347.           den.  This technique explicitly captures the design struc-
  1348.           ture of a software system in the software at the level at
  1349.           which each design decision was made.  The advantage of this
  1350.           design approach is that, if the need arises to modify the
  1351.           system, the effects of the modification should be localized
  1352.           to one module.
  1353.  
  1354.                An information hiding module defines a set of software
  1355.           functions while hiding the information about how the func-
  1356.           tions are actually implemented.  This technique supports the
  1357.           development of software which is designed for easily imple-
  1358.           mented enhancements and modifications.  One of the principle
  1359.           design goals of Ada was to allow exploitation of these pro-
  1360.           ductivity advantages.  One disadvantage of this approach is
  1361.           that the resulting application may suffer from the perfor-
  1362.           mance standpoint when compared to an equivalent application
  1363.           which has its functions coded inline.  Ada provides an
  1364.           elegant solution to this problem by allowing the developer
  1365.           to tell the compiler to compile certain functions as if they
  1366.           had been written inline.  It is a general design principle
  1367.           of Ada that the presence of expensive capabilities (in terms
  1368.           of performance) should not penalize the efficiency for usage
  1369.           of simple capabilities.
  1370.  
  1371.                A software system designed using this technique is
  1372.           organized into a hierarchy of modules.  Within the hierar-
  1373.           chy, a function of a module is only permitted to use func-
  1374.           tions of other modules which are beneath it in the hierarchy
  1375.           to perform its function.  The levels in the hierarchy can be
  1376.           viewed as abstract machines.  Each abstract machine provides
  1377.           functional capabilities to higher-level software components
  1378.           that are more powerful and application specific than the
  1379.           lower levels of abstraction.  Use of information hiding as
  1380.           the decomposition criteria fully supports incremental
  1381.  
  1382.  
  1383.                                        19
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.           development, as each level of the hierarchy only depends on
  1395.           the visible functions provided by lower levels.  Unless the
  1396.           visible functions change, modifications are localized.
  1397.  
  1398.  
  1399.  
  1400.           2.3.1.2.  Object-oriented Design
  1401.  
  1402.                Object-oriented design is a methodology which attempts
  1403.           to map a solution to a problem directly to the solution's
  1404.           users' view of the problem.  The methodology is character-
  1405.           ized by its balanced treatment between the software com-
  1406.           ponents representing the objects of the problem space and
  1407.           the software operations representing the actions taken by or
  1408.           applied to these objects.  The software objects are viewed
  1409.           as actors, each with its own set of applicable operations.
  1410.           The basic approach is to initially develop an informal stra-
  1411.           tegy for the solution to a problem that parallels the world
  1412.           view of the users.  This solution strategy is expressed in
  1413.           terms of the concepts from this problem space.  Given this
  1414.           informal strategy, the objects and actions are identified,
  1415.           and the relationships among the objects are established.  At
  1416.           this point, a formal description of the visible interfaces
  1417.           to each object can be developed, which explicitly defines
  1418.           the operations that may be performed on or by each object.
  1419.           The scope and visibility of each entity is also defined.
  1420.  
  1421.                The object-oriented design methodology supports the
  1422.           principles of abstraction through information hiding.
  1423.           Abstractions are directly implemented from the problem
  1424.           space, providing a strategy for decomposing a system into
  1425.           modules in which design decisions are localized to match the
  1426.           "world view."
  1427.  
  1428.  
  1429.  
  1430.  
  1431.  
  1432.  
  1433.  
  1434.  
  1435.  
  1436.  
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.                                        20
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457.  
  1458.  
  1459.  
  1460.           2.3.2.  Dynamic Storage Management
  1461.  
  1462.                The concept of the name of an object is central to the
  1463.           design of a dynamic storage management mechanism.  A name is
  1464.           an access path to an object.  Variables occurring in the
  1465.           usual fashion in compiled programs are one kind of name, in
  1466.           this case the access path (at compile time) to the storage
  1467.           location allocated by the compiler for the variable at run-
  1468.           time.  A variable is a constant name;  an example of a
  1469.           dynamic name is the value of an Ada access type, which is
  1470.           the name of an object dynamically allocated at run-time.  An
  1471.           access to integer variable is the name of an access object,
  1472.           whose value is the name of an integer object whose value is
  1473.           an integer.  The problem of managing dynamically allocated
  1474.           storage is, at the level of Ada source code, a problem in
  1475.           the dynamic management of name values.
  1476.  
  1477.                A data object which is accessible via two different
  1478.           names is said to have aliases.  A simple example is seen
  1479.           with the Ada access type: if X contains an access value
  1480.           referencing an integer object, and X is assigned to Y
  1481.           (assuming both X and Y are assignment compatible), then both
  1482.           X and Y contain alias names for the same integer object.
  1483.           Changing the value of that integer object can be accom-
  1484.           plished using the value assigned either to X or to Y as its
  1485.           name.
  1486.  
  1487.                Alias names cause a problem when there is an operation
  1488.           which causes a dynamically allocated object to become deal-
  1489.           located.  A deallocated object is no longer in use, and so
  1490.           can be reused to satisfy another allocation request for
  1491.           dynamic storage space.  If a particular object has alias
  1492.           names, and one of those names is used as an argument to the
  1493.           operation which deallocates the object, then the alias names
  1494.           will reference a part of storage which is supposed to be
  1495.           currently inaccessible and available for reuse.  This situa-
  1496.           tion is referred to as dangling references.
  1497.  
  1498.                In order to address the dangling reference problem
  1499.           caused by alias names, there are various storage reclamation
  1500.           schemes which ensure that an object is not reused while
  1501.           there are outstanding names for the object.  The Ada stan-
  1502.           dard does not require an implementation to provide such a
  1503.           mechanism, although it is permitted.  The implementation of
  1504.           dynamic objects assumes that storage reclamation is not pro-
  1505.           vided.
  1506.  
  1507.                A storage reclamation scheme must either know the set
  1508.           of names referring to a particular object at all times, or
  1509.           else must know what names are available for referencing any
  1510.           object at all times and know the set of objects currently
  1511.           allocated.  The first alternative can be simplified to
  1512.           merely record the number of names for a particular object.
  1513.  
  1514.  
  1515.                                        21
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.           This is called reference counting, and permits incremental
  1527.           storage reclamation, since as soon as there are no names for
  1528.           an object, it can be deallocated.  The second alternative is
  1529.           referred to as garbage collection.  When the available free
  1530.           space for allocating new dynamic objects is exhausted, all
  1531.           objects accessible from the known set of available name
  1532.           values are marked as in use.  All dynamic objects not marked
  1533.           can then be reused.
  1534.  
  1535.                Either version of storage reclamation mentioned above
  1536.           is satisfactory within the run-time environment supporting
  1537.           either an interpreted language, such as LISP, or a compiled
  1538.           language, such as Ada.  Both an interpreter and a compiler
  1539.           can ensure that reference counting occurs where required,
  1540.           and both can ensure that the garbage collector knows the set
  1541.           of names which may reference dynamic storage.  Unfor-
  1542.           tunately, neither implementation is completely satisfactory
  1543.           if built on top of an interpreted or compiled language.  The
  1544.           reasons are discussed in the following subsections.
  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.                                        22
  1582.  
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.  
  1591.  
  1592.           2.3.2.1.  Reference Counting
  1593.  
  1594.                The reference counting scheme requires that a count of
  1595.           the number of different names by which a dynamic object can
  1596.           be referenced be maintained at all times.  In particular,
  1597.           this means that whenever a name value is assigned to a name
  1598.           variable, the reference count of the object named be incre-
  1599.           mented, and if the name variable originally referred to some
  1600.           other object, that object's reference count be decremented.
  1601.  
  1602.                Since the Ada assignment statement does not do this for
  1603.           us, an assignment operation must be defined and use of the
  1604.           Ada assignment statement should be prohibited.  Ada provides
  1605.           a mechanism for prohibiting the assignment statement by
  1606.           defining the type representing dynamic object names as lim-
  1607.           ited private.  Unfortunately, since assignment is a state-
  1608.           ment, overloading of the ":=" symbol is not permitted, so
  1609.           the assignment operation must be defined as a procedure.
  1610.           For any other symbolic expression operations, the internal
  1611.           implementation can maintain reference counts as required.
  1612.  
  1613.                If this were sufficient to reclaim all inaccessible
  1614.           dynamic object storage, the implementation would be
  1615.           extermely powerful and would hide all details of the recla-
  1616.           mation process from a programmer, even to the extent of hid-
  1617.           ing its existance.  The latter comment is significant, in
  1618.           that an implementation of symbolic expressions running on an
  1619.           Ada run-time system which supports automatic storage recla-
  1620.           mation could allow the run-time system to do the work, while
  1621.           an implementation running on a more restricted run-time sys-
  1622.           tem could take care of it, and the programmer would not have
  1623.           to consider the issue in his program.
  1624.  
  1625.                Nevertheless, the above approach is not without its
  1626.           problems.  While declaring types to be limited private does
  1627.           prevent the use of the assignment statement, this also has
  1628.           the unfortunate effect of prohibiting initializations, con-
  1629.           stants and default parameters and precludes a programmer
  1630.           from ignoring the storage management facilities if the Ada
  1631.           run-time system provides storage management.
  1632.  
  1633.                In addition, there are three important situations that
  1634.           arise when implementing reference counting on top of a run-
  1635.           time system which make it impossible to hide the fact that
  1636.           storage reclamation exists from a programmer.  These prob-
  1637.           lems affect the manner in which a programmer will have to
  1638.           write his code.  These situations are:
  1639.  
  1640.           (a)  Aliasing of names via subprogam parameters.
  1641.  
  1642.           (b)  Exit from the scope of a locally declared name vari-
  1643.                able.
  1644.  
  1645.  
  1646.  
  1647.                                        23
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.  
  1657.  
  1658.           (c)  Returning a name value as the result of a function.
  1659.  
  1660.                The real problem is that there is no compiler support
  1661.           for locating name values.  The only access to name values
  1662.           available to a Ada programmer is via name variables or name
  1663.           constants, whereas the compiler itself knows where all of
  1664.           the name values will be at run-time.
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  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.                                        24
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722.  
  1723.  
  1724.           2.3.2.1.1.  Name Aliasing via Subprogram Parameters
  1725.  
  1726.                Within a subprogram with a parameter of the symbolic
  1727.           expression type, the formal parameter establishes a new
  1728.           alias for the object named by the actual parameter.  Since
  1729.           parameter passing is implemented below the level of storage
  1730.           management in this situation, the reference count of that
  1731.           object has not been properly adjusted.  If the programmer is
  1732.           allowed to use an operation on the formal parameter which
  1733.           adjusts the reference count downward, the dynamic object's
  1734.           reference count may reach zero prematurely, and be treated
  1735.           as inaccessible by the storage reclamation process.  At this
  1736.           point, the actual parameter may now contain a dangling
  1737.           reference.  On the other hand, if the actual parameter is a
  1738.           visible global (with respect to the subprogram) variable and
  1739.           this variable is used as an argument to an operation which
  1740.           adjusts the reference count downward, resulting in the
  1741.           object becoming reclaimed, the formal parameter name con-
  1742.           tains a dangling reference.  This latter case is a side
  1743.           effect that happens to be defined as an erroneous program by
  1744.           the Ada standard <6.2, 13>, since the standard then defines
  1745.           the formal parameter to have an undefined value.
  1746.  
  1747.                Assume that the symbolic expression type is defined as
  1748.           limited private in order to prevent use of the Ada assign-
  1749.           ment statement, forcing the type to be used only as a sub-
  1750.           program parameter of mode in.  If all operations which can
  1751.           have the internal effect of modifying a reference count have
  1752.           the appropriate parameters defined as mode in out, then the
  1753.           programmer will be prohibited from using these operations on
  1754.           subprogram formal parameters, thus enforcing the Ada
  1755.           interpretation of a formal parameter of mode in as a local
  1756.           constant.  This will force all operations which may reclaim
  1757.           object space to be applied only to variables.  This will not
  1758.           prevent the programmer from getting into the second situa-
  1759.           tion, unless the run-time system can enforce it.
  1760.  
  1761.                The disadvantage of this solution is that, since the
  1762.           programmer cannot pass symbolic expressions as output param-
  1763.           eters from a subprogram, it will encourage use of global
  1764.           variables, which tends to be discouraged by most of the
  1765.           recent program design methodologies.  This solution does, on
  1766.           the other hand, tend to encourage a functional programming
  1767.           style of program design, where the only way to get new
  1768.           values is as the returned value of a function subprogram
  1769.           with no side effects on function parameters.  Unfortunately,
  1770.           the process of returning a symbolic expression value from a
  1771.           function has its own problems, discussed later.
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.                                        25
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.  
  1787.  
  1788.  
  1789.  
  1790.           2.3.2.1.2.  Scope Exit for a Local Variable
  1791.  
  1792.                If a dynamic object is created and its name value
  1793.           assigned only to a name variable declared in a local
  1794.           declaration scope, then on exit from that scope, the dynamic
  1795.           object can be reclaimed since there are no longer any refer-
  1796.           ences to it.  However, with no interpreter/compiler support
  1797.           for object reclamation, the programmer must be relied upon
  1798.           to explicitly indicate this situation.  Therefore, he must
  1799.           be given a special operation to be used to indicate to the
  1800.           dynamic storage reclamation process that a name value is to
  1801.           be eliminated, causing the reference count of the named
  1802.           object to be decremented.
  1803.  
  1804.  
  1805.  
  1806.  
  1807.  
  1808.  
  1809.  
  1810.  
  1811.  
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817.  
  1818.  
  1819.  
  1820.  
  1821.  
  1822.  
  1823.  
  1824.  
  1825.  
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831.  
  1832.  
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.  
  1842.  
  1843.  
  1844.  
  1845.                                        26
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855.  
  1856.           2.3.2.1.3.  Returning a Value from a Function
  1857.  
  1858.                In order to conveniently manipulate dynamic objects,
  1859.           the objects themselves are seldom actually copied.  Instead,
  1860.           names of dynamic objects are manipulated as values (in Ada,
  1861.           as values of some access type).  As previously discussed,
  1862.           all formal parameters of the symbolic expression type will
  1863.           be local constant name values within a subprogram, and so
  1864.           cannot be used as name variables to construct a new symbolic
  1865.           expression value to return as a function result.  Also, the
  1866.           programmer must explicitly apply a deallocation operation to
  1867.           all local name variables before leaving a declaration scope,
  1868.           which includes the body of a subprogram.
  1869.  
  1870.                There are two aspects of this situation which cause
  1871.           problems, which are really the two sides of the more general
  1872.           issue of how to deal with a temporary name value.  On the
  1873.           one hand, a name value which is not currently assigned to
  1874.           any name variable needs to be treated as naming a dynamic
  1875.           object with reference count zero, so that when that value is
  1876.           assigned to a name variable, the assignment operation, which
  1877.           increments reference counts, will leave the reference count
  1878.           at one.  On the other hand, within the function body, the
  1879.           name value is most likely assigned to a local name variable
  1880.           which will be used as the expression of the Ada return
  1881.           statement to define the result value of the function call.
  1882.           Since the value is assigned to a variable, it has reference
  1883.           count equal to (at least) one, so the value of the function
  1884.           call, when assigned to a variable of the outer dynamic
  1885.           range, will have a reference count equal to (at least) two.
  1886.           In this situation, the dynamic object named appears to have
  1887.           more alias names than it actually has, so the dynamic object
  1888.           storage will never be reclaimed by the storage reclamation
  1889.           process.
  1890.  
  1891.                An additional problem arises if the returned value is
  1892.           never assigned to a variable, but rather is immediately
  1893.           passed as an actual parameter of some other subprogram call,
  1894.           which never internally assigns it to a variable.  In this
  1895.           situation, there is no name variable available with which to
  1896.           free the dynamic object.
  1897.  
  1898.                A function result can be arranged to have the appropri-
  1899.           ate reference count only if the programmer is given a spe-
  1900.           cial operation to be used only as the result expression of a
  1901.           return statement within a function subprogram which needs to
  1902.           get its return value from a local variable.  The parameter
  1903.           of this function could only be a name variable which con-
  1904.           tains the name value of the desired result of the function
  1905.           call.  Since there is no way to enforce proper use of this
  1906.           special operation, it would have to be up to the programmer
  1907.           to use it where it is required, and only where it is
  1908.           required, which is an undesirable but inescapable situation.
  1909.  
  1910.  
  1911.                                        27
  1912.  
  1913.  
  1914.  
  1915.  
  1916.  
  1917.  
  1918.  
  1919.  
  1920.  
  1921.  
  1922.           The problem arising from never assigning a name value
  1923.           returned from a function cannot be solved without explaining
  1924.           the situation to the programmer and leaving it up to him to
  1925.           do the right thing in each particular situation.  An easy
  1926.           convention would be, of course, to always assign the result
  1927.           of a function call to a variable.
  1928.  
  1929.                Alternatives considered, but abandoned as needlessly
  1930.           complex, included the following:
  1931.  
  1932.           (a)  Attach the names of all newly created dynamic objects,
  1933.                or those which are returned from a function via a spe-
  1934.                cial result operation with reference count equal to
  1935.                zero, to some globally known list of temporary values.
  1936.                The assignment operation applied to a name value on
  1937.                this list removes it from the list.  Name values left
  1938.                hanging around on this list must be reclaimed by a spe-
  1939.                cial operation invoked by the programmer when he knows
  1940.                that all possible temporary values are no longer
  1941.                required.
  1942.  
  1943.           (b)  Provide dynamic scope start and end operations.  All
  1944.                symbolic expression variables would have to be attached
  1945.                to some dynamic scope by use of a dynamic instantiation
  1946.                operation separate from the Ada declaration.  All tem-
  1947.                porary values not assigned to a variable are also
  1948.                attached to the current dynamic scope; values returned
  1949.                from functions via a special result operation with
  1950.                reference count equal to zero are attached to the
  1951.                dynamic scope enclosing the location of the function
  1952.                call.  On execution of the dynamic scope end operation,
  1953.                all values local to the dynamic scope are reclaimed.
  1954.  
  1955.  
  1956.  
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.                                        28
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.  
  1988.           2.3.2.2.  Garbage Collection
  1989.  
  1990.                Implementing a garbage collector is somewhat cumbersome
  1991.           in a language like Ada, since the only useful characteriza-
  1992.           tion of names is the name variable.  The only entity that
  1993.           knows about the locations of name values is the compiler.
  1994.           Therefore, name value tracking has to be implemented as name
  1995.           variable tracking, using some mechanism for maintaining a
  1996.           collection of dynamic name variables.  The approaches are
  1997.           all variations of the same basic theme of implementing the
  1998.           symbolic expression type as a reference to some dynamically
  1999.           allocated component of an object known to the storage allo-
  2000.           cation and reclamation operations.  Each such component is,
  2001.           or contains, a slot which is a name variable.
  2002.  
  2003.                Given this approach, whenever desired, the storage rec-
  2004.           lamation process knows where all of the name values for
  2005.           dynamic objects can be found, and, if it can also gain
  2006.           access to all allocated dynamic objects, it can mark all
  2007.           objects accessible from any name value and then locate all
  2008.           unmarked objects, which can be reclaimed.
  2009.  
  2010.                If each variable of type symbolic expression is allo-
  2011.           cated to a unique name variable in this global set of names,
  2012.           then the problems associated with aliasing via subprogram
  2013.           parameters, as discussed for reference counting, go away in
  2014.           the sense that side effects are consistently propagated to
  2015.           all aliases.  Operations which reclaim dynamic storage do
  2016.           not change the set of currently active names, so both
  2017.           aliases generated by an actual/formal parameter association
  2018.           always share the same dynamic object (or lack thereof).
  2019.           This has the disadvantage of potentially violating the
  2020.           spirit of Ada's parameter mode in, since a formal parameter
  2021.           could be modified and thus modify the actual parameter even
  2022.           in this mode.
  2023.  
  2024.                The problems associated with exit from the scope of a
  2025.           locally declared symbolic expression variable and with
  2026.           returning a symbolic expression as the result of a function
  2027.           call are essentially unchanged, requiring the same basic
  2028.           solutions, which are not repeated here.
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.                                        29
  2044.  
  2045.  
  2046.  
  2047.  
  2048.  
  2049.  
  2050.  
  2051.  
  2052.  
  2053.  
  2054.           2.3.2.3.  Summary
  2055.  
  2056.                Based upon the previous discussion, two subprograms
  2057.           will be provided for each AI data type to assist in storage
  2058.           management.
  2059.  
  2060.           (a)  A procedure to indicate that a variable is at the end
  2061.                of its scope and that its contents should be deallo-
  2062.                cated.
  2063.  
  2064.           (b)  A function which can decrement the reference count of a
  2065.                variable which is used to return a value from a func-
  2066.                tion.
  2067.  
  2068.                In addition, it has been determined that the use of
  2069.           limited private types will not provide sufficient assistance
  2070.           with storage management to overcome the disadvantages they
  2071.           impose.  Therefore, it has been decided that the AI data
  2072.           types developed in these packages be declared as private to
  2073.           provide sufficient data encapsulation without undue restric-
  2074.           tions.
  2075.  
  2076.  
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088.  
  2089.  
  2090.  
  2091.  
  2092.  
  2093.  
  2094.  
  2095.  
  2096.  
  2097.  
  2098.  
  2099.  
  2100.  
  2101.  
  2102.  
  2103.  
  2104.  
  2105.  
  2106.  
  2107.  
  2108.  
  2109.                                        30
  2110.  
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118.  
  2119.  
  2120.           2.3.3.  Multi-Tasking Synchronization
  2121.  
  2122.                Ada provides a powerful and general multi-tasking
  2123.           mechanism as an integral part of the language.  A task is an
  2124.           independent flow of control which interfaces in a discip-
  2125.           lined way with other flows of control, each with its own
  2126.           internal data.  The tasking constructs provide intertask
  2127.           communication using message passing.  The fact that tasks
  2128.           provide a high-level synchronization capability, and are the
  2129.           only Ada data type to provide such a capability, means that
  2130.           there will be many situations in which tasks will be used
  2131.           purely as a synchronizing mechanism to implement other con-
  2132.           trol abstractions, such as co-routines.
  2133.  
  2134.                In addition to high-level communication constructs,
  2135.           tasks provide high-level access to facilities commonly pro-
  2136.           vided in a machine-dependent fashion in other languages.
  2137.           For example, the delay statement enables a task to suspend
  2138.           its execution until at least the specified time interval has
  2139.           elapsed, allowing a program to control the frequency of its
  2140.           execution.
  2141.  
  2142.                Once the use of tasks as a primitive construct out of
  2143.           which more complex abstractions are built becomes common-
  2144.           place, complex applications composed of explicitly con-
  2145.           current or parallel processes will become readily accepted
  2146.           solutions.  Under these conditions, the problems of effi-
  2147.           ciently synchronizing access to shared global data must be
  2148.           dealt with.  This will become especially important when, for
  2149.           example, expert systems technology is applied to airborne
  2150.           applications and is installed within embedded computers in a
  2151.           multi-tasking environment.  Expecting that synchronization
  2152.           can be efficiently accomplished outside of the implementa-
  2153.           tion package for symbolic expressions is probably naive.
  2154.           This is especially true if the implementation of symbolic
  2155.           expressions includes hidden structure sharing.  It is more
  2156.           reasonable to expect that a version of the symbolic expres-
  2157.           sion package will be available which provides, internally,
  2158.           the proper synchronization efficiently tailored to the par-
  2159.           ticular implementation.
  2160.  
  2161.                The initial implementation will not provide such inter-
  2162.           nal synchronization mechanisms.  However, the interface to
  2163.           the symbolic expression facilities will be designed to allow
  2164.           such synchronization to be installed at the lowest implemen-
  2165.           tation levels within another version of the product without
  2166.           requiring changes to the visible interface.
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.  
  2174.  
  2175.                                        31
  2176.  
  2177.  
  2178.  
  2179.  
  2180.  
  2181.  
  2182.  
  2183.  
  2184.  
  2185.  
  2186.           3.  Functional Specifications
  2187.  
  2188.                All visible Ada type identifiers which represent the
  2189.           visible objects defined below will be defined as private.
  2190.           This will ensure that only the provided operations will be
  2191.           used to manipulate these objects.
  2192.  
  2193.           3.1.  Rulebases
  2194.  
  2195.           3.1.1.  Introduction
  2196.  
  2197.                The two major design decisions for rules are how to
  2198.           represent them and where to put them for fast retrieval.
  2199.           Retrieval of rules is independent of rule representation, so
  2200.           the approach taken is to encapsulate the retrieval issues
  2201.           within objects representing rulebases.  The representation
  2202.           issues for rules will be deferred to a lower level of
  2203.           abstraction.
  2204.  
  2205.                The term rulebase, as used here, refers to a collection
  2206.           of rules and facts representing a knowledge base, or to a
  2207.           temporary collection of facts, rules and a query represent-
  2208.           ing the current state of computation for a problem.
  2209.  
  2210.                Structure sharing is an important criteria for this
  2211.           implementation in order to avoid generating an exploding
  2212.           requirement for storage when rule data bases are manipulated
  2213.           with set operations which may be used to implement certain
  2214.           control strategies.
  2215.  
  2216.                An obvious solution to the requirement for fast
  2217.           retrieval is to provide some type of internal indexing of
  2218.           the rules present in a data base.  Since it is assumed that
  2219.           the structure of a rule is a set of terms in predicate form,
  2220.           separated by ANDs and ORs, a simple approach would be to
  2221.           build a hash table indexing the predicate symbols of each of
  2222.           the terms in a rule.
  2223.  
  2224.  
  2225.  
  2226.           3.1.2.  Objects
  2227.  
  2228.           (a)  Rulebase, which provides associative access, or content
  2229.                addressing, for its contents.  Retrieval of the con-
  2230.                tents is achieved by pattern-directed retrieval, which
  2231.                will allow access of the data base contents by partial
  2232.                specification of the desired content of a retrieval.
  2233.                Rulebase variables will allow implementation of
  2234.                extremely flexible control strategies for expert system
  2235.                and logic programming implementation.  For example,
  2236.                conditional execution of subsets of rules can be imple-
  2237.                mented by separating rules into individual rulebases
  2238.                which are selected for use at each unification step
  2239.  
  2240.  
  2241.                                        32
  2242.  
  2243.  
  2244.  
  2245.  
  2246.  
  2247.  
  2248.  
  2249.  
  2250.  
  2251.  
  2252.                using Ada's conditional control structures.  The set of
  2253.                rulebases could be implemented as an array of rule-
  2254.                bases.  This would provide a powerful mixture of non-
  2255.                procedural programming with the more conventional pro-
  2256.                cedural facilities of Ada.  This also eliminates the
  2257.                restriction to a single knowledge base common to con-
  2258.                ventional logic programming and production systems.
  2259.  
  2260.           (b)  The null rulebase, a constant representing a rulebase
  2261.                which has no rules.
  2262.  
  2263.  
  2264.  
  2265.           3.1.3.  Operations
  2266.  
  2267.           3.1.3.1.  Rulebase Operations
  2268.  
  2269.           (a)  Determine if a rulebase is empty.
  2270.  
  2271.           (b)  Determine if two rulebases are equivalent.
  2272.  
  2273.           (c)  Convert a rulebase to a symbolic expression.
  2274.  
  2275.           (d)  Convert a symbolic expression to a rulebase.
  2276.  
  2277.           (e)  Assign values to variables of type rulebase.
  2278.  
  2279.           (f)  Delete an unused rulebase.
  2280.  
  2281.           (g)  Return a rulebase bound to a local variable as the
  2282.                value of a function.
  2283.  
  2284.           (h)  Add a rule to a rulebase.
  2285.  
  2286.           (i)  Delete a rule from a rulebase.
  2287.  
  2288.           (j)  Associative retrieval using a rule as a query, yielding
  2289.                a symbolic expression containing instantiated values
  2290.                which satisfy the query.
  2291.  
  2292.           (k)  Set operations on rulebases - union ("and"), intersec-
  2293.                tion ("or"), difference ("-") and exclusive union
  2294.                ("xor").
  2295.  
  2296.           (l)  Input/output operations for rulebases.
  2297.  
  2298.                The conversion from/to symbolic exrepssions provides a
  2299.           primitive inteface between the symbolic computation facility
  2300.           and the logic programming facility.  The control strategies
  2301.           for logic programming all need some form of matching with
  2302.           variable binding, which suggests that the antecedent and
  2303.           consequent of a generalized rule should be implemented using
  2304.           patterns with pattern matching operations defined.  It is
  2305.  
  2306.  
  2307.                                        33
  2308.  
  2309.  
  2310.  
  2311.  
  2312.  
  2313.  
  2314.  
  2315.  
  2316.  
  2317.  
  2318.           intended that the contents of a rulebase are uninstantiated
  2319.           rules.
  2320.  
  2321.  
  2322.  
  2323.  
  2324.  
  2325.  
  2326.  
  2327.  
  2328.  
  2329.  
  2330.  
  2331.  
  2332.  
  2333.  
  2334.  
  2335.  
  2336.  
  2337.  
  2338.  
  2339.  
  2340.  
  2341.  
  2342.  
  2343.  
  2344.  
  2345.  
  2346.  
  2347.  
  2348.  
  2349.  
  2350.  
  2351.  
  2352.  
  2353.  
  2354.  
  2355.  
  2356.  
  2357.  
  2358.  
  2359.  
  2360.  
  2361.  
  2362.  
  2363.  
  2364.  
  2365.  
  2366.  
  2367.  
  2368.  
  2369.  
  2370.  
  2371.  
  2372.  
  2373.                                        34
  2374.  
  2375.  
  2376.  
  2377.  
  2378.  
  2379.  
  2380.  
  2381.  
  2382.  
  2383.  
  2384.           3.2.  Rules
  2385.  
  2386.           3.2.1.  Introduction
  2387.  
  2388.                The representation of rules depends primarily upon how
  2389.           variables are represented.  We will implement rules in terms
  2390.           of patterns and defer this issue to a lower level in the
  2391.           abstraction hierarchy.
  2392.  
  2393.  
  2394.  
  2395.           3.2.2.  Objects
  2396.  
  2397.                Other than as stated below, no interpretation is
  2398.           imposed by this level of abstraction on the contents of a
  2399.           rule.  Rules are represented as a data structure consisting
  2400.           of a template and a (possibly null) binding context.  The
  2401.           template is a pattern consisting of two sub-patterns which
  2402.           represent the (possibly null) antecedent and consequent
  2403.           parts.  When a rule is created, the two sub-patterns are
  2404.           treated as a single pattern so that the variable binding
  2405.           context is shared by both components of the rule template.
  2406.           This allows variable bindings to apply across an entire
  2407.           rule.
  2408.  
  2409.           (a)  Rules, which are a subtype of rule composed of a conse-
  2410.                quent, or head, and an antecedent, or body;  the
  2411.                interpretation of a rule is that the truth of the
  2412.                antecedent implies the truth of the consequent;
  2413.  
  2414.           (b)  Facts, which are a subtype of rule composed of a conse-
  2415.                quent only;  the interpretation of a fact is that the
  2416.                truth of the consequent does not depend on anything;
  2417.  
  2418.           (c)  Querys, which are a subtype of rule composed of an
  2419.                antecedent only;  the interpretation of a query is that
  2420.                the truth of the antecedent is unknown, but may be
  2421.                inferred from some collection of facts and rules with
  2422.                an appropriate inference mechanism;
  2423.  
  2424.           (d)  Variable binding context, which are associated with an
  2425.                instance of a rule during rule matching operations, and
  2426.                keep track of variable bindings.
  2427.  
  2428.           (e)  The null rule, a constant representing a rule which has
  2429.                a null antecedent, consequent and binding context.
  2430.  
  2431.  
  2432.  
  2433.           3.2.3.  Operations
  2434.  
  2435.           (a)  Determine if a rule is null.
  2436.  
  2437.  
  2438.  
  2439.                                        35
  2440.  
  2441.  
  2442.  
  2443.  
  2444.  
  2445.  
  2446.  
  2447.  
  2448.  
  2449.  
  2450.           (b)  Determine if one rule is equal to another.
  2451.  
  2452.           (c)  Determine if a rule is a fact, query or general rule.
  2453.  
  2454.           (d)  Create a rule by conversion from a symbolic expression.
  2455.  
  2456.           (e)  Convert a rule back to a symbolic expression.
  2457.  
  2458.           (f)  Extract the antecedent or consequent from a rule as a
  2459.                pattern.  The variable binding context of the extracted
  2460.                component is shared with the original rule.
  2461.  
  2462.           (g)  Extract the variable binding context from a rule.
  2463.  
  2464.           (h)  Associate a specific variable binding context with a
  2465.                rule.
  2466.  
  2467.           (i)  Match two rules, retaining variable bindings in the
  2468.                associated variable binding contexts.
  2469.  
  2470.           (j)  Instantiate a rule, yielding a symbolic expression with
  2471.                all variables replaced by the values to which they are
  2472.                bound.
  2473.  
  2474.           (k)  Make a rule unique by uniquely renaming all variables
  2475.                within the rule.
  2476.  
  2477.           (l)  Assign values to variables of type rule.
  2478.  
  2479.           (m)  Delete an unused rule value or rule instance value.
  2480.  
  2481.           (n)  Return a rule value bound to a local variable as the
  2482.                value of a function.
  2483.  
  2484.           (o)  Input/output operations for rules.
  2485.  
  2486.  
  2487.  
  2488.  
  2489.  
  2490.  
  2491.  
  2492.  
  2493.  
  2494.  
  2495.  
  2496.  
  2497.  
  2498.  
  2499.  
  2500.  
  2501.  
  2502.  
  2503.  
  2504.  
  2505.                                        36
  2506.  
  2507.  
  2508.  
  2509.  
  2510.  
  2511.  
  2512.  
  2513.  
  2514.  
  2515.  
  2516.           3.3.  Patterns
  2517.  
  2518.           3.3.1.  Introduction
  2519.  
  2520.                The representation of patterns depends upon how vari-
  2521.           ables are to be represented.  Our approach is based upon
  2522.           structure sharing of the literals of a pattern (the tem-
  2523.           plate) with binding list which is unique to each instance of
  2524.           a pattern.
  2525.  
  2526.           3.3.2.  Objects
  2527.  
  2528.           (a)  Pattern variables, which are special atomic components
  2529.                of a symbolic expression used to indicate component
  2530.                positions in an expression which will match an arbi-
  2531.                trary component of another expression.
  2532.  
  2533.           (b)  Patterns, which are symbolic expressions consisting of
  2534.                a pattern (possibly null) template and a (possibly
  2535.                null) binding context.
  2536.  
  2537.           (c)  Variable binding contexts, a collection of variable
  2538.                binding associations used to hold the result of a match
  2539.                operation for variables of a given pattern. Variable
  2540.                binding contexts are unique to a particular pattern,
  2541.                but may be shared by a pattern which is extracted from
  2542.                some other pattern.
  2543.  
  2544.           (d)  The null pattern, a constant representing a pattern
  2545.                with a null template and binding context.
  2546.  
  2547.  
  2548.  
  2549.           3.3.3.  Operations
  2550.  
  2551.           (a)  Determine if a pattern is null.
  2552.  
  2553.           (b)  Determine if one pattern is equal to another.
  2554.  
  2555.           (c)  Create a pattern by conversion from a symbolic expres-
  2556.                sion.
  2557.  
  2558.           (d)  Convert a pattern back to a symbolic expression.
  2559.  
  2560.           (e)  Extract the first component from a pattern.  The vari-
  2561.                able binding context of the extracted component is
  2562.                shared with the original pattern.
  2563.  
  2564.           (f)  Extract all components except the first from a pattern.
  2565.                The variable binding context of the extracted com-
  2566.                ponents is shared with the original pattern.
  2567.  
  2568.  
  2569.  
  2570.  
  2571.                                        37
  2572.  
  2573.  
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580.  
  2581.  
  2582.           (g)  Extract the variable binding context from a pattern.
  2583.  
  2584.           (h)  Associate a specific variable binding context with a
  2585.                pattern.
  2586.  
  2587.           (i)  Match two patterns, retaining variable bindings in the
  2588.                associated variable binding contexts.
  2589.  
  2590.           (j)  Instantiate a pattern, yielding a symbolic expression
  2591.                with all variables replaced by the values to which they
  2592.                are bound.
  2593.  
  2594.           (k)  Make a pattern unique by uniquely renaming all vari-
  2595.                ables within the pattern.
  2596.  
  2597.           (l)  Assign values to variables of type pattern.
  2598.  
  2599.           (m)  Delete an unused pattern.
  2600.  
  2601.           (n)  Return a pattern bound to a local variable as the value
  2602.                of a function.
  2603.  
  2604.           (o)  Input/output operations for patterns.
  2605.  
  2606.  
  2607.  
  2608.  
  2609.  
  2610.  
  2611.  
  2612.  
  2613.  
  2614.  
  2615.  
  2616.  
  2617.  
  2618.  
  2619.  
  2620.  
  2621.  
  2622.  
  2623.  
  2624.  
  2625.  
  2626.  
  2627.  
  2628.  
  2629.  
  2630.  
  2631.  
  2632.  
  2633.  
  2634.  
  2635.  
  2636.  
  2637.                                        38
  2638.  
  2639.  
  2640.  
  2641.  
  2642.  
  2643.  
  2644.  
  2645.  
  2646.  
  2647.  
  2648.           3.4.  Symbolic Expressions
  2649.  
  2650.           3.4.1.  Introduction
  2651.  
  2652.                A symbolic expression is either null, or is a single
  2653.           atomic component, or is an ordered collection of components,
  2654.           each of which is itself a symbolic expression.
  2655.  
  2656.                At each level of recursion in a symbolic expression,
  2657.           the components are ordered sequentially.  Consequently, it
  2658.           is easiest to deal with symbolic expressions in terms of
  2659.           this sequential component ordering.  A non-atomic symbolic
  2660.           expression is considered to have a first, component, which
  2661.           can be extracted directly.  The only other primitive access
  2662.           operation is to extract everything except the first com-
  2663.           ponent, that is, to extract the rest of the symbolic expres-
  2664.           sion.  The primitive construction operation prefix is the
  2665.           direct inverse of these two access operations, and makes two
  2666.           symbolic expressions into the first and rest components of a
  2667.           new symbolic expression.  Most of the other symbolic expres-
  2668.           sion manipulation operations are provided for efficiency and
  2669.           ease-of-use only, as they can all be defined in terms of
  2670.           these primitives.
  2671.  
  2672.  
  2673.  
  2674.           3.4.2.  Objects
  2675.  
  2676.           (a)  Atomic expressions, which contain values of some
  2677.                application-defined type.  It is assumed that, for any
  2678.                AI production program, the values of an atomic expres-
  2679.                sion are from at most a finite set of types.  The
  2680.                application developer can define the atomic type as a
  2681.                record with variant part encompassing the set of types
  2682.                if there is more than one atomic type required.
  2683.  
  2684.           (b)  Non-atomic expressions, which consist of an ordered
  2685.                collection of components, each of which is itself a
  2686.                symbolic expression.
  2687.  
  2688.           (c)  The null symbolic expression, which may be considered
  2689.                either atomic or non-atomic, depending on the context.
  2690.  
  2691.                The actual structure of a symbolic expression will be
  2692.           hidden from the user.
  2693.  
  2694.           3.4.3.  Operations
  2695.  
  2696.           (a)  Determine if a symbolic expression is null.
  2697.  
  2698.           (b)  Determine if a symbolic expression is atomic.
  2699.  
  2700.  
  2701.  
  2702.  
  2703.                                        39
  2704.  
  2705.  
  2706.  
  2707.  
  2708.  
  2709.  
  2710.  
  2711.  
  2712.  
  2713.  
  2714.           (c)  Determine if a symbolic expression is non-atomic.
  2715.  
  2716.           (d)  Determine if a symbolic expression is a variable.
  2717.  
  2718.           (e)  Determine if one symbolic expression is equal to
  2719.                another.
  2720.  
  2721.           (f)  Determine if one symbolic expression is a member of
  2722.                another.
  2723.  
  2724.           (g)  Create a symbolic expression from a user-supplied
  2725.                atomic value.
  2726.  
  2727.           (h)  Create a symbolic expression variable with a given
  2728.                name.
  2729.  
  2730.           (i)  Set the tag associated with a symbolic expression vari-
  2731.                able.
  2732.  
  2733.           (j)  Extract the user-supplied atomic value from a given
  2734.                atomic symbolic expression.
  2735.  
  2736.           (k)  Extract the name from a given symbolic expression vari-
  2737.                able.
  2738.  
  2739.           (l)  Extract the tag from a given symbolic expression vari-
  2740.                able.
  2741.  
  2742.           (m)  Assign values to variables of type symbolic expression.
  2743.  
  2744.           (n)  Delete an unused symbolic expression.
  2745.  
  2746.           (o)  Return a symbolic expression bound to a local variable
  2747.                as the value of a function.
  2748.  
  2749.           (p)  Prefix one symbolic expression onto another.
  2750.  
  2751.           (q)  Append one symbolic expression onto another.
  2752.  
  2753.           (r)  Determine the length (number of top-level components)
  2754.                of a symbolic expression.
  2755.  
  2756.           (s)  Extract the first component of a symbolic expression.
  2757.  
  2758.           (t)  Extract all components except the first of a symbolic
  2759.                expression.
  2760.  
  2761.           (u)  Extract the last component of a symbolic expression.
  2762.  
  2763.           (v)  Extract the nth component of a symbolic expression.
  2764.  
  2765.           (w)  Extract the first component of a symbolic expression n
  2766.                times using the result of the previous extraction as
  2767.  
  2768.  
  2769.                                        40
  2770.  
  2771.  
  2772.  
  2773.  
  2774.  
  2775.  
  2776.  
  2777.  
  2778.  
  2779.  
  2780.                the new argument.
  2781.  
  2782.           (x)  Extract all components except the first of a symbolic
  2783.                expression n times using the result of the previous
  2784.                extraction as the new argument.
  2785.  
  2786.           (y)  Reverse the order of components within a symbolic
  2787.                expression.
  2788.  
  2789.           (z)  Delete all top-level occurrences of one symbolic
  2790.                expression from another.
  2791.  
  2792.           (aa) Replace all top-level occurrences of one symbolic
  2793.                expression within another with a new symbolic expres-
  2794.                sion.
  2795.  
  2796.           (bb) Flatten a symbolic expression by extracting all non-
  2797.                atomic components while retaining all atomic components
  2798.                of the given symbolic expression.
  2799.  
  2800.           (cc) Set operations on symbolic expressions - union ("and"),
  2801.                intersection ("or"), difference ("-") and exclusive
  2802.                union ("xor").
  2803.  
  2804.           (dd) Extract either the first or all the non-atomic com-
  2805.                ponents of a symbolic expression whose first component
  2806.                matches a given symbolic expression.
  2807.  
  2808.           (ee) Input/output operations for symbolic expressions.
  2809.  
  2810.  
  2811.  
  2812.  
  2813.  
  2814.  
  2815.  
  2816.  
  2817.  
  2818.  
  2819.  
  2820.  
  2821.  
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.  
  2832.  
  2833.  
  2834.  
  2835.                                        41
  2836.  
  2837.  
  2838.  
  2839.  
  2840.  
  2841.  
  2842.  
  2843.  
  2844.  
  2845.  
  2846.  
  2847.  
  2848.  
  2849.  
  2850.  
  2851.  
  2852.  
  2853.  
  2854.  
  2855.  
  2856.  
  2857.  
  2858.  
  2859.  
  2860.  
  2861.  
  2862.  
  2863.  
  2864.  
  2865.  
  2866.  
  2867.  
  2868.  
  2869.  
  2870.  
  2871.  
  2872.  
  2873.  
  2874.  
  2875.  
  2876.  
  2877.  
  2878.  
  2879.  
  2880.  
  2881.  
  2882.  
  2883.  
  2884.  
  2885.  
  2886.  
  2887.  
  2888.  
  2889.  
  2890.  
  2891.  
  2892.  
  2893.  
  2894.  
  2895.  
  2896.  
  2897.  
  2898.  
  2899.  
  2900.  
  2901.                                        42
  2902.  
  2903.  
  2904.  
  2905.  
  2906.  
  2907.  
  2908.  
  2909.  
  2910.  
  2911.  
  2912.  
  2913.  
  2914.  
  2915.  
  2916.  
  2917.  
  2918.  
  2919.  
  2920.  
  2921.  
  2922.  
  2923.  
  2924.  
  2925.  
  2926.  
  2927.  
  2928.  
  2929.  
  2930.  
  2931.  
  2932.  
  2933.  
  2934.  
  2935.  
  2936.  
  2937.                              Final Technical Report
  2938.  
  2939.  
  2940.  
  2941.  
  2942.  
  2943.  
  2944.  
  2945.  
  2946.  
  2947.  
  2948.  
  2949.  
  2950.  
  2951.  
  2952.  
  2953.  
  2954.  
  2955.  
  2956.  
  2957.  
  2958.  
  2959.  
  2960.  
  2961.  
  2962.  
  2963.  
  2964.  
  2965.  
  2966.  
  2967.  
  2968.  
  2969.  
  2970.  
  2971.  
  2972.  
  2973.  
  2974.  
  2975.  
  2976.  
  2977.  
  2978.           1.  Introduction
  2979.  
  2980.           The  C2  Support  Software  in  Ada  to   be   provided   by
  2981.           Software A & E  consists  of  a generic package, the AI Data
  2982.           Types package, which  provides  facilities  to  support  the
  2983.           development  of Artificial Intelligence (AI) applications in
  2984.           Ada.  These facilities include:
  2985.  
  2986.           (1)  Definitions of the  primary  data  object  to  be  used
  2987.                throughout this package, the symbolic expression.
  2988.  
  2989.           (2)  Symbolic expressions operators.  These include  subpro-
  2990.                grams  for  the  creation,  selection, manipulation and
  2991.                destruction of symbolic expressions.
  2992.  
  2993.           (3)  Packages which  define  generic  AI  objects  generally
  2994.                found useful in AI applications (patterns, rules, rule-
  2995.                bases) and supporting operations such as pattern match-
  2996.                ing and deductive rulebase retrieval.
  2997.  
  2998.           2.  Purpose
  2999.  
  3000.           The purpose of this document is to summarize experiences  in
  3001.           Ada  software  engineering  on the above mentioned contract.
  3002.           The topics covered by this report  include  program  statis-
  3003.           tics, notes on the design, implementation and test phases of
  3004.           the project, experiences with  Ada  and  Ada  compilers  and
  3005.           thoughts  about documentation and the support of distributed
  3006.           software engineering in a network culture.
  3007.  
  3008.           This document, the Final Technical Report, is  part  two  of
  3009.           two  of  the final delivery of CDRL A002 (Informal Technical
  3010.           Information) for contract N66001-85-C-0039 between  Software
  3011.           Architecture  and  Engineering, Inc. and Naval Ocean Systems
  3012.           Center, 271 Catalina Boulevard, Building A33, San Diego,  CA
  3013.           92152.
  3014.  
  3015.           3.  Program Statistics
  3016.  
  3017.           The AI_Data_Types package is a  generic  package  containing
  3018.           four subordinate packages each of which supports the defini-
  3019.           tion of one of the following abstract AI  data  types:  sym-
  3020.           bolic  expressions, patterns, rule and rulebases.  The pack-
  3021.           age consists of approximately 2000 lines of Ada  code  (3500
  3022.           including  comments)  and was implemented using DEC Ada on a
  3023.           VAX 11/780 under VMS/Eunice, an environment providing access
  3024.           to  both  UNIX and VMS.  Non-generic versions of the package
  3025.           were also implemented using Telesoft Ada,  Version  2.1  and
  3026.           the  DG/Rolm Ada compiler.  Additional supporting facilities
  3027.           such as  test  programs  and  demonstrations  accounted  for
  3028.           another 3000 lines of commented Ada code.
  3029.  
  3030.  
  3031.  
  3032.  
  3033.                                        1
  3034.  
  3035.  
  3036.  
  3037.  
  3038.  
  3039.  
  3040.  
  3041.  
  3042.  
  3043.  
  3044.           4.  Design, Implementation and Testing Statistics
  3045.  
  3046.           As of  the  last  progress  report,  2458.5  man-hours  were
  3047.           expended  on  this  project.  The work done during this time
  3048.           can be categorized into three areas:
  3049.  
  3050.           (a) Design
  3051.               The work done as part of design accounted for the  larg-
  3052.               est  portion  of  the  project.  Of the 2458.5 man-hours
  3053.               expended on the project,  approximately  1354  of  these
  3054.               (55%)  were  devoted to design.   The tasks accomplished
  3055.               under design were:
  3056.  
  3057.               (1) Developing the preliminary interface  specifications
  3058.                   and design document.
  3059.  
  3060.               (2) Assessing the suitability of the  GFE  computer  and
  3061.                   Ada compiler for the needs of the project.
  3062.  
  3063.               (3) Developing a draft  top-level  design  document  and
  3064.                   user's manual.
  3065.  
  3066.               (4) Preparing  for  and  holding  a  preliminary  design
  3067.                   review (PDR) attended by members of World-Wide Mili-
  3068.                   tary Command and Control System (WWMCCS) Information
  3069.                   Systems (WIS).
  3070.  
  3071.               (5) Developing  documents  which  discussed  the  issues
  3072.                   raised at the PDR.
  3073.  
  3074.               (6) Prototyping portions of the  design  to  verify  the
  3075.                   completeness  of  the operators provided by the pro-
  3076.                   ject.
  3077.  
  3078.               (7) Revising the top-level design document based on  the
  3079.                   changes  suggested  at  the  PDR and those resulting
  3080.                   from the prototyping exercise.
  3081.  
  3082.           (b) Implementation
  3083.               Implementation of the  resulting  design  accounted  for
  3084.               approximately 702.5 hours (29%) of the time spent on the
  3085.               project.  The tasks completed during this phase  of  the
  3086.               project included:
  3087.  
  3088.               (1) Implementing the packages and operators provided  by
  3089.                   the project.
  3090.  
  3091.               (2) Providing  solutions  and  workarounds  to  problems
  3092.                   raised  by  the  use  of  GFE computers and Ada com-
  3093.                   pilers. Examples of problems raised by  the  use  of
  3094.                   GFE  computers  include disk space and response time
  3095.                   limitations.  Limitations imposed  by  Telesoft  Ada
  3096.                   (Version  2.1)  included  the  inability  to support
  3097.  
  3098.  
  3099.                                        2
  3100.  
  3101.  
  3102.  
  3103.  
  3104.  
  3105.  
  3106.  
  3107.  
  3108.  
  3109.  
  3110.                   generics, subunits, certain types of  short  circuit
  3111.                   control   forms  and  certain  discriminated  record
  3112.                   types.   There were also restrictions imposed by the
  3113.                   use of DEC Ada which included limitations on the use
  3114.                   of records with unconstrained discriminants,  access
  3115.                   to  enumeration literal values declared within other
  3116.                   packages without the use of an Ada "use" clause  and
  3117.                   non-standard  restrictions  on the order of variable
  3118.                   and program declarations.
  3119.  
  3120.               (3) Porting to  a  Data  General  computer  to  use  the
  3121.                   Rolm/DG  Ada  compiler  to solve the problems engen-
  3122.                   dered by the use of TeleSoft Ada.
  3123.  
  3124.               (4) Modifying the code to work under DEC Ada.
  3125.  
  3126.               (5) Unit testing.
  3127.  
  3128.           (c) Testing
  3129.               Testing accounted for the remaining 402 man-hours  (16%)
  3130.               expended  on  the project.  The tasks accomplished under
  3131.               testing included:
  3132.  
  3133.               (1) Developing programs used to demonstrate the  use  of
  3134.                   the facilities provided by the packages developed on
  3135.                   the project.
  3136.  
  3137.               (2) Correcting any errors raised by the execution of the
  3138.                   above programs.
  3139.  
  3140.           5.  Experiences in Ada Software Development
  3141.  
  3142.           The project's  use  of  such  Ada  constructs  as  packages,
  3143.           private  and  limited  private types, constrained and uncon-
  3144.           strained discriminated record types and  access  types  pro-
  3145.           vided  an excellent opportunity to use those features of the
  3146.           language which make Ada truly unique with respect  to  other
  3147.           languages.   Using  these facilities also provided an oppor-
  3148.           tunity to explore the state of the art in Ada compiler  con-
  3149.           struction.    The  following  two  sections will concentrate
  3150.           upon features of the Ada language and characteristics of the
  3151.           Ada  compilers  used  which were found to be most helpful or
  3152.           detrimental in the construction of the  AI_Data_Types  pack-
  3153.           age.
  3154.  
  3155.           5.1.  Ada Language Features
  3156.  
  3157.           One of Ada's most helpful features is  its  highly  readable
  3158.           syntax.   It  was this feature that provided the opportunity
  3159.           to use the language in the design phase as a program  design
  3160.           language.  Specifications for the facilities provided by the
  3161.           AI_Data_Types package were  written  and  compiled  to  help
  3162.           insure  the semantic consistency of the design.  This use of
  3163.  
  3164.  
  3165.                                        3
  3166.  
  3167.  
  3168.  
  3169.  
  3170.  
  3171.  
  3172.  
  3173.  
  3174.  
  3175.  
  3176.           Ada as a PDL helped to finalize the design and  provided  an
  3177.           ideal bridge from the design to the implementation phases of
  3178.           the project.
  3179.  
  3180.           Another benefit is the presence of language features such as
  3181.           packages  and private types which provide direct support for
  3182.           the creation of encapsulated data types.  It was  this  sup-
  3183.           port  that  was the most beneficial to the project.  By pro-
  3184.           viding a means of restricting access to the data types  pro-
  3185.           vided  by  the packages, using Ada helped to reduce the com-
  3186.           plexity of the programs by reducing side effects and enforc-
  3187.           ing a clean interface between packages.
  3188.  
  3189.           Among those features which were detrimental to  the  project
  3190.           was  the  absence of good string definition and manipulation
  3191.           facilities.  In Ada, the length of a string  variable  is  a
  3192.           static  characteristic,  once the variable is declared to be
  3193.           of a specific length only strings  of  that  length  can  be
  3194.           assigned  to  that variable.  This is, in many cases, highly
  3195.           inconvenient.  Ada does provide a mechanism by which one can
  3196.           circumvent  this  restriction.   This  involves  declaring a
  3197.           discriminated record containing an array whose  upper  bound
  3198.           depends  on the record discriminant.  By providing a default
  3199.           value for the discriminant, one can then  simulate  variable
  3200.           length  strings by declaring variables of this unconstrained
  3201.           discriminated record type and using aggregates  composed  of
  3202.           the  string  length  and  the string value to do assignment.
  3203.           However, this appears to be a difficult feature to implement
  3204.           due to the fact that two of the compilers (Telesoft V2.1 and
  3205.           DEC Ada) do not handle it properly.  Therefore, without this
  3206.           mechanism,  simulating  variable  length  strings was fairly
  3207.           difficult, limited and verbose.
  3208.  
  3209.           Another aspect which was mildly restrictive dealt  with  the
  3210.           input  and  output  facilities  provided  by  the  language.
  3211.           Checking for end of file while doing character IO amounts to
  3212.           surrounding  the  code  doing  the  reading with a begin-end
  3213.           block and placing an exception handler for END_ERROR at  the
  3214.           end of the block.  This seems a bit extreme.  Another annoy-
  3215.           ance was the difficulty of moving the current position of  a
  3216.           file  backward, a helpful feature when doing certain parsing
  3217.           operations.
  3218.  
  3219.           5.2.  Ada Compiler Usage
  3220.  
  3221.           Three different compilers were used during  the  development
  3222.           of this project.  These were TeleSoft Ada (Version 2.1 under
  3223.           VMS), Rolm/Data General Ada and DEC Ada.
  3224.  
  3225.           TeleSoft Ada served as the introduction to Ada for the  pro-
  3226.           ject  and  it  quickly  became apparent that it would not be
  3227.           sufficient for the original generic  design  that  had  been
  3228.           planned.   Although  a  successful  version  of the Symbolic
  3229.  
  3230.  
  3231.                                        4
  3232.  
  3233.  
  3234.  
  3235.  
  3236.  
  3237.  
  3238.  
  3239.  
  3240.  
  3241.  
  3242.           Expressions  package  was  built  and   demonstrated   using
  3243.           TeleSoft Ada, this was not without effort.  The following is
  3244.           a description of  a  number  of  errors  found  while  using
  3245.           TeleSoft Ada and the impact upon the project.
  3246.  
  3247.           (1)  The first major problem was the discovery  of  numerous
  3248.                restrictions  on the use of generic packages.  The most
  3249.                significant restrictions were  those  which  prohibited
  3250.                the use of private and discriminated types with in gen-
  3251.                eric packages.  Similar restrictions  held  for  incom-
  3252.                plete  types,  tasks  and  nested generic declarations.
  3253.                After discovering this, a decision was made to continue
  3254.                with the implementation of a non-generic version of the
  3255.                package until a different compiler could be provided.
  3256.  
  3257.           (2)  However, even the non-generic version  of  the  package
  3258.                could not be implemented as planned.  TeleSoft Ada res-
  3259.                tricted the size of package implementations was limited
  3260.                to  32K.   At one point, this required the splitting of
  3261.                the Symbolic Expressions package into two modules, thus
  3262.                eliminating  the possibility of using private types for
  3263.                the project while using TeleSoft Ada.
  3264.  
  3265.           (3)  A chance to save some development time was lost due  to
  3266.                the  fact  that subunits were not properly implemented.
  3267.                Because the Symbolic Expressions package  consisted  of
  3268.                approximately  45  different  functions,  it would have
  3269.                speeded the implementation phase considerably if  these
  3270.                functions  could have been compiled separately to avoid
  3271.                recompiling the entire set of functions  each  time  an
  3272.                error  was  found.   However, because subunits were not
  3273.                properly implemented, this was out of the question.
  3274.  
  3275.           (4)  Short circuit control forms (and then, or else) did not
  3276.                function  properly.   This  forced  the  recoding  of a
  3277.                number of routines using a less efficient nested condi-
  3278.                tional approach.
  3279.  
  3280.           (5)  As mentioned  previously,  discriminated  record  types
  3281.                with a discriminant which denotes the upper bound of an
  3282.                array declared  within  the  record  did  not  function
  3283.                correctly.   This required the implementation of a more
  3284.                limited scheme for handling variable length strings.
  3285.  
  3286.           (6)  The check for the equality of two variant  records  was
  3287.                not  implemented correctly.  It appeared that the space
  3288.                following the contents of the  currently  valid  record
  3289.                slots was also being used in the comparison.
  3290.  
  3291.           (7)  A final observation, which was not specifically a  com-
  3292.                piler  bug, was that each user of the TeleSoft Ada com-
  3293.                piler was required to have  a  copy  of  a  1  megabyte
  3294.                TeleSoft  program  library  resident  in  a  particular
  3295.  
  3296.  
  3297.                                        5
  3298.  
  3299.  
  3300.  
  3301.  
  3302.  
  3303.  
  3304.  
  3305.  
  3306.  
  3307.  
  3308.                directory on their  account.   Therefore,  the  use  of
  3309.                TeleSoft Ada placed a large burden on disk resources.
  3310.  
  3311.           To alleviate some of the problems caused by the use  of  the
  3312.           TeleSoft Ada compiler, an effort was made to port the imple-
  3313.           mentation of the Symbolic Expressions package to a Data Gen-
  3314.           eral  computer which had the Rolm/Data General Ada compiler.
  3315.           Although this compiler was used only for a  short  time,  it
  3316.           did  help  to bring the implementation back in line with the
  3317.           original design.  Because the restriction  on  the  size  of
  3318.           packages was no longer an issue, the two packages comprising
  3319.           the Symbolic Expressions package at that time were collapsed
  3320.           into  one  and  the  symbolic  expression data type was made
  3321.           private.  No significant problems were  noticed  when  using
  3322.           Rolm/Data  General Ada.  However, due to the short amount of
  3323.           time the compiler was actually used, an in depth  evaluation
  3324.           was not done.
  3325.  
  3326.           It was at this time that NOSC installed  the  DEC  Ada  com-
  3327.           piler.   Having heard generally favorable comments about DEC
  3328.           Ada, it was decided to attempt the  generic  package  design
  3329.           originally proposed for the project.  The latest implementa-
  3330.           tions of the various packages were sent back to NOSC and the
  3331.           project began using DEC Ada.
  3332.  
  3333.           The results were phenomenal.  Within one month and  a  half,
  3334.           the final generic version of the package was completed and a
  3335.           demonstration program constructed.   The  DEC  Ada  compiler
  3336.           performed  quickly  and  competently  and  provided the most
  3337.           detailed error diagnostics of the three compilers used.   It
  3338.           can be conjectured that if the DEC Ada compiler had been the
  3339.           original compiler provided, implementation time  could  have
  3340.           been cut by 25 to 50 percent.
  3341.  
  3342.           However, this is not to say that the  DEC  Ada  compiler  is
  3343.           problem-free.   Three  apparent deviations from standard Ada
  3344.           seem to be present in DEC Ada.  These are:
  3345.  
  3346.           (1)  Once again, discriminated record types with a  discrim-
  3347.                inant  which  denotes  the  upper  bound  of  an  array
  3348.                declared within the record did not function  correctly.
  3349.                Programs using this feature would compile and link suc-
  3350.                cessfully but  would  cause  a  run-time  NUMERIC_ERROR
  3351.                exception when elaborating the type declaration.
  3352.  
  3353.           (2)  DEC Ada places a restriction  on  the  order  in  which
  3354.                variables  and  subprograms local to a particular scope
  3355.                can be declared.  When declaring subprograms and  vari-
  3356.                ables  local  to another subprogram, the variables must
  3357.                be declared before the subprograms; otherwise, a compi-
  3358.                lation error is raised.  An instance where this becomes
  3359.                difficult to work with is the case where  a  subprogram
  3360.                is  declared  to  be  used  in  instantiating a generic
  3361.  
  3362.  
  3363.                                        6
  3364.  
  3365.  
  3366.  
  3367.  
  3368.  
  3369.  
  3370.  
  3371.  
  3372.  
  3373.  
  3374.                package, the generic package is instantiated  and  then
  3375.                an  attempt is made to declare variables based on types
  3376.                exported by the package.   These  variables  cannot  be
  3377.                declared without creating a local block and placing the
  3378.                variable declarations within the block.
  3379.  
  3380.           (3)  The final  anomaly  noted  with  DEC  Ada  concerns  an
  3381.                attempt  to  access  the literals of an enumerated type
  3382.                declared in another package using only a with statement
  3383.                for  the  package and a qualifier using the appropriate
  3384.                package name and type.  The compiler does not recognize
  3385.                the  value  as a literal of the desired type.  However,
  3386.                when a "use" clause is given containing the name of the
  3387.                package  in  which the enumerated type is declared, the
  3388.                compiler recognizes the  value  as  a  literal  of  the
  3389.                appropriate type even without qualification.
  3390.  
  3391.           Examples of these errors and the programs that  caused  them
  3392.           are listed in the Appendices.
  3393.  
  3394.           6.  Documentation and Distributed Software Engineering
  3395.  
  3396.           The final topic which this report is to discuss  is  methods
  3397.           for  streamlining  the documentation process to support dis-
  3398.           tributed software engineering in  a  network  culture.   The
  3399.           primary problem with development in a network culture is the
  3400.           dissemination of  information.   Attempting  to  obtain  and
  3401.           manage  this  distributed  information  can quickly become a
  3402.           logistical nightmare.  Also, with software  development  and
  3403.           maintenance  being  the  most costly aspect of computer sys-
  3404.           tems, it is crucial to monitor projects as closely as possi-
  3405.           ble.   Ada  and its promise of reusable software promises to
  3406.           provide some relief from this cost burden.  Yet, determining
  3407.           what efforts have previously been put forward to avoid their
  3408.           duplication simply  becomes  another  additional  aspect  of
  3409.           managing  the  information  and documentation present in the
  3410.           distributed system.  Thus, with the use of Ada this  problem
  3411.           becomes an even more crucial concern.
  3412.  
  3413.           How then is one to manage this voluminous quantity of  docu-
  3414.           mentation?  Centralization of this information might offer a
  3415.           solution.  Efforts to this effect already seem to be  under-
  3416.           way, with the Ada Repository being a prime example.  The Ada
  3417.           Repository consists of a  collection  of  Ada  programs  and
  3418.           documentation  housed  on  a computer at White Sands Missile
  3419.           Range.  Access to the repository is available to  all  users
  3420.           of  Defense  Data  Network  (DDN) hosts.  Therefore, the Ada
  3421.           Repository serves to centralize and  categorize  information
  3422.           and promote the reusability of Ada software.
  3423.  
  3424.           There may be situations in which placing  the  documentation
  3425.           itself  in  a  central location is not possible.  If this is
  3426.           the case, then a possible solution  may  be  to  maintain  a
  3427.  
  3428.  
  3429.                                        7
  3430.  
  3431.  
  3432.  
  3433.  
  3434.  
  3435.  
  3436.  
  3437.  
  3438.  
  3439.  
  3440.           centralized  data base which one can query to find where the
  3441.           information can actually be found.
  3442.  
  3443.           Although the centralizing of information is a good  starting
  3444.           point,  there  is another factor which creates a problem for
  3445.           distributed software engineering.   It is an  accepted  fact
  3446.           that  the  software  life  cycle  is  an  iterative process.
  3447.           Software development is not a simple progression from design
  3448.           to  implementation,  implementation  to  testing, testing to
  3449.           delivery but tends to be  a  circular  process.   Therefore,
  3450.           change in the form of documentation updates is an inevitable
  3451.           part of any software engineering effort.   This  problem  is
  3452.           magnified  in  a  network  environment  due to the fact that
  3453.           those people making updates and those  people  who  have  to
  3454.           know of the updates are not localized.
  3455.  
  3456.           This sort of problem argues for a specific protocol for han-
  3457.           dling documentation updates. In fact, this protocol might be
  3458.           handled by a software tool, a documentation control  system,
  3459.           which would provide functions such as:
  3460.  
  3461.           (1)  maintaining statistics of which  users  accessed  which
  3462.                documentation.
  3463.  
  3464.           (2)  providing multiple versions of documentation to provide
  3465.                a  method by which users could obtain documentation for
  3466.                any particular version of the system in question.
  3467.  
  3468.           (3)  notifying interested parties of updates  based  on  the
  3469.                lists  of  users who previously accessed the older ver-
  3470.                sions of the documentation.
  3471.  
  3472.  
  3473.  
  3474.  
  3475.  
  3476.  
  3477.  
  3478.  
  3479.  
  3480.  
  3481.  
  3482.  
  3483.  
  3484.  
  3485.  
  3486.  
  3487.  
  3488.  
  3489.  
  3490.  
  3491.  
  3492.  
  3493.  
  3494.  
  3495.                                        8
  3496.  
  3497.  
  3498.  
  3499.  
  3500.  
  3501.  
  3502.  
  3503.  
  3504.  
  3505.  
  3506.           7.  APPENDICES
  3507.  
  3508.           7.1.  Discriminated Record Type Problem
  3509.  
  3510.           The  following  Ada  program  demonstrates  a  problem  with
  3511.           discriminated  record  types containing an array whose upper
  3512.           bound depends upon the descriminant.  This program  compiles
  3513.           and  links  without  error  and causes the runtime exception
  3514.           listed after the code.
  3515.  
  3516.           procedure Adabug1 is
  3517.              type Dyn_String (Length : Natural := 80) is
  3518.                 record
  3519.                    Dyn_Str : String (1 .. Length);
  3520.                 end record;
  3521.  
  3522.              D_Str1 : Dyn_String;
  3523.           begin
  3524.              D_Str1 := (6, "string");
  3525.           end Adabug1;
  3526.  
  3527.           %ADA-I-NUMERIC_ERROR, NUMERIC_ERROR
  3528.           %SYSTEM-F-INTOVF, arithmetic trap, integer overflow at PC=00000646,
  3529.            PSL=03C000AA
  3530.           %TRACE-F-TRACEBACK, symbolic stack dump follows
  3531.           module name     routine name           line       rel PC    abs PC
  3532.  
  3533.           ADABUG1         DYN_STRING$MAX_SIZE11     2      00000010  00000646
  3534.           ADABUG1         ADABUG1                   7      00000015  0000066A
  3535.           ADA$ELAB_ADABUG ADA$ELAB_ADABUG1                 00000009  00000609
  3536.                                                            00000717  00000717
  3537.                                                            0000C833  0000C833
  3538.           ADA$ELAB_ADABUG ADA$ELAB_ADABUG1                 0000001B  0000061B
  3539.                                                            000006F2  000006F2
  3540.  
  3541.  
  3542.  
  3543.  
  3544.  
  3545.  
  3546.  
  3547.  
  3548.  
  3549.  
  3550.  
  3551.  
  3552.  
  3553.  
  3554.  
  3555.  
  3556.  
  3557.  
  3558.  
  3559.  
  3560.  
  3561.                                        9
  3562.  
  3563.  
  3564.  
  3565.  
  3566.  
  3567.  
  3568.  
  3569.  
  3570.  
  3571.  
  3572.           7.2.  Declaration Order Restriction Problem
  3573.  
  3574.           DEC Ada requires the declaration of all variables before any
  3575.           local  program  declarations.   This  Ada program causes the
  3576.           generation of a compilation error to this effect.
  3577.  
  3578.           procedure Adabug2 is
  3579.              procedure Local_Subprogram is
  3580.                 A : Integer;
  3581.              begin
  3582.                 A := 1;
  3583.              end Local_Subprogram;
  3584.  
  3585.              B : Integer;
  3586.           begin
  3587.              B := 2;
  3588.           end Adabug2;
  3589.  
  3590.           $ ada/nolist/warnings=(warn:terminal,weak:terminal,supp:terminal,
  3591.             status:terminal ,comp:none) dba4:[contr07.ada]ADABUG2.ADA
  3592.  
  3593.               8      B : Integer;
  3594.           %ADAC-E-BASICAFTLATER, (1) Basic-declaration not allowed after
  3595.                   later-declarations which begin at line 2
  3596.           %ADAC-E-ERRCOMPILE, Error(s) compiling procedure body Adabug2 in file
  3597.                   DBA4:[CONTR07.ADA]ADABUG2.ADA;1
  3598.             Errors:                    2
  3599.             Peak working set:        750
  3600.             Virtual pages used:     5346
  3601.             Virtual pages free:    38654
  3602.             CPU Time:              00:00:00.82    (804 Lines/Minute)
  3603.             Elapsed Time:          00:00:01.38
  3604.             Compilation Complete
  3605.           %ADAC-E-ENDDIAGS, Ada compilation completed with 1 diagnostic
  3606.  
  3607.  
  3608.  
  3609.  
  3610.  
  3611.  
  3612.  
  3613.  
  3614.  
  3615.  
  3616.  
  3617.  
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623.  
  3624.  
  3625.  
  3626.  
  3627.                                        10
  3628.  
  3629.  
  3630.  
  3631.  
  3632.  
  3633.  
  3634.  
  3635.  
  3636.  
  3637.  
  3638.           7.3.  Enumeration Literal Access Problem
  3639.  
  3640.           The following package specification and subprogram cause the
  3641.           given compilation errors.  Is there any other way to qualify
  3642.           the enumerated literals to make  them  recognizable  by  the
  3643.           compiler  without  the  use  of a "use" clause?   As will be
  3644.           seen later, the use of a "use" clause prevents the  compila-
  3645.           tion errors.
  3646.  
  3647.           package Package_Adabug3 is
  3648.  
  3649.              type Color_Kind is (Red, Yellow, Blue);
  3650.              type Color_Value (Kind : Color_Kind := Red) is
  3651.                 record
  3652.                    case Kind is
  3653.                       when Red    => Red    : String (1 .. 3);
  3654.                       when Yellow => Yellow : String (1 .. 6);
  3655.                       when Blue   => Blue   : String (1 .. 4);
  3656.                    end case;
  3657.                 end record;
  3658.  
  3659.           end Package_Adabug3;
  3660.  
  3661.           with Package_Adabug3;
  3662.           with Text_Io;
  3663.           procedure Prog_Adabug3 is
  3664.              procedure Local_Subprogram (Color_Val :
  3665.                                          Package_Adabug3.Color_Value) is
  3666.              begin
  3667.                 case Color_Val.Kind is
  3668.                    when Package_Adabug3.Color_Kind'(Red)
  3669.                         => Text_Io.Put ("Red");
  3670.                    when Package_Adabug3.Color_Kind'(Yellow)
  3671.                         => Text_Io.Put ("Yellow");
  3672.                    when Package_Adabug3.Color_Kind'(Blue)
  3673.                         => Text_Io.Put ("Blue");
  3674.                 end case;
  3675.              end Local_Subprogram;
  3676.           begin
  3677.              null;
  3678.           end Prog_Adabug3;
  3679.           $ ada/nolist/warnings=(warn:terminal,weak:terminal,supp:terminal,
  3680.             status:terminal,comp:none) dba4:[contr07.ada]ADABUG3.ADA
  3681.           %ADAC-I-CL_ADDED, Package specification PACKAGE_ADABUG3 added to library
  3682.               Replaces older version compiled 15-Mar-1986 23:16
  3683.  
  3684.              21  when Package_Adabug3.Color_Kind'(Red)
  3685.           %ADAC-E-NOTDECL, (1) Red is not declared
  3686.           %ADAC-I-POSSUSE, (1) Possibly a use clause for or selected component
  3687.                    of package Package_Adabug3 in Package_Adabug3 at line 1 was
  3688.                    intended
  3689.           %ADAC-E-EXPNOTSTATIC, (2) Expression is not static
  3690.  
  3691.  
  3692.  
  3693.                                        11
  3694.  
  3695.  
  3696.  
  3697.  
  3698.  
  3699.  
  3700.  
  3701.  
  3702.  
  3703.  
  3704.              23  when Package_Adabug3.Color_Kind'(Yellow)
  3705.           %ADAC-E-NOTDECL, (1) Yellow is not declared
  3706.           %ADAC-I-POSSUSE, (1) Possibly a use clause for or selected component
  3707.                   of package Package_Adabug3 in Package_Adabug3 at line 1 was
  3708.                   intended
  3709.           %ADAC-E-EXPNOTSTATIC, (2) Expression is not static
  3710.  
  3711.              25  when Package_Adabug3.Color_Kind'(Blue)
  3712.           %ADAC-E-NOTDECL, (1) Blue is not declared
  3713.           %ADAC-I-POSSUSE, (1) Possibly a use clause for or selected component
  3714.                  of package Package_Adabug3 in Package_Adabug3 at line 1 was
  3715.                  intended
  3716.           %ADAC-E-EXPNOTSTATIC, (2) Expression is not static
  3717.           %ADAC-E-ERRCOMPILE, Error(s) compiling procedure body Prog_Adabug3 in file
  3718.                   DBA4:[CONTR07.ADA]ADABUG3.ADA;1
  3719.             Errors:                    7
  3720.             Peak working set:       2400
  3721.             Virtual pages used:     5730
  3722.             Virtual pages free:    38270
  3723.             CPU Time:              00:00:03.72    (451 Lines/Minute)
  3724.             Elapsed Time:          00:00:07.55
  3725.             Compilation Complete
  3726.           %ADAC-E-ENDDIAGS, Ada compilation completed with 6 diagnostics
  3727.  
  3728.           Version 2:
  3729.           package Package_Adabug3 is
  3730.  
  3731.              type Color_Kind is (Red, Yellow, Blue);
  3732.              type Color_Value (Kind : Color_Kind := Red) is
  3733.                 record
  3734.                    case Kind is
  3735.                       when Red    => Red    : String (1 .. 3);
  3736.                       when Yellow => Yellow : String (1 .. 6);
  3737.                       when Blue   => Blue   : String (1 .. 4);
  3738.                    end case;
  3739.                 end record;
  3740.  
  3741.           end Package_Adabug3;
  3742.  
  3743.           with Package_Adabug3;
  3744.           with Text_Io;
  3745.           procedure Prog_Adabug3 is
  3746.              use Package_Adabug3;
  3747.              procedure Local_Subprogram (Color_Val : Color_Value) is
  3748.              begin
  3749.                 case Color_Val.Kind is
  3750.                    when Red    => Text_Io.Put ("Red");
  3751.                    when Yellow => Text_Io.Put ("Yellow");
  3752.                    when Blue   => Text_Io.Put ("Blue");
  3753.                 end case;
  3754.              end Local_Subprogram;
  3755.           begin
  3756.              null;
  3757.  
  3758.  
  3759.                                        12
  3760.  
  3761.  
  3762.  
  3763.  
  3764.  
  3765.  
  3766.  
  3767.  
  3768.  
  3769.  
  3770.           end Prog_Adabug3;
  3771.  
  3772.           $ ada/nolist/warnings=(warn:terminal,weak:terminal,supp:terminal,
  3773.             status:terminal,comp:none) dba4:[contr07.ada]ADABUG3
  3774.           %ADAC-I-CL_ADDED, Package specification PACKAGE_ADABUG3 added to
  3775.                             library
  3776.               Replaces older version compiled 15-Mar-1986 23:20
  3777.           %ADAC-I-CL_ADDED, Procedure body PROG_ADABUG3 added to library
  3778.             Peak working set:       2500
  3779.             Virtual pages used:     5730
  3780.             Virtual pages free:    38270
  3781.             CPU Time:              00:00:04.24    (410 Lines/Minute)
  3782.             Elapsed Time:          00:00:09.42
  3783.             Compilation Complete
  3784.  
  3785.  
  3786.  
  3787.  
  3788.  
  3789.  
  3790.  
  3791.  
  3792.  
  3793.  
  3794.  
  3795.  
  3796.  
  3797.  
  3798.  
  3799.  
  3800.  
  3801.  
  3802.  
  3803.  
  3804.  
  3805.  
  3806.  
  3807.  
  3808.  
  3809.  
  3810.  
  3811.  
  3812.  
  3813.  
  3814.  
  3815.  
  3816.  
  3817.  
  3818.  
  3819.  
  3820.  
  3821.  
  3822.  
  3823.  
  3824.  
  3825.                                        13
  3826.  
  3827.  
  3828.  
  3829.