Google
 

Trailing-Edge - PDP-10 Archives - decus_20tap1_198111 - decus/20-0004/20lisp.doc
There are no other files named 20lisp.doc in the archive.











                               SECTION 20

                PRINTSTRUCTURE, INTERSCOPE, AND HELPSYS

                   1
20.1 Printstructure


In trying  to work with  large programs,  a user can  lose track  of the
hierarchy which defines his program structure; it is often convenient to
have a map to show which  functions are called by each of  the functions
in a system.  If fn is the name of the top level function called in your
system, then typing in printstructure[fn] will cause a tree  printout of
the function-call structure of  fn.  To illustrate this in  more detail,
we use the printstructure program itself as an example.































------------------------------------------------------------------------
1
    A preliminary version of printstructure was written by D. G. Bobrow.
    The current form of printstructure was written by W. Teitelman.




                                  20.1



PRINTSTRUCTURE     PRGETD
                   PROGSTRUC PRGETD
                             PRGSTRC   NOTFN     PRGETD
                                       PROGSTRUC
                                       PRGSTRC1  PRNCONC
                                                 PRGSTRC1
                                                 PRGSTRC
                                       PRNCONC
                                       PRGSTRC
                             CALLS1    MAKELIST
                                       NOTFN
                                       CALLS2    CALLS1
                                                 PRGETD
                   TREEPRINT TREEPRINT1
                             TREEPRINT
                   VARPRINT  VARPRINT1 TREEPRINT1
                             VARPRINT2 ALLCALLS  ALLCALLS1 ALLCALLS1
                             TREEPRINT1

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

PRINTSTRUCTURE     [X,FILE: DONELST,N,TREELST,TREEFNS,LSTEM,X,Y,Z,
FN,TREE;PRDEPTH,LAST-PRINTSTRUCTURE]
   CALLED BY:

PRGETD   [X,FLG; ; ]
   CALLED BY: PRINTSTRUCTURE,PROGSTRUC,NOTFN,CALLS2

PROGSTRUC [FN,DEF; N,Y,Z,CALLSFLG,VARSFLG,VARS1,VARS2,D,X; N,DONELST]
   CALLED BY: PRINSTRUCTURE,PRGSTRC

PRGSTRC  [X,HEAD,FLG; Y,TEM,X; VARSFLG,D,NOFNS,CALLSFLG,N,DONELST,
TREEFNS,NOTRACEFNS,FN,VARS1,QUOTEFNS]
   CALLED BY: PROGSTRUC,PRGSTRC1,PRGSTRC

NOTFN    [FN; DEF; NOFNS,YESFNS,FIRSTLOC,LASTLOC]
   CALLED BY: PRGSTRC,CALLS1

PRGSTRC1 [L,HEAD,FLG; A,B; VARS1,VARS2]
   CALLED BY: PRGSTRC,PRGSTRC1

PRNCONC  [X,Y; ; CALLSFLG]
   CALLED BY: PRGSTRC1,PRGSTRC

CALLS1   [ADR,GENFLG,D; LIT,END,V1,V2,LEFT,OPD,X,X; VARS1,VARS2,
VARSFLG]
   CALLED BY: PROGSTRUC,CALLS2

MAKELIST [N,ADR; L; ]
   CALLED BY: CALLS1





                              Figure 20-1






                                  20.2



The upper portion of this printout is the usual horizontal version  of a
tree.  This tree is straighforwardly derived from the definitions of the
functions:  printstructure  calls  prgetd,  progstruc,   treeprint,  and
varprint.  progstruc in turn calls prgetd, prgstrc and  calls1.  prgstrc
calls notfn, progstruc,  prgstrc1, prnconc, and itself.   prgstrc1 calls
prnconc, itself, and prgstrc.   Note that a function  whose substructure
has already been shown is  not expanded in its second occurrence  in the
tree.

The  lower  portion  of  the  printout  contains,  for   each  function,
information about  the variables it  uses, and a  list of  the functions
that  call  it.   For  example,  printstructure  is  a  function  of two
arguments, x and file.   It binds eleven variables  internally: donelst,
              2
n,  ...  tree,   and  uses  prdepth  and  last-printstructure   as  free
variables.   It is  not called  by  any of  the functions  in  the tree.
prgetd is  a function of  two arguments, x  and flg, binds  no variables
internally, uses  no free  variables, and  is called  by printstructure,
progstruc, notfn and calls2.

printstructure calls many other  low-level functions such as  getd, car,
list, nconc, etc.   in addition to the  four functions appearing  in the
above output.  The reason these do not appear in the output is that they
were  defined  "uninteresting"  by  the user  for  the  purposes  of his
analysis.  Two functions, firstfn and lastfn, and two  variables, yesfns
and nofns are used for  this purpose.  Any function that appears  on the
list nofns is  not of interest, any  function appearing on yesfns  is of
interest.

yesfns=T effectively  puts all  functions on  yesfns.  As  for functions
appearing  on neither  nofns or  yesfns, all  interpreted  functions are
deemed interesting, but only those compiled functions whose code lies in
that portion of  bpspace between the  two limits established  by firstfn
and lastfn.   For example,  the above  analysis was  performed following
firstfn[PRINTSTRUCTURE] and lastfn[ALLCALLS1].

Two other variables, notracefns  and prdepth, also affect the  action of
printstructure.   Functions  that  appear on  the  list  notracefns will
appear in the tree, assuming they are "interesting" functions as defined
above, but their definitions will not be analyzed.  prdepth is  a cutoff
depth for analysis.  It is initially set to 7.

printstructure assumes  that all  functions whose argtypes  are 1  or 3,
i.e. all NLAMBDAs, do not evaluate their arguments.  For example, if the
function prinq were defined  as (NLAMBDA (X) (MAPC X (FUNCTION PRIN1))),
and  the form  (PRINQ (NOW IS THE TIME))  appeared in  a  function being
analyzed, IS, THE, and TIME would not be reported as free variables, and
NOW as an undefined  function.  The user can inform  printstructure (and
other system  packages which require  this information) that  an nlambda
function does evaluate its arguments by putting on its property list the
property INFO value EVAL. For example, the functions and, ersetq, progn,
etc., are all initialized in this fashion.



------------------------------------------------------------------------
2
    Variables are bound internally by either PROGs LAMBDA-expressions.




                                  20.3



If printstructure encounters a form beginning with two  left parentheses
in the course  of analyzing an interpreted  function (other than  a COND
clause or open  lambda expression) it notes  the presence of  a possible
parentheses error by the  abbreviation P.P.E., followed by  the function
in which the form appears, and the form itself, as in the example below.
Note  also  that since  printstructure  detects functions  that  are not
defined, (i.e., atoms appearing as  CAR of a form), printstructure  is a
useful tool for debugging.






















































                                  20.4



_PP FOO

(FOO
  [LAMBDA (X)
    (COND
      ((CAR X) (FOO1 X))
      (T ((CONS X (CAR X])
FOO
_PRINTSTRUCTURE(FOO)

FOO       FOO1

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

FOO       [X; ; ]
   CALLED BY:

FOO1      IS NOT DEFINED.

P.P.E. IN FOO - ((CONS X (CAR X)))



                              Figure 20-2


OTHER OPTIONS

printstructure is a function  of three arguments, x, exprflg,  and file.
printstructure analyzes x, sets the free variable last-printstructure to
the results  of its  analysis, prints  the result  (in the  format shown
earlier) to file (which  is opened if necessary and  closed afterwards),
and returns x as  its value.  Thus if the  user did not want to  see any
                                                     3
output, he could call  printstructure with file=NIL:,  and  then process
the result himself by using last-printstructure.

printstructure always checks for EXPR properties on the property list of
functions that are  not defined.  However, if  exprflg=T, printstructure
will prefer to analyze  EXPR definitions whenever possible, i.e.  if the
function definition  call contains a  compiled definition, and  there is
also an EXPR property, the latter will be analyzed.

x can be NIL, a list, a  function, or an atom that evaluates to  a list.
If x is  NIL, printstructure does not  perform any analysis,  but simply
prints  the  result  of   the  last  analysis,  i.e.,  that   stored  on
last-printstructure.  Thus the user can effectively redirect  the output
that is going to the terminal  to a disc file by aborting  the printout,
and then performing printstructure[NIL;file].



------------------------------------------------------------------------

3
    NIL: is  a TENEX output  device that acts  like a  'bottomless pit'.
    Note that file=NIL (not NIL:) means print the tree to primary output
    file.




                                  20.5



If x  is a list,  printstructure analyzes the  first function on  x, and
then analyzes the second function, unless it was already  analyzed, then
the third, etc.,  producing however many  trees required.  Thus,  if the
user wishes to analyze a collection of functions, e.g., breakfns, he can
simply perform (PRINTSTRUCTURE BREAKFNS).

If x is not a list, but is the name of a function,  printstructure[x] is
the same as printstructure[(x)].  Finally,  if the value of x is  a list
of functions, printstructure will process that list as described above.

Note  that in  the  case that  x  is a  list,  or evaluates  to  a list,
subsequent  functions  are not  separately  analyzed if  they  have been
encountered in the analysis of a function appearing earlier on the list.
Thus, the ordering of x can be important.  For example, if both  FOO and
FIE call FUM, printstructure[(FOO FIE FUM)], will produce a tree for FOO
containing embedded in it the tree for FUM.  FUM will not be expanded in
the tree for FIE,  nor will it have a  tree of its own.  (Of  course, if
FOO  also  calls  FIE,  then  FIE will  not  have  a  tree  either.) The
convention of listing  FUM can be used  to force printstructure  to give
FUM  a  tree  of  its  own.   Thus  printstructure[(FOO FIE (FUM))] will
produce three trees,  and neither of  the calls to  FUM from FOO  or FIE
will be expanded in their respective trees.  Of course, in this example,
the  same  effect  could   have  been  achieved  by   reordering,  i.e.,
printstructure[(FUM FOO FIE)].   However,  if  FOO,  FIE,  and  FUM, all
called each other, and yet the user wanted to see three  separate trees,
no  ordering  would  suffice.   Instead,  the  user  would  have  to  do
printstructure[((FOO) (FIE) (FUM))].

The result of the analysis of printstructure is in two parts: donelst, a
list  summarizing the  argument/variable information  for  each function
appearing  in  the   tree(s),  and  treelst,   a  list  of   the  trees.
last-printstructure is set to cons[donelst;treelst].

donelst is a list consisting, in alternation, of the functions appearing
in any tree, and a variable list for that function.  car of the variable
list is a list of variables bound in the function, and cdr is a  list of
those variables used freely in  the function.  Thus the form  of donelst
for the earlier example would be:

(PRINTSTRUCTURE ((X FILE DONELST N TREELST TREEFNS L TEM X Y Z
FN TREE) PRDEPTH LAST-PRINTSTRUCTURE) PRGETD ((X FLG))
PROGSTRUC (( FN DEF N Y Z CALLSFLG VARSFLG VARS1 VARS2 D X)
N DONELST) ... ALLCALLS1 ((FN TR A B)))

Possible parentheses  errors are  indicated on  donelst by  a non-atomic
form appearing where  a function would normally  occur, i.e., in  an odd
position.  The non-atomic form is  followed by the name of  the function
in which the P.P.E. occurred.


PRINTSTRUCTURE FUNCTIONS

printstructure[x;exprflg;file]
                             analyzes     x,     saves     result     on
                             last-printstructure,   outputs   trees  and
                             variable information to file, and returns x
                             as its value.





                                  20.6



                             If exprflg=T, printstructure will prefer to
                             analyze expr's.  See page 20.5.


treeprint[x;n]               prints  a  tree in  the  horizontal fashion
                             shown   in  the   examples   above.   i.e.,
                             printstructure performs
                             (MAPC TREELST (FUNCTION TREEPRINT)).


varprint[donelst;treelst]    prints    the   "lower    half"    of   the
                             printstructure output.


allcalls[fn;treelst]         uses  treelst  to  produce  a  list  of the
                             functions that call fn.


firstfn[fn]                  If fn=T, lower boundary is set to  0, i.e.,
                             all subrs  and all compiled  functions will
                             pass this test.  If fn=NIL,  lower boundary
                             set at  end of  bpspace, i.e.,  no compiled
                             functions will  pass this  test.  Otherwise
                             fn is the  name of a compiled  function and
                             the  boundary  is  set  at  fn,  i.e.,  all
                             compiled functions defined earlier  than fn
                             are rejected.


lastfn[fn]                   if  fn=NIL, upper  boundary set  at  end of
                             bpspace, i.e., all compiled  functions will
                             pass this test.  Otherwise boundary  set at
                             fn,  i.e., all  compiled  functions defined
                             later than fn are rejected.


Thus  to   accept  all  compiled   functions,  perform   firstfn[T]  and
lastfn[NIL]: to reject all compiled functions, perform firstfn[].


calls[fn;exprflg;varsflg]    is a fast 'one-level' printstructure, i.e.,
                             it indicates  what functions fn  calls, but
                             does  not  go further  and  analyze  any of
                             them.   calls does  not print  a  tree, but
                             reports  its findings  by returning  as its
                             value a list  of three elements: a  list of
                             all  functions  called  by  fn,  a  list of
                             variables  bound  in  fn,  and  a  list  of
                             variables used freely in fn, e.g.,

                             calls[progstruc]                          =
                             ((PRGETD EXPRP PRGSTRC CCODEP
                             CALLS1 ATTACH) (FN DEF N Y Z CALLSFLG
                             VARSFLG VARS1 VARS2 D X) (N DONELST))

                             fn can be a function name, a definition, or
                             a  form.   Calls  first   does  firstfn(T),
                             lastfn()  so  that all  subrs  and compiled




                                  20.7



                             functions  appear, except  those  on nofns.
                             If  varsflg is  T, calls  ignores functions
                             and  only  looks  at  the   variables  (and
                             therefore runs much faster).


vars[fn;exprflg]             cdr[calls[fn;exprflg;T]]


freevars[fn;exprflg]         cadr[vars[fn;exprflg]]



               4
20.2 Interscope


While  printstructure  is  a  convenient tool  for  giving  the  user an
overview of  the structure of  his programs, it  is not well  suited for
determining the answer to  particular questions the user may  have about
his programs.  For example, if FOO uses X freely, and the user  wants to
know where X is bound 'above' FOO, he has to visually trace back  up the
tree that is output by printstructure, and, at each point, look  down at
the lower  portion of  the printout and  find whether  the corresponding
function binds  X.  For  large systems,  such a  procedure can  be quite
tedious.   Furthermore,  printstructure does  not  even  compute certain
certain important types of information. For example, printstructure does
not distinguish between functions  that use a variable freely  and those
that set it (or smash it).

Interscope is an extension  of printstructure designed to  resolve these
shortcomings.   Like   printstructure,   interscope   analyses  programs
(functions),  although  it extracts  considerably  more  information and
relationships than does printstructure.  However, instead  of presenting
the information it obtains in a predetermined format,  interscope allows
the user to ask it questions about the programs it has analysed, i.e. to
interrogate its data base.  These questions can be input in English, and
contain   conjunctions,  disjunctions,   and  negations   of   the  many
relationships  between  functions and  variables  that  interscope knows
about.     The    questions    can    be    closed    questions,    e.g.
"DOES FOO CALL FIE?",  or  open  questions,  "WHAT FUNCTIONS CALL FIE?".
The  answers to  some questions  are obtainable  directly from  the data
base,   e.g.   "WHAT VARIABLES DOES FOO SET?"   Other   questions  cause
interscope      to       search      its      data       base,      e.g.
"WHAT FUNCTIONS BIND VARIABLES THAT FOO SETS?".  Figure 20-3  contains a
sample session with interscope.








------------------------------------------------------------------------
4
    Interscope   was  originally   written   by  P.   C.   Jackson,  and
    substantially revised and improved by L. M. Masinter.




                                  20.8



_INTERSCOPE]
 Hello, shall I analyze a system?                                    [1]
&_WTFIXFNS AND CLISPFNS.
 This may take a few minutes.

GC: 8
1233, 10431 FREE WORDS
 Shall I analyze another system?
&_NO                                                                 [2]
 Ok, what would you like to know?
&WHO CALLS RETDWIM?
(WTFIX FIX89TYPEIN FIXAPPLY FIXATOM FIXCONTINUE CLISPATOM FIXT)
&HOW IS CLISPATOM CALLED?
 I didn't understand that.                                           [3]
&WHAT FUNCTIONS CALL CLISPATOM?                                      [4]
(WTFIX FIXAPPLY FIXATOM)
&WHAT FREE VARIABLES DOES CLISPATOM USE?
(ONLYSPELLFLG CLISPCHANGES CLISPFLG TYPE-IN? CLISPSTATS INFIXSTATS LST
FAULTXX CHCONLST FAULTX DWIMIFYFLG 89CHANGE FAULTPOS)
&WHO BINDS TAIL?
(WTFIX RETDWIM1 RETDWIM2 RETDWIM3 CLISPFUNCTION? CLISPATOM0 CLISPATOM1
CLISPATOM1A CLISPATOM2A DWIMIFY1A DWIMIFY2 DWIMIFY2A CLISPRESPELL)
&WHO BINDS TAIL AND CALLS CLISPATOM SOMEHOW?
(WTFIX DWIMIFY2)
&WHAT VARS DOES HELPFIX CHANGE?
(FORM LASTPOS NOCHANGEFLG HELPFIXTAIL FN TEM BRKEXP)
&WHAT FUNCTIONS CHANGE THE VARIABLE TENTATIVE?
(CLISPATOM1 CLISPATOM2 CLISPATOM2C CLISPATOM2A CLISPATOM1A)
&WHO CHANGES TAIL?
(FIXATOM HELPFIX1 CLISPATOM1 CLISPATOM2 DWIMIFY2)
&WHAT FNS USE TEM AS AN INTERANL VAR AND
...ARE CALLED BY CLISPATOM INDIRECTLY?
INTERANL=INTERNAL ?  Yes
(RETDWIM RETDWIM1 FIX89TYPEIN)
&HOW DOES CLIAPTOM CALL LISTP?
CLIAPTOM=CLISPATOM ?  Yes
((CLISPATOM LISTP) (CLISPATOM *** RETDWIM *** LISTP) (CLISPATOM      [5]
FIX89 FIX89A LISTP))
&SHOW ME THE PATHS FROM CLISPATOM TO LISTP.
CLISPATOM LISTP
          RETDWIM LISTP                                              [6]
                  RETDWIM1 LISTP
          FIX89TYPEIN RETDWIM ...
          FIX89 FIX89A LISTP
&DOES GETVARS SMASH ANY VARIABLES?
(L)
&SHOW ME HOW GETVARS SMASHES L.
 (NCONC L (AND (LISTP X) (MAPCAR & &)))
&GOODBYE.
 Goodbye.




                              Figure 20-3







                                  20.9



In order  to answer  questions about  programs, interscope  must analyze
them and build its data-base.  When interscope is first called,  it will
ask the user what functions  he wants analyzed. The user can  respond to
this question by giving interscope either: 1) the name of the  top level
function  called  in his  system,  or 2)  the  name of  a  variable that
evaluates to a list of top level functions, or 3) the list  itself.  All
of the functions below each top level function will be  analyzed, except
those  which are  declared to  be "uninteresting,"  as  described below.
                                                             5
Note that after interscope goes into question-answering mode,   the user
can  instruct  interscope  to analyze  additional  functions,  either in
English input, e.g. "ANALYZE FOOFNS." or by calling the  function lookat
directly (page 20.13).

The structure of interscope may be divided into three  major subsystems:
a top-level monitor function, an English preprocessor, and the functions
which  build  and  search  the  data  base.  The  monitor   function  is
implemented via userexec (see Section  22), so that the features  of the
                                                                  6
programmer's  assistant  are  available  from  within  interscope.   For
example, the user can REDO or FIX interscope questions,  interrogate the
                                                                     7
history list for his session, or run programs from within interscope.




------------------------------------------------------------------------
5
    When interscope is first called, and it has not  previously analyzed
    any functions, it is in analysis mode, as indicated by  its greeting
    and prompt  character (&_ instead  of &) (see  [1] in  Figure 20-3).
    Interscope goes into  question-answering mode when the  user answers
    NO to  the question "Shall  I analyse a  (another) system?"  ([2] in
    Figure  20-3).   The  only  difference  between  analysis  mode  and
    question-answering mode is that in analysis mode,  interscope treats
    forms as indicating a list  of functions to be analysed,  whereas in
    question-answering  mode,  interscope simply  passes  forms  back to
    lispx for evaluation.

6
    interscope assumes that any  input line terminated by  a punctuation
    mark is intended for it to process. interscope will also  attempt to
    process other  input lines,  i.e. those  not ending  in punctuation.
    However, if it  is not able to  make sense of the  input, interscope
    will assume that it was intended to be handled by lispx, and pass it
    back   for   evaluation.    For   example,   if   the   user   types
    "HAS THOU SLAIN THE JABBERWOCK?", interscope will respond  "I didn't
    understand that", but  if the user omits  the '?', the line  will be
    given  to lispx  for evaluation  and (probably)  cause  a U.D.F. HAS
    error.

7
    Since the data base that interscope constructs is global  (stored on
    property lists), the user  can also exit from interscope,  either by
    typing OK or GOODBYE, or via control-D, and then  reenter interscope
    at some later point and continue asking questions, without having to
    reanalyze his functions.




                                 20.10



                                                      8
The English preprocessor translates English questions,   statements, and
commands into INTERLISP forms appropriate for searching and building the
interscope data base.  Although this preprocessor is fairly flexible and
robust (e.g. includes spelling correction), it translates only a limited
subset of English sentences, and replies  "I didn't understand that." to
                                                   9
anything outside this subset  ([3] in Figure 20-3).  When  this happens,
usually  a  simple rephrasing  of  the question  will  suffice  to allow
interscope to handle it ([4] in Figure 20-3).

The interscope data-base  can be accessed directly  by the user  via the
functions described below.  It should be noted that  interscope actually
creates  two  data bases,  the  first containing  information  about the
elementary relations between the  functions and variables in  the user's
system, and  the second containing  information derived from  the first,
i.e. the paths by which one function calls another. The first  data base
is created when interscope analyzes a system (via the  function lookat).
The second data base is developed incrementally (by the function paths),
depending on the questions asked by the user. Both data bases are stored
on the property lists of the functions and variables which are analyzed.

Interscope "understands" a wide variety of the elementary relations that
exist between functions and  variables, e.g. which functions  bind, use,
change, test,  or smash a  given variable, which  functions may  cause a
                                                                10
given  function to  be called,  either directly  or  indirectly,   which
variables are used as global or local free variables, either by  a given
function or by a group of functions, etc.

Information about the function-call paths from one program to another is
"generalized" when it is stored; e.g.  at [5] in Figure 20-3, one of the
paths by which CLISPATOM calls LISTP is given as (CLISPATOM  *** RETDWIM
*** LISTP), which means that there is more than one path  from CLISPATOM
to RETDWIM, and more than one path from RETDWIM to LISTP.

The conventions  used by interscope  for recognizing functions  that are
"uninteresting"  are  the same  as  those used  by  printstructure (page
20.3), i.e. yesfns, nofns firstfn,  and lastfn all have the  same effect
as for printstructure.





------------------------------------------------------------------------
8
    The translation  of the most  recent input is  always stored  in the
    function definition cell of the atom MEANING.

9
    Where possible, interscope will try to inform the user what  part of
    the sentence it did not understand.

10
    e.g.  if  FOO calls  FIE,  and FIE  calls  FUM, then  FOO  calls FUM
    indirectly.    'SOMEHOW'   means   directly   or   indirectly,  e.g.
    "WHAT FUNCTIONS CALL FOO SOMEHOW?"




                                 20.11



INTERSCOPE FUNCTIONS

paths[x;y;type;must;avoid;only]
                             Value is a list of paths from x to y, where
                             each path is an ordered list  of functions.
                             *** is used to indicate multiple paths. For
                             example, if  FOO calls  FIE, and  FIE calls
                             FUM directly as well as calling  FIE1 which
                             calls  FUM,  then   paths[FOO;FUM]  returns
                             ((FOO FIE *** FUM)).

                             type, must,  avoid, and only  are optional.
                             type can be  either CALLS or  CALLEDBY (NIL
                             is equivalent to CALLS), e.g.  in the above
                             example,    paths[FUM;FOO;CALLEDBY]   would
                             return   the   same   set   of   paths   as
                             paths[FOO;FUM], except  each path  would be
                             in the reverse order.

                             must, avoid,  and only  are used  to select
                             out certain  types of  paths.  Each  can be
                             specified by an  atom which evaluates  to a
                             list   of  functions,   or  a   form  which
                             evaluates to  such a  list.  If  (the value
                             of) must is non-NIL, each path  is required
                             to go through  at least one of  the members
                             of must.  If avoid is non-NIL, no  path can
                             go through any member of avoid. If  only is
                             non-NIL,  no   path  can  go   through  any
                             function  which is  not a  member  of only,
                             i.e.   each  path   can  only   go  through
                                               11
                             functions on only.


                             
treepaths[x;y;type;must;avoid;only]
                             Like paths, except  prints paths as  a tree
                             structure, as shown at [6] in  Figure 20-3.
                             type, must, avoid,  and only have  the same
                                                   12
                             meaning as with paths.





------------------------------------------------------------------------
11
    paths    is   called    for    English   inputs    of    the   form:
    "WHAT ARE THE PATHS FROM x TO y?".  Such  questions can  be modified
    with subordinate clauses to indicate values for must,  avoid, and/or
    only,  e.g.  "WHAT  ARE THE  PATHS  FROM FOO  TO FIE  WHICH  ONLY GO
    THROUGH FOOFNS AND AVOID FIEFNS?"

12
    treepaths is called  for English inputs of  the form "SHOW ME  HOW x
    CALLS y", "DISPLAY THE PATHS FROM x TO y", etc.




                                 20.12



lookat[x]                    Builds the initial data base describing the
                             system x, where x  is either the name  of a
                             function,  the  name  of  a  variable which
                             evaluates to  a list  of functions,  or the
                             list of functions itself.


clumpget[object;relation;universe]     Value  is   a  list   of  objects
                             (functions  or  variables)  which  have the
                             indicated relation with respect  to object,
                             e.g.  clumpget[FOO;CALLERS] returns  a list
                             of     functions     that     call     FOO,
                             clumpget[X;SMASHERS]  a  list  of functions
                             that smash the variable X, etc.  A complete
                             list of the possible values for relation is
                                         13
                             given below.

                             object  can  be  a list  of  objects  (or a
                             variable  which  evaluates  to  a  list  of
                             objects), in which case the  value returned
                             by  clumpget  is the  list  of  all objects
                             which have the indicated relation to any of
                             the members of object.

                             Similarly,  universe  can  be  a   list  of
                             objects (or a variable which evaluates to a
                             list of objects),  in which case  the value
                             returned  by clumpget  is the  list  of all
                             objects   in   universe   which   have  the
                             indicated relation to object (or any of the
                             members       of        object),       e.g.
                             clumpget[X;SMASHERS;FOOFNS].

                             Finally,, universe can be a relation, which
                             is       equivalent       to      supplying
                             clumpget[object;universe]   in   place   of
                             object, i.e. the value returned is the list
                             of  all  objects which  have  the indicated
                             relation to any of the members of  the {set
                             of all objects which bear  the relationship
                             universe   to   object}.     For   example,
                             clumpget[FOO;CALLERS;CALLEDFNS]  is  a list
                             of  all  functions  that  call  any  of the
                             functions   (CALLERS)  that   are  directly
                             called       by       FOO      (CALLEDFNS).
                             clumpget[FOO;FREEUSERS;LOCALVARS] is a list
                             of  functions that  use freely  any  of the
                             variables that are bound locally by FOO.


------------------------------------------------------------------------
13
    If  clumpget  is  given  a  value  for  relation  that  it  does not
    recognize, it will attempt  spelling correction, and if  that fails,
    generate an error.  If given a value for object that it has not seen
    before, it will  type "I don't know  anything about object,  shall I
    analyse a system?" and go into analysis mode.




                                 20.13



Currently, the following relations are implemented:


CALLERS                 list of functions that directly call object.


CALLEDFNS               list of functions directly called by object.


CALLCAUSERS             list  of  functions  that  call  object, perhaps
                        indirectly.    In   English:   "WHO   CALLS  FOO
                        SOMEHOW?".


CALLSCAUSED             list  of  functions  called  by  object, perhaps
                        indirectly.   In  English:  "WHO  DOES  FOO CALL
                        SOMEHOW?"


ABOVE                   union of object with CALLCAUSERS.


BELOW                   union of object with CALLSCAUSED.


ARGS                     arguments of object.


ARGBINDERS              list  of  functions  that  have  object   as  an
                        argument.


LOCALVARS               list  of  variables that  are  locally  bound in
                        object, e.g. PROG vars.


LOCALBINDERS            list of  functions that bind  object as  a local
                        variable.


FREEVARS                list of variables used freely by object.


FREEUSERS               list of functions that use object freely.


LOCALFREEVARS           list  of  variables  that  are  used  freely  in
                        object, but are bound in object before  they are
                        used,   e.g.   clumpget[FOO;LOCALFREEVARS;BELOW]
                        gives  a  list of  those  variables  used freely
                        below FOO,  but are bound  above the  place that











                                 20.14


                                      14
                        they are used.   In English: "WHAT ARE THE LOCAL
                        FREE VARS (VARIABLES) BELOW FOO?"


GLOBALFREEVARS          list of variables used freely in  object without
                        previously being bound in object.


ENTRYFNS                list  of each  function in  object which  is not
                        called  by  any function  in  object  other than
                        itself, e.g.  clumpget[FOOFNS;ENTRYFNS].


SELFRECURSIVE           list   of   functions  in   object   which  call
                        themselves directly.


CAUSESELFCALL           list  of functions  in object  which  could call
                        themselves, perhaps indirectly.


CAUSERECURSION          list  of functions  in object  which  cause some
                        function to call itself, perhaps indirectly.


CHANGEVARS              list of  variables that  are changed  by object,
                        where 'changed' means any flavor  of assignment,
                        i.e.  via SETQ,  SETQQ, RPAQ,  SETN, or  even an
                        expression          of          the         form
                        (RPLACA (QUOTE atom) value)     (or     FRPLACA,
                                               15
                        /RPLACA, SAVESET, etc.)


CHANGERS                list of functions that change object.


Note:  'set'  in  English  input means  any  flavor  of  assignment, and
translates the same as 'change'.


SMASHVARS               list  of variables  whose value  are  smashed by
                        object, where 'smash' means the variable appears



------------------------------------------------------------------------
14
    Note that if object is the  name of a function and universe  is NIL,
    LOCALFREEVARS will  always be  NIL, and  GLOBALFREEVARS the  same as
    FREEVARS. It  is only  in connection  with collections  of functions
    that LOCALFREEVARS and GLOBALFREEVARS become interesting.

15
    clumpget  will  accept  as  relations  SETQVARS,  SETQERS,  SETVARS,
    SETTERS,  SETQQERS,  SETQQVARS,  etc., in  case  the  user  wants to
    distinguish between the various flavors of assignments.  In English,
    "WHAT ARE THE SETQERS OF X?", etc.




                                 20.15



                        as  the first  argument to  one of  the  list of
                                                 16
                        functions on smasherslst.


SMASHERS                list of functions that smash object.


TESTVARS                list  of variables  that are  tested  by object,
                        where 'tested'  means they  appear as  the first
                        argument  to one  of  the list  of  functions on
                        testerslst, initially (ATOM LISTP NUMBERP NLISTP
                        STRINGP EQ  EQP EQUAL NULL),  or anywhere  in an
                        AND or OR, or as the predicate in a COND clause,
                        or as the first argument to SELECTQ, etc.


TESTERS                 list of functions that test object.


USEVARS                 list of variables that are used in object, where
                        'used' means actually appear in the body  of the
                        function, i.e.  if a  variable is  simply bound,
                        but not actually  used anywhere, it will  not be
                        included  in the  value of  USEVARS.  CHANGEVARS
                        and TESTVARS are subsets of USEVARS.


USERS                   list of functions that use object.  






















------------------------------------------------------------------------
16
    Initially  (RPLACA  RPLACD  FRPLACA  FRPLACD  /RPLACA  /RPLACD NCONC
    NCONC1  /NCONC  /NCONC1  ATTACH  /ATTACH  RPLNODE  /RPLNODE RPLNODE2
    /RPLNODE2).  As with assignments, clumpget will accept  as relations
    RPLACAERS, RPLACAVARS, RPLACDERS, RPLACDVARS, etc., in case the user
    wants to distinguish the different types of smashing.




                                 20.16



            17
20.3 Helpsys   


Helpsys provides  yet another  form of on-line  assistance to  the user,
namely  in the  area  of documentation  of INTERLISP.  Helpsys  uses the
INTERLISP Reference Manual as a data base, and answers  simple questions
about INTERLISP by presenting the appropriate passages from  the manual.
Inquiries are made in the form of simple sentences, void of punctuation,
terminated  with  a  carriage-return.   The  following   sample  session
illustrates the use of Helpsys. User inputs are underlined.

_HELPSYS]
Type ??? <CR> for assistance
!TELL ME ABOUT WHILE
... WHILE as a CLISP iterative statement operator from section 23

WHILE pred
     provides a way of terminating the i.s.  WHILE  pred evaluates
pred before each iteration, and if  the value is NIL, exits.

!TELL ME ABOUT EVAL
Do you want to see the function ?  No
Do you want to see the break command ?  Yes
EVAL
     Same as GO or OK except that the break is  maintained after the
evaluation.  The  user can then interrogate the value of  the break
which is bound on the variable  !value, and continue with the break.
More? Yes
  Typing GO or OK following EVAL will  not cause reevaluation but
another EVAL  will.  EVAL is a useful command when the  user is not
sure whether or not the break  will produce the correct value and
wishes  to be able to do something about it if it  is wrong.

!TELL ME ABOUT UB
... UB as a break command from section 15

UB
     unbreaks  brkfn, e.g.
(FOO BROKEN)
:UB
FOO
:
     and FOO is now unbroken

!REDO EVAL
Do you want to see the function ?  ...yes
eval[x]
     eval evaluates the expression  x  and returns this value i.e.
eval  provides a way of calling the  interpreter.
Footnote [7] now? Yes
----------
{*7*}  eval is a  subr so that the 'name'  x does not actually appear


------------------------------------------------------------------------
17
    Helpsys was written by R. L. Walker II.




                                 20.17



on  the stack.
----------
Note that  eval is  itself a  lambda type function, so its  argument
                                                                      18
is the first evaluated, e.g., {user aborts output by typing control-E}

!WHAT ARE THE ARGS FOR BREAK1
 Valid arguments for BREAK1 are: [BRKEXP;BRKWHEN;BRKFN;BRKCOMS;BRKTYPE]

!TELL ME AOUT THE THIRD ARG FOR BREAK1
=ABOUT
... BREAK1 as a function from section 15

break1[brkexp;brkwhen;brkfn;brkcoms;brktype]
     is an  nlambda.    brktype is NIL for user breaks,  INTERRUPT for
 control-H breaks, and  ERRORX for error breaks.

!TELL ME ABOUT ERROR IN ARRAYSIZE
... ARRAYSIZE as a function from section 10

  Generates an error, ARG NOT ARRAY, if  a  is not an array.

!TELL ME ABOUT THE LAST ARUGNEMT OF CHANGEPROP
=ARGUMENT
... CHANGEPROP as a function from section 7

changeprop[x;prop1;prop2]
     Changes name of property  prop1 to  prop2 on property list of  x,
 (but does  not affect the value of the property).

!USE 2ND FOR LAST
... CHANGEPROP as a function from section 7

changeprop[x;prop1;prop2]
     Changes name of property  prop1 to  prop2 on property list of  x,
 (but does  not affect the value of the property).   Value is  x,
(but does not affect the value of the property).

!WHAT IS THE VALUE OF MAPC
... MAPC as a function from section 11

  The value of  mapc is NIL.
!OK
NIL








------------------------------------------------------------------------
18
    The user could also interrupt the output by striking the  'del' key,
    which  simply causes  helpsys  to skip  over what  it  was currently
    typing, e.g. footnote, paragraph,  etc., and continue with  the same
    subject further on.




                                 20.18