








      Charlemagne Object Property Lists (Version 1.2,
                         08/20/91)





1.  Introduction

As the capabilities of our above-RPL-level system has grown,
the  need  to  have  a uniform method of "attaching" various
pieces of information to individual  objects  has  grown  as
well. When there are only a few "properties" to consider and
only a few objects have those properties, it makes sense  to
embed  the property information directly in the code dealing
with the specific property by means of a  table  of  objects
with  the  property,  or  some execution equivalent thereof.
Examples of this technique in the current code include pars-
ing  information,  textbook-mode graphics information, COLCT
information, and information on quoted arguments.

Embedding property information in the code  dealing  with  a
property  has  a  number of drawbacks. Not only does it make
maintenance and adjustments to the code much more difficult,
but  it also freezes in certain (often unstated) assumptions
about which object have and do not have a certain  property.
This  can  limit  the possible extensions to the behavior of
the code which can be made without a major re-write, and  it
also  locks  out  extensions of the code by plug-in or user-
created libraries.

In view of this, it makes sense to conventionalize  the  use
of property lists in the system. Candidates for inclusion on
the property lists (which in turn  imposes  restrictions  on
the  structure)  are  described in the first section, below.
The second section describes some of the design issues to be
resolved. The next section proposes an implementation scheme
for property lists. The final section discusses the required
structure of each property list element.

2.  Candidates for Inclusion on Property Lists

2.1.  Parsing Information

Symbolics -
     Prefix/infix/precedence information.
     Which arguments  (if  any)  should  be  protected  from
     evaluation and which of the protected arguments must be
     names.

Macros    -



                     November 16, 1992





                           - 2 -


     Whether a token is the  beginning,  middle,  or  ending
     delimiter of a macro (or none of the above).
     The macro parser  associated  with  a  beginning  macro
     token.

2.2.  Decompilation Information

Symbolics -
     Textbook-mode direct GRaphics  OBject  production  rou-
     tines.
     Textbook-mode GROB modification update routines.

2.3.  HELP-Mode Information

Frames   -
     Whether or not a help-frame exists.
     Help-frames for RPN and AOS execution.

2.4.  Single-Step Information

Control-Structure Words -
     Any objects which do not require the  runstream  as  an
     argument  can  be single-stepped easily. Unfortunately,
     single-stepping control structures is  more  difficult.
     Since  any keyword, built-in or in a plugin, cannot use
     the runstream, the only problematic structures are mac-
     ros.  These will in general need to provide single-step
     information.

2.5.  Inverse, Derivative, and Integral Information

Inverse  -
     Replaces current INV<op> information.

Derivative -
     Replaces current D/D<op> information.

Integral -
     Extends the symbolic integral for each integrable func-
     tion.

2.6.  FORM Information

Menus    -
     Associates zero or more FORM sub-menus with each opera-
     tor.

2.7.  EXPND Information

Routines -
     Associates a manipulation to each top-level operator of
     a  subexpression,  which  corresponds  to the notion of
     expanding the subexpression.




                     November 16, 1992





                           - 3 -


2.8.  COLCT Information

Routines -
     Associates a manipulation to each top-level operator of
     a  subexpression,  which  corresponds  to the notion of
     collecting the subexpression.

2.9.  Range Information

ISOL Corrections -
     The  current  symbolic  solver  can  produce  erroneous
     results  due to its lack of information on the range of
     functions it is inverting. This is  a  different  issue
     from the multi-valuedness of some of the results. As an
     example, 'ASIN(X)=Y' 'X' ISOL produces 'SIN(Y)',  which
     is correct if and only if -PI < RE(Y) <= PI, since this
     is the range of ASIN. This range information  needs  to
     be  included  in the answer for later evaluation, since
     in general the validity can't be determined at the time
     of the execution of ISOL.

Smarter COLCT -
     Range projections like RE can be  eliminated  when  the
     range  of  the  expression  they  are applied to can be
     determined to be included or excluded from their range.

2.10.  Function Bounds

Smarter Plotting -
     Having so-called  epsilon-delta  bounds  for  functions
     would  allow plotting of two variable inequalities in a
     time  comparable  to  plotting  functions,  instead  of
     sixty-four times slower.

Numeric D.E.s -
     Most expressions do not have closed form integrals, and
     so  the  symbolic integrator will necessarily fail with
     them. Our current numeric integration cannot  guarantee
     the  accuracy,  or  even  the  reasonableness,  of  its
     result. Functions bounds would provide a means of  com-
     paring the exact integral with a symbolic approximation
     (Taylor series, say), and provide a means of guarantee-
     ing the accuracy of our numeric integral.

Multi-Solver -
     The current solver is limited by topological considera-
     tions  to  one-dimensional problems because it can only
     compute the values of the equation to be  solved  on  a
     set  of  dimension  zero  (countable number of points).
     Function bounds would allow equations to  be  computed,
     in  effect, on a set of maximal dimension. This removes
     the topological  constraint on solving systems of equa-
     tions.




                     November 16, 1992





                           - 4 -


3.  Structure of property lists

Since the needs of macro words are so different  from  other
ROM  objects and since macros are distinguishable from other
ROM objects by characteristics of their ROM pointer address,
the  structure  of  macro  property lists will be quite dif-
ferent  from  general  ROM  objects.  The   structures   are
described separately.

Built-in named ROM objects, which are normally referenced by
the  absolute  address of the object (i.e. a "non-updateable
object pointer") are preceded by the bytes of  ROMPTR  body.
Floating  ROM  objects  are  normally  referenced  by  a ROM
pointer, which partially obviates the need for the duplicate
of the ROMPTR body immediately preceding the actual floating
ROM object. However, the error-handling mechanism  (LASTWORD
stuff) needs to have the ROM pointer body available from the
secondary  itself.  In  view  of  this,  the  structure   of
floating-ROM property lists and built-in word property lists
will be identical.  The words dealing  with  property  lists
will decide as follows whether or not an object passed to it
has a property list.

If the object is passed as a ROMPTR, then it is  assumed  to
have  a property list if and only if it resolves to a secon-
dary. Otherwise, it is assumed to have a  property  list  if
and only if the object is both a ROM-WORD and a secondary.

This state of affairs means that  floating  ROM  secondaries
which  are meant for "internal execution only" could be mis-
takenly assumed to have property lists if  they  are  unwit-
tingly  "fed"  to  the property list routines. It seems more
desirable to handle this possibilty by careful coding and/or
inclusion  of  "null" property lists than to visit the extra
code requirement of insisting on ROMPTR  bodies  with  every
"named" floating ROM object.

Immediately preceding the ROMPTR body  (in  the  either  the
built-in or floating ROM case) of an object which has a pro-
perty list is a field which gives information about the pro-
perty list itself.  This field is called the prop-list field
and is descibed below for  the  various  types  of  property
lists.

3.1.  Macro property lists

Libraries with ID numbers 700h - 7FEh are reserved  entirely
for  macros,  both  built-in  and plug-in. Since every named
built-in and floating ROM object, by definition, is preceded
by  the body of its associated ROM pointer, and floating ROM
objects are referenced  by  the  ROMPTRs  themselves,  macro
objects can be readily distinguished from other ROM objects.

The prop-list  field  in  this  case  is  a  four-bit  field



                     November 16, 1992





                           - 5 -


representing  the type of the macro. The macro-type subfield
comprises the two least-significant bits. If  the  value  of
the  macro-type  field  is  1, then the macro is a beginning
macro. If the value is 2, the macro is a  middle  macro.  If
the  field is 3, the macro is an end macro. This information
is primarily used for the  smart  decompiler,  which  "tabs"
right,  not  at all, or left, depending on whether the macro
word being decompiled is a beginning, a middle, or an ending
macro.  If  the  value is 0, then the macro in question is a
stand-alone macro word.

The two most significant bits comprise the  macro-prop  sub-
field and will be used to decide which elements of a macro's
property list are present.  The property list of a beginning
macro is a sequence of objects which immediately follows the
macro object itself within the library, that is, it  can  be
reached by skipping the macro object.

The elements of the property list  of  a  macro  can  reside
immediately  following  the  macro in any one of three ways.
Each element of the list  can  be  an  embedded  object,  an
object pointer, or an embedded ROM pointer to an object. The
property list is not a list object, rather it is the "inner"
of  a  list  object  -  a  sequence  of  objects  and object
pointers. Even so, we will continue to  refer  to  it  as  a
list.

The property list of a beginning  or  stand-alone  macro  is
always non-empty. The first object in the list is an RPL ERS
standard production parser. The property lists of other mac-
ros  may be either empty or non-empty.  If the most signifi-
cant bit  of  the  macro-prop  subfield  is  set,  then  the
single-step  code  associated  with  the macro (described in
another section) is  present  and  immediately  follows  the
macro  parser  (if present). If the least significant bit of
the macro-prop subfield is set, then the help-mode  informa-
tion  associated  with this macro (also described in another
section) is present and immediately follows the  single-step
code (if present).

3.2.  General ROM Object Property Lists

Only those named ROM  objects  which  are  secondaries  (so-
called  ROM words) can have recognized property lists. Those
secondaries which are not allowed in symbolic  objects  have
simpler  needs  in  terms of property lists than those which
are allowed. In consequence, these objects  have  a  simpler
property list structure.

In both cases, preceding the ROM pointer body preceding  the
ROM  word  itself  is  a  prop-list  field  similar  to that
described for macros. The state of each of the bits  in  the
prop-list field determines the presence or absence of a par-
ticular element  of  the  property  list.  Once  again,  the



                     November 16, 1992





                           - 6 -


property list is not a list object, but rather a sequence of
objects, object pointers, and ROM pointers immediately  fol-
lowing the location of the object in the library.

ROM words which are not allowed in symbolic objects  have  a
1-nib prop-list field.

ROM words which are allowed in symbolic objects have a 3-nib
prop-list field.

Although our convention in previous machines  was  that  the
criterion  for deciding whether a given secondary was allow-
able  in  an  expression  was   the   structure   ::   CK<n>
CK&DISPATCH2...  ;  to  speed  up the process of determining
property lists it is assumed that this information has  been
pre-compiled into the m.s.b. of the prop-list field, so that
object is allowed in an expression if an only if the  m.s.b.
is 0 (clear).

3.3.  Ordering of Properties

3.3.1.  Non-symbolic ROM Words

The properties associated with a non-symbolic ROM word  are,
in order from m.s.b. to l.s.b. of the prop-list field:

      [not allowable in algebraics]     ALG     - always 1,
                                                - no associated element
      [has HELP entry]                  HELP
      [has algebraic alias]             ALIAS
      [has parse_data ]                 PDATA   - always zero



3.4.

The properties associated with a symbolic ROM word  are,  in
order from m.s.b. to l.s.b. of the prop-list field:

      [not allowable in algebraics]     ALG     - always 0
                                                - no associated element
      [has HELP entry]                  HELP
      [has algebraic alias]             ALIAS - always 0
      [has parse_data]                  PDATA

   N.B. All of the definitions above are "hard coded" into the structure
   of words in this file, and cannot be changed in any easy way. The
   order of the bits below are essentially arbitrary and no particular
   assumptions are made about them.

      [has D/D data]                    DER
      [has INV<op> data]                INV
      [has COLCT data]                  COLCT
      [has EXPND data]                  EXPND



                     November 16, 1992





                           - 7 -



      [has FORM data]                   FORM
      [has INTEGRAL data]               INTG
      [has WHERE data]                  WHERE
      [has very-unsyminner data]        VUNS

3.5.  Templates for Property List Structures

In this section are included templates for use in the  three
classes of objects which have property lists.

3.5.1.  Macro Objects





*************************************************************************
** Local Equates for Macro ROMPARTS
*************************************************************************
sotype  EQU 0           stand-alone macro - has parser
toptype EQU 1           beginning macro - has parser
midtype EQU 2           middle macro - doesn't have parser
bottype EQU 3           ending macro - doesn't have parser

** the equates below, and the ordering of the elements must correspond
** with that given in CALR/proplists.s

hasSST EQU 8            SST data corresponds with the high bit
hasPROMPTM EQU 4

* macro prop-list field
ASSEMBLE
        CON(1)  (macrotype)+0*(hasPROMPTM)+0*(hasSST)
RPL
sNAME <macrolabel> <macroname>
:: <code> ;
RPL
* Macro Parser (if sotype or toptype)
        MacroParserOb/Ptr

* Single-Step Data (if present)
        SSTob/Ptr

* Prompt Mode Data (if present)
        PROMPTMob/Ptr

ASSEMBLE

3.5.2.  Non-Algebraic Keyword







                     November 16, 1992





                           - 8 -


ASSEMBLE
**miscdoc+*********************************************************************
** prop_list defining field for non-macro, non-algebraic objects
**+miscdoc*********************************************************************

        CON(1)  (nonALG)+0*(hasHELP)+0*(hasALIAS)+0*(hasPDATA)
RPL
sNAME <wordlabel> <wordname>
:: <code> ;
RPL
**miscdoc+*********************************************************************
** non-algebraic property list elements
**+miscdoc*********************************************************************

** Help (Prompt-Mode) Data (if present)

        HelpData/Ptr

** Algebraic Alias (if present)

        AlgebraicAlias/Ptr


3.5.3.  Algebraic Keyword




ASSEMBLE
**miscdoc+*********************************************************************
** prop_list defining field for an algebraic function
**+miscdoc*********************************************************************

        CON(1)  0*(hasFORM)+0*(hasINTG)+0*(hasWHERE)+0*(hasVUNS)
        CON(1)  0*(hasDER)+0*(hasINV)+0*(hasCOLCT)+0*(hasEXPND)
        CON(1)  0*(hasHELP)+0*(hasPDATA)
RPL
sNAME <wordlabel> <wordname>
:: <code> ;
RPL
**miscdoc+*********************************************************************
** algebraic function property list elements
**+miscdoc*********************************************************************

** Help (Prompt-Mode) Data (if present)

        HelpData/Ptr

* parse data (if present)

        ParseData/Ptr

* derivative (if present)




                     November 16, 1992





                           - 9 -


        D/DFCN/Ptr

* inverse (if present)

        INVFCN/Ptr

* COLCT data (if present)

        COLCTData/Ptr

* EXPND data (if present)

        EXPNDData/Ptr

* FORM menu (if present)

        FORMMenu/Ptr

* Integral Data (if present)

        INTData/Ptr

* WHERE Building Data (if present)

        WHEREData/Ptr

* very-unsyminner Data (if present)

        VUNSData/Ptr


3.6.  Documentation for Algebraic Keyword Property List Ele-
ments

The structure and assumed conventions for the  various  ele-
ments  of  the property list will be outlined. Unless other-
wise noted, they will be the same for built-in  and  plug-in
keywords.

Several notational conventions are used throughout the docu-
mentation.   The  first  is  the "metaobject" notation where
[...] is used to represent a  sequence  of  objects  on  the
stack  together with a binary integer representing the total
number of objects. Thus, for example,  INNERCOMP  changes  a
composite object into a metaobject:
{ %1 %2 %3 } --> [%1 %2 %3]

A second convention is that  expr  (or  sym)  represents  an
object  allowable  in expressions, that is a real or complex
number, a unit, a global  or  local  name,  a  zero-argument
function, or a symbolic object. On the other hand, '...' (or
symb) represents a symbolic object only.





                     November 16, 1992





                           - 10 -


3.6.1.  Help/Graphics Data

Used by the EquationWriter. Any operator  that  performs  in
any  special  way in EquationWriter -- e.g., division, where
the divide-bar grows as wide as the numerator and  denomina-
tor,  or integral, square root, etc. -- must accomplish this
through the routine indicated here.  It has different struc-
tures  for versions A-E and version G; they are not compati-
ble. The structure includes code to handle "adjustors"  (for
redrawing  parts  of  the  picture), "centerers" (for moving
arguments around), "font adjustors" (for changing font  size
and making other updates, such as to the argument count used
by the parser) and (in version G  only)  "backup  routines".
Documentation  for  these  structures is given in the source
files parser.s (or GsymbPA.s), template.s,  and  gutil.s  in
EQW/NewEQW.

3.6.1.1.  Libraries

Extra constraints apply to writers of libraries which imple-
ment   operators  with  graphics  data  routines.  The  file
extension.s contains  documentation  of  these  constraints,
which are more extensive in version G.  A sample library has
been constructed, producing object file TCK.o  to  implement
external  functions  with  special graphical properties (see
the file TSplist.s). It is version G compatible.

3.6.2.  Parse Data

This item is fully described in the symbolic parser  chapter
(file symbPA.ers).

3.6.3.  D/D<FCN> Derivative Data

This item is executed by  the  derivative  operator  and  is
assumed  to be executable, with entry and exit conditions as
given below.



**Description/Algorithm:
** This word takes the metaobject consisting of the unevaluated arguments
** to the built-in-operator together with the quoted variable of
** differentiation and the operator and attempts to find the D/D<FCN>
** of the entry of the function from its property list. If it exists, it
** evaluates this element which should return (as an expr)
** the derivative of the expression with respect to the variable. If the
** D/D<FCN> element is not present, it creates an identifier corresponding
** to the function and acts as if it were a user-defined function.
**
** The D/D<FCN> element should have the following stack diagram:
**
** [expr...expr] 'id/lam' --> expr
**



                     November 16, 1992





                           - 11 -


** where the resulting expression represents the single-step derivative.
** For example, the entry for x+ would take
** ID X ID Y #TWO 'ID Z' --> ''ID Z' 'ID X' xDER 'ID Z' 'ID Y' xDER x+'

3.6.4.  Inverse (ISOL) Function Element

This element is used by the ISOL  operator  and  is  assumed
executable.  It  is used to find the solution of an equation
in which the left-hand-side has the given  operator  as  its
topmost operator and one of its arguments contains the vari-
able to be isolated. If the operator has no  INVFCN  element
on  its property list, the "unable to isolate" error is gen-
erated.



**Description/Algorithm:
** This word determines whether the given expression contains the
** variable to be isolated. If not, it returns drops all of the arguments
** and returns FALSE. Otherwise, it checks to see if the expression consists
** of a non-operator. If so, it must be the variable and thus returns the
** the second expression and TRUE, indicating that the isolation is complete.
** Otherwise, it checks to see if the operator has an inverse-function
** element on its property list. If not, it drops all its arguments and
** returns FALSE. If so, it EVALs this element, which should attempt to
** apply it inverse (in metaobject form) to the second expression, and then
** re-evaluate this word. If it cannot determine the inverse to apply, it
** should drop all the arguments and return FALSE. It should thus have a
** stack diagram of the form:
**
** [expr] [expr] id --> [expr'] [expr''] | subsolve /
** [expr] [expr] id --> FALSE
**
** In addition, there is assumed to be a temporary environment containing
** stream-objects for creating identifiers of the form ID s<number> and
** ID n<number> which are used for indicating arbitrary signs and integers,
** respectively. The next in the sequence can be created and returned to
** the stack by executing nextsgn and nextint, respectively.


3.6.5.  COLCT Element

The COLCT element of the property list is used in the  final
stages  of  COLCT  for  a "non-destructive" evaluation of an
operator, as described below.  It can also  be  used  as  an
augmentation of the COLCT keyword itself.



**Description/Algorithm:
** The word colleval evaluates the given expression as a user-level program without
** evaluating names or symbolic operators, and hence attempts to 'collect'
** numeric subexpressions into their results. It does this by a special form
** of EVAL for each object in the expression. If the object is a



                     November 16, 1992





                           - 12 -


** non-operator (as determined by nonopcase) it just puts it on the stack.
** If the object is an operator which has an associated COLCT element on
** its property list, it EVALs the associated element instead of the operator.
** Otherwise it EVALs the operator.
**
** The parameval word is like colleval except that it takes an additional object
** handler which checks for special cases other than those described above.
** It should have a stack diagram of the form:
**
** ob1...obN ob --> ob1...obN ob FALSE
** ob1...obN ob --> ob1'...obN' TRUE
**
** Where the first case should hold if it wants the default action; the second
** case should hold it has already taken care of the object and its arguments.
**
** The entry and exit conditions for the COLCT element of a property list
** is the same as that for the associated operator. In particular, stack-depth
** and type-checking must be done as for a user-level keyword.

3.6.6.  EXPND Expand Element

Not yet defined.

3.6.7.  FORM Menu Element

Not yet documented.

3.6.8.  INTG Integral Extension Element

Not yet documented.

3.6.9.  WHERE Element




** Each of the procedures defined here is bound to the WHERE entry of the
** property list of some built-in function. Analogous entries are required
** for any plug-in function whose WHERE behavior is other than the default.
**
** The default behavior of WHERE when applied to a function is to first
** apply WHERE to each of the arguments, and then re-apply the original
** function to the result. In this sense functions with no bound WHERE
** behavior are 'transparent' to where. For example the expression
** 'X+Y|(X=1)' when EVALed first checks the WHERE behavior of + and
** finding none, it produces the expression 'X|(X=1)+(Y|X=1)' which is
** then EVALed yielding '1+Y' (assuming that Y is formal.)
**
** The stack diagrams for all the dispatchees for WHERE look like
**
** ['id/lam'...obN] [arg1...argP]  --> expr'
**
** where ['id/lam'...obN] is the sequence of symbolically quoted
** (i.e. single-object symbolics) identifiers and the expressions



                     November 16, 1992





                           - 13 -


** supposed to be bound to them, and [arg1...argP] is the sequence
** of arguments (in exploded form) of the operator. For example, if
** + had a WHERE dispatchee in the above example, on entry to the
** dispatchee the stack would look like
**
** 'ID X' %1 TWO ID X ID Y TWO
**
** The stack upon completion of the dispatchee's execution should contain
** a single expression representing the result of the WHERE operation.
**
** The primary reason for having a WHERE dispatchee is to control the
** order of substitution. For example in (<der>X(X^2))|(X+1) the derivative
** must be applied before the substituion is made in order for the result
** to be correct. The type-checker nmetasyms has been applied to all the
** arguments of WHERE before dispatch occurs so this is not necessary
** for the dispatchees to repeat.


3.6.10.  VUNS VeryUnSymInner Element




** The main task of veryunsyminner is to reassemble an expression meta-object
** (exploded) form into a symbolic object. In order to do this, it needs
** to determine which subexpressions need to be "quoted", that is, prevented
** from evaluating. Each of these subexpressions will be represented as
** embedded symbolic objects; all others are merely inserted in the top
** level symbolic object in their given order.
**
** Strictly speaking, the determination of quoted arguments should be
** controlled by the parse data (PDATA) associated with each operator:
** an argument represented in PDATA as either a quoted name (QN) or a
** quoted expression (QE) should be quoted, all others should remain
** unquoted. However, veryunsymin assumes that this information has been
** compiled into a procedure attached to the VUNS element of the property
** list of any operator which requires quoted arguments.
**
** If the VUNS element is absent, it is assumed that no quoting is
** necessary. If present, the VUNS element itself is assumed to be a list
** whose first element is a procedure which takes the meta-object of the
** form [expr...expr' arg1...argN] where arg1...argN are the meta-object
** forms of the arguments to the operator, and expr...expr' are
** subexpressions irrelevent to the current operator, and returns
** [expr...expr; arg1'...argN'] where arg1'...argN' are symbolic objects,
** or exploded versions, as necessary.
**
** The procedures may assume that all necessary quoting within the
** arguments has been done so that veryunsymin need not be called
** recursively.
**
** The second element of the VUNS list (always present if the list is
** present) is the QN? element which determines if a particular argument
** needs to be a quoted name (corresponding to the pdQN entry in the



                     November 16, 1992





                           - 14 -


** parse-data.) If the function takes a definite number of arguments,
** the stack diagram for the every QN? element procedure is
**
**      argument_position(#) --> flag
**
** where the argument_position is a bint representing the ordinal number
** of the argument in left-to-right RPN order, ONE representing the left-most
** argument. The procedure should return TRUE if this argument must be a
** quoted name, FALSE otherwise.
**
** For functions taking an indefinite number of arguments, the stack diagram
** is
**
**      argument_position(#) total_number_of_args(#) --> flag
**
** The only difference being that the total number of arguments
** passed to the function is also given.
**
** The third element in the VUNS property list is the "unalias" element and it
** is used by the unalias routine called by splitoffexpr called by EXPR>
** It purpose is to allow functions whose RPN form is different from their
** algebraic form to return their RPN alias and re-arrange arguments as
** desired. The stack diagram for these routines is
**
** [ 'arg1'...'argN'] alg<fcn> --> [ob1..obN'] rpn<fcn>
**
** where 'arg1'...'argN' are arguments suitable to be returned to the user,
** and so must be ob1...obN'. rpn<fcn> is the keyword or romptr thereto which
** should be used as the RPN version of the function.




























                     November 16, 1992


