*start*
02291 00024 USt
Date: 6 July 1981 12:59 pm PDT (Monday)
Subject: Current Level 0/1 Interdoc status
To: Guttag, Horning, Lampson
cc: Mitchell

The low-level syntax for InterDocs is the following (basically it represents the dominant tree structure  by the nonterminal "node", each of which can have some set of labels, some structure, which may be subtrees as well as actual data, and a set of transformations on an environment, about which more below):

node ::= "(" [label* ":"] [envTrans] structure ")"

label ::= "#" atom

envTranses ::= "{" envTrans* "}"

envTrans ::= [ "'" ] (name | definition)	-- a name "invokes" a definition

name ::= atom ( "." atom)*

definition ::= name rhs

rhs ::= bindingOp ( envTranses | content ) | "." envTranses

structure ::= content*

content ::= literal | node | name	-- need "~" for Booleans?

literal ::= Boolean | integer | hexint | real | string | label

Boolean ::= F | T

bindingOp ::= "=" | [ "/" ] ( "←" | "+" | "" | "*" | "/" )

How properties propagate and are inherited:

We imagine an InterDoc script being processed in the following manner (or in any algorithmically equivalent way, of course):

(1) Parse the script to form a parse tree in which the dominant tree structure is derived directly from the node/structure part of the above grammar and associate with each node its envTranses.

(2) As soon as the envTranses for a node have been parsed, its environment can be determined by starting with its parent's environment and modifying it by the new node's envTranses.  Any persistent envTranses are made in both the parent's and the node's environments (Is this sufficient? Can persistent transes change higher nodes' environments?).

(3) Once a node's environment has been determined, its structure can be parsed and evaluated (in the obvious recursive manner).  The structure may use values from the node's environment (e.g., chapter or section numbers).  This is why one needs to be able to assign trees to variables in the environment.  The only way a value from a node's structure can affect its environment is if a subnode makes a persistent change to a value in the parent node's environment.  There is no direct way in which the content of a node can affect its environment since the environment is determined first.
*start*
01134 00024 USt
Date: 7 July 1981 1:36 pm PDT (Tuesday)
From: Mitchell.PA
Subject: Basic InterDoc Semantics
To: Mitchell

Here are the current semantics for interdocs:

The kinds of values that can be represented in an InterDoc script are
	primitiveValue: Booleans, integers, reals, strings, atoms, labels, and
			    sequences of primitiveValues;	
	environment: id > value
	function: environment > value
	node: (labels, function, value)

The expression forms of interest come from the following set:
	literal
	id		(should probably also have ~id)
	id.exp
	n op v	( op in  {+,,*,/,and,or,...}, n a name, v a value)
	bind(n,v)
	bindq(n,v)
	compose(e1,e2)
	invoke(n)

The semantics of these expression forms is defined by the following (E=Eval, 
denotes an environment; [id←v]() means " with id bound to v"):
	E(literal,) = primitiveValue(literal)
	E(id,) = (id)
	E(id.n,) = E(n,(id))
	E(bindq(id,v),) = [id←v]()
	E(bindq(id.n,v),) = [id←E(bindq(n,v),(id))]()
	E(bind(n,v),) = E(bindq(n,E(v,)),)
	E(n op v,) = E(bindq(n, op(E(n,),E(v,))),)
	E(compose(e1,e2),) = E(e2,E(e1,))
	E(invoke(n),) = E(n,)()

*start*
03587 00024 USt
Date: 13 July 1981 6:39 pm PDT (Monday)
From: Horning.pa
Subject: GML paper
To: Interdoc

At Chuck Geschke's suggestion, I took a look at the paper on GML in the
proceedings of the ACM SIGPLAN SIGOA Symposium on Text Manipulation. 
Apparently some IBM people have been pushing ANSI to adopt GML as a
standard for interchange of editable documents.

I agree with Chuck that there is nothing astounding in this paper; I like our
own preliminary design for Interdoc a lot better.  (It should be much easier to
translate an arbitrary GML document to Interdoc than the other way around.) 
However, it is interesting to see Goldfarb confirming some of the basic Interdoc
premisses, as indicated in the following excerpts:

Procedural markup ... has a number of disadvantages.  For one thing, information
about the document's attributes is usually lost. ... Procedural markup is also
inflexible.  If the user decides to change the style of his document (perhaps
because he is using a different output device), he will need to repeat the
markup process to reflect the changes. ... Moreover, markup with control words
can be time-consuming, error-prone, and require a high degree of operator
training, particularly when complex typographic results are desired. ...

If, as postulated, descriptive markup like this suffices for all processing, it must
follow that the processing of a document is a function of its attributes. ... In
terms of the document processing model, the advantage of descriptive markup is
that is permits the user to define attributes--and therefore element types--not
known to the formatter, and to specify the processing for them. ...

Generic coding is a considerable improvement over procedural markup in
practical use, but it is conceptually unsound.  This is because documents are
complex objects, and they have other attributes that a markup language must be
capable of describing. ... "Content" is, of course, a primary attribute, and is the
one that the secondary attributes of an element describe.  The content consists of
an arrangement of other elements, each of which in turn may have other
elements in its content, and so on until further division is impossible.  One way
in which GML differs from generic coding schemes is in the conceptual and
notational tools it provides for dealing with this hierarchical structure. ...

Formatting specifications [for Cliff Jones's book "Software Development: A
Rigorous Approach"] were provided by the publisher, and no concessions were
needed to accomodate the use of GML, despite the markup having existed before
the specifications.  (On the contrary, the publisher took advantage of GML by
changing some of the specifications after he saw the page proofs.)  The
experiment was completed on time, and the publisher considers it a complete
success. (This despite some geographical complications: the publisher was in
London, the book's author in Brussels, and this paper's author in California. 
Almost all communication was done via an international computer network, and
the project was nearly completed before all the participants met for the first
time.) ...

While procedural markup (or no markup at all) leaves a document as a character
string that has no form other than that which can be deduced from analysis of
the document's meaning, GML markup reduces a document to a regular
expression in a known grammar.  This permits established techniques of
computational linguistics and compiler design to be applied to natural language
processing and other document processing applications.

*start*
05228 00024 USt
Date: 15 July 1981 6:44 pm PDT (Wednesday)
From: Mitchell.PA
Subject: Current Level 0/1 Interdoc status
To: Horning
cc: Mitchell

Jim,

Here is my rendering (rending?) of my whiteboard and an attempt to solve a few
loose ends.  The item of which I am most unsure is the mechanism for
connecting environments and the binding function in the semantics section. 
Have at it.

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

We imagine an InterDoc script being processed in the following manner (or in
any algorithmically equivalent way, of course):

Parse the script, evaluating environment transformations (called functions in the
semantics) as soon as parsed.  In general, these functions may return zero or
more "values": if zero, then the function has no effect on the tree structure
being generated from the script; if one or more, then each of these becomes a
leaf subnode of the node currently being elaborated.  A node with its own
substructure may also be returned.


Basic InterDoc Semantics

The kinds of values that can be represented in an InterDoc script are
	primitiveValue:
		NIL
		Boolean: {F,T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		atom:  (the null id), bold, thisIsAnAtom, Helvetica, . . .
		label: #A123, #anAtom, #Paragraph
		the empty environment: nullEnv
		modifier: {var,local,const,propagate,none}
		and sequences of primitiveValues;	
	environment: id > value X modifier
	function: environment > value
	node: (labels, function) -> function X value

The expression forms of interest come from the following set:
	literal
	id		-- (should probably also have ~id)
	id.n		-- n a name
	op(n,v,m)	-- ( op in {+,,*,/,and,or,...}, v a value, m a modifier)
	bind(n,v,m)
	bindq(n,v,m)
	compose(e1,e2)
	invoke(n)
	cond(e1,e2,e3)	-- if e1 then e2 else e3

The semantics of these expression forms are defined by the following evaluation
rules (E=Eval,  denotes an environment; (id) is the value associated with id
in ; <id> is the modifier of id in ; [id←(v,m)]() means " with id bound to
(v,m)"):
	binding(id,nullEnv)=none
	binding(id,) = if <id>=none then binding(id,(parent)) else <id>
	E(id,) = if <id>=none then E(parent.id,) else (id)
	E(id,nullEnv) = id
	E(literal,) = primitiveValue(literal)
	E(id.n,) = E(n,(id))
	E(compose(e1,e2),) = E(e2,E(e1,))
	E(invoke(n),) = E(n,)()
	E(cond(e1,e2,e3),) = if E(e1,)=T then E(e2,) else E(e3,)
	E(bindq(id,v,m),) =
		id=parent			   => [ERROR←T]()
		binding(id,)=const 	   => [ERROR←T]()
		m=var and binding(id,)=var =>
			[id←(v,var)]([parent←E(bindq(id,v,propagate),(parent))]())
		m=propagate and <id>=none  =>
			[parent←E(bindq(id,v,propagate),(parent))]()
		T				   => [id←(v,m)]()
	E(bindq(id.n,v,m),) = [id←E(bindq(n,v,m),(id))]()
	E(bind(n,v,m),) = E(bindq(n,E(v,),m),)
	E(op(n,v,m),) = E(bindq(n, op(E(n,),E(v,)),m),)

Notes:
	[ERROR←T]() simply notes that an error has occurred in a bindq in 



How semantics are associated with an entire document:

Each environment initially contains only its parent (as the id "parent").  When a
valid bindq(id,v,var) is evaluated in an environment , it may have
environmental impact on both  and (parent).  It will have an effect on
(parent) if already bound as var in the parent chain, in which case its effect
on (parent) is bindq(id,v,propagate), which, since parent is a component of ,
alters  to be [parent←E(bindq(id,v,propagate),(parent))](); then, this altered
, ' is further altered by modifying id, i.e., [id←(v,var)](').  An "propagate"
bindq in  has the semantics that it is passed on to (parent) if <id>=none and
acts like bindq(id,v,local) otherwise.

When an id is referred to and <id>=none, then the value is sought in
(parent), i.e., E(parent.id,) is evaluated (this is a recursive definition).  I don't
think this lengthening rule causes any problems assuming that direct
assignments to parent are not allowed (the first line in the semantics of bindq
rules this out).



Semantics of labels:

A label #atom on a node gives that node membership in the set named by atom. 
Multiple labels place a single node in multiple sets, and a unique label on a
node places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

The low-level syntax for InterDocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some contents, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] structure* ")"
label ::= "#" atom
structure ::= envTrans | content
content ::= literal | ["'"] name | node
literal ::= Boolean | integer | hexint | real | string | label
name ::= atom ( "." atom)*
atom ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
envTrans ::= singleTrans | compoundTrans
singleTrans ::= name [ "%" ] rhs		-- % means var
rhs ::= Op ( compoundTrans | content ) | "." compoundTrans
compoundTrans ::= "{" singleTrans* "}"
Op ::= "=" | "←" | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .

Missing or in question:
	literal sequences
	optional quote before name in a content

*start*
01253 00024 USt
Date: 15 July 1981 6:46 pm PDT (Wednesday)
From: Horning.pa
Subject: Draft Interdoc Outline
To: Mitchell
cc: Horning

[Notes for the contents of the document we hope to construct in the next two
weeks.  * marks items likely to be only sketched at this time.  XXX marks
placeholders for items needed but not being worked on.]

			TOWARDS AN INTERCHANGE LANGUAGE
				FOR EDITABLE DOCUMENTS

INTRODUCTION
	* Rationale and background
	* Overview
	Scope
	Exclusions
	* Feasibility

* CONCEPTS AND GUIDING PRINCIPLES

EXAMPLES [hardcopy, private representation, Interdoc script]
	Laurel message
	Simple Bravo document
	BravoX document with styles

THE BASE LANGUAGE
	Syntax
	Primitive and sequence data types and literals
	Labels and references

PROPERTIES
	Environments, names, and values
	Transformations: binding, definitions and invocations
	Scope and persistence
	Standard properties

CONVENTIONS
	[Property definitions to be shared by various editor classes]
	Text
	Messages
	* Fonts and formats
	* Hierarchical documents
	* Styles
	XXX Graphics

PRAGMATICS
	* Private encodings and private representations
	XXX Conversion efficiency

XXX APPENDICES
	GLOSSARY
	FORMAL SEMANTIC DEFINITION
	RELATION TO OTHER STANDARDS

XXX INDEX

*start*
04792 00024 USt
Date: 16 July 1981 3:36 pm PDT (Thursday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 1
To: Mitchell
cc: Horning

We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, evaluating environment transformation functions as soon as
parsed (so that the environment of each piece of content is available during
parsing).  In general, these functions may return zero or more "values": if zero,
then the function has no effect on the tree structure being generated from the
script; if one or more, then each of these becomes a leaf subnode of the node
currently being elaborated.  A node with its own substructure may also be
returned. 

Basic InterDoc Semantics

The kinds of values that can be represented in an InterDoc script are
	primitiveValue:
		NIL
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anAtom, #Paragraph
		the empty environment: nullEnv
		modifier: {var, local, const, assign, none}
		and sequences of primitiveValues;	
	environment: id > value, modifier
	function: environment > value
	node: labels, function

The functional expressions of interest come from the following set:
		-- by convention n: name, v: value, m: modifier, e: expression
	literal
	name	-- id ( '. id)*
	op(n, v, m)	-- ( op in {+, , *, /, and, or, ... })
	bindq(n, v, m)
	bind(n, v, m)
	compose(e1, e2)
	invoke(n)
	cond(e1, e2, e3)	-- if e1 then e2 else e3
	node(labels, function)

The semantics of these expressions are defined by the following evaluation
rules (E for evaluate,  denotes an environment; (id) is the value bound to id
in ; <id> is the modifier of id in ; [id←(v, m)]() means " with id bound to
(v, m)"):
	modifier(id, nullEnv)=none
	modifier(id, ) = if <id>=none then modifier(id, (outer)) else <id>

	E(id, nullEnv) = id
	E(id, ) = if <id>=none then E(id, (outer)) else (id)
	E(id.n, ) = E(n, (id))

	E(literal, ) = primitiveValue(literal)

	E(compose(e1, e2), ) = E(e2, E(e1, ))

	E(invoke(n), ) = E(E(n, ), )

	E(cond(e1, e2, e3), ) = if E(e1, )=T then E(e2, ) else E(e3, )

	E(bindq(id, v, m), ) =
		modifier(id, )=const => 
		m=assign		 => {
			    <id>=local	=> 
			    <id>=var	=> [id←(v, var)]()
			    <id>=none	=>
				[outer←(E(bindq(id, v, assign), (outer)), local)]() }
		T			 => [id←(v, m)]()

	E(bindq(id.n, v, m), ) = [id←E(bindq(n, v, m), (id))]()

	E(bind(n, v, m), ) = E(bindq(n, E(v, ), m), )

	E(op(n, v, m), ) = E(bindq(n, OP(E(n, ), E(v, )), m), )
		-- where OP denotes the binary function associated with op

	E(node(l, f), ) = E(outer, E(f, [outer←(, local)](nullEnv)))



How semantics are associated with an entire document:

Each environment initially contains only its "inherited" environment (bound to
the id "outer").  Most bindings take place directly in .  However, the value of a
bindq(id, v, assign) in an environment  will change  by rebinding id in the
"innermost" environment (following the chain of outer's) in which it is bound,
provided that binding has the modifier var.

When an id is referred to and <id>=none, then the value is sought recursively
in (outer).  Perverse explicit bindings to outer might create loops, leaving some
ids undefined, but there seems to be little reason to clutter up the semantics by
forbidding such assignments.



Semantics of labels:

A label #atom on a node gives that node membership in the set named by atom. 
Multiple labels place the node in multiple sets, and a unique label on a node
places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

Note that we should really be using this syntax above, both to define the
syntax of expressions, and in the left-hand side of the semantic equations.

The low-level syntax for InterDocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some contents, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] content* ")"
label ::= "#" id
content ::= literal | ["'"] name | node | envTrans
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
envTrans ::= singleTrans | compoundTrans
singleTrans ::= name rhs
rhs ::= Op ( compoundTrans | content ) | "." compoundTrans
compoundTrans ::= "{" singleTrans* "}"
Op ::= "=" | "←" | "%" | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .
		-- % means var

Missing or in question:
	literal sequences
	optional quote before name in a content

*start*
02222 00024 USt
Date: 16 July 1981 3:38 pm PDT (Thursday)
From: Mitchell.PA
Subject: Draft Interdoc Outline and Meeting Reminder
To: InterDoc
cc: Horning, Mitchell

We believe we are at a point where it would be worthwhile meeting tomorrow,
Friday, July 17 at the canonical time of 1:30 p.m. in the CSL Commons.  Jim H.
and Jim M. would like to present the results of their efforts of the last two weeks
with John Guttag and Butler Lampson.  We would also like to discuss the table
of contents for a document on InterDoc, and I have attached that table of
contents to this message.  Jim H. will be sending a separate message on the
semantics and syntax of interdoc scripts today so you will all have a chance to
look it over beforehand.  See you there.

Jim M.



[Notes for the contents of the document we hope to construct in the next two
weeks.  * marks items likely to be only sketched at this time.  XXX marks
placeholders for items needed but not being worked on.  Explanatory material is
in Laurel markers like this]

			TOWARDS AN INTERCHANGE LANGUAGE
				FOR EDITABLE DOCUMENTS

INTRODUCTION
	* Rationale and background
	* Overview
	Scope
	Exclusions
	* Feasibility

* CONCEPTS AND GUIDING PRINCIPLES
	Descriptive rather than procedural
	Maintaining document structure over edits
	Using limited editors on rich documents
	An open-ended standard

EXAMPLES [hardcopy, private representation, Interdoc script]
	Laurel message
	BravoX document with styles
	Star document with a bar chart, a simple curve, a table, or a form
	A GML example (from SIGOA paper)

THE BASE LANGUAGE
	Syntax
	Primitive and sequence data types and literals
	Labels and references

PROPERTIES
	Environments, names, and values
	Transformations: binding, definitions, and invocations
	Scope and persistence
	Standard properties

CONVENTIONS
	[Property definitions to be shared by various editor classes]
	Text
	Messages
	* Fonts and formats
	* Hierarchical documents
	* Styles
	XXX Graphics

PRAGMATICS
	* Private encodings and private representations
	XXX Conversion efficiency

XXX APPENDICES
	GLOSSARY
	FORMAL SEMANTIC DEFINITION
	RELATION TO OTHER STANDARDS

XXX INDEX

*start*
05190 00024 USt
Date: 16 July 1981 7:41 pm PDT (Thursday)
From: Mitchell.PA
Subject: Current Level 0/1 Interdoc status/rev. 2
To: Mitchell
cc: Horning

We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, evaluating environment transformation functions as soon as
parsed (so that the environment of each piece of content is available during
parsing).  In general, these functions may return zero or more "values": if zero,
then the function has no effect on the tree structure being generated from the
script; if one or more, then each of these becomes a leaf subnode of the node
currently being elaborated.  A node with its own substructure may also be
returned. 

Basic InterDoc Semantics

The kinds of values that can be represented in an InterDoc script are
	primitiveValue:
		NIL
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anAtom, #Paragraph
		the empty environment: nullEnv
		modifier: {var, local, const, assign, none}
		and sequences of primitiveValues;	
	environment: id > value, modifier
	function: environment > value
	node: labels, function

The functional expressions of interest come from the following set:
		-- by convention n: name, v: value, m: modifier, e: expression
	literal
	name	-- id ( '. id)*
	bind(n, m, op, v)	-- ( op in {', +, , *, /, and, or, ... })
	compose(e1, e2)
	invoke(n)
	cond(e1, e2, e3)	-- if e1 then e2 else e3
	node(labels, function)

The semantics of these expressions are defined by the following evaluation
rules (E for evaluate, V for value,  denotes an environment; (id) is the value
bound to id
in ; <id> is the local modifier of id in ; [id←(v, m)]() means " with id
bound to (v, m)"):

	E(n, ) = 

	E(literal, ) = 

	E(compose(e1, e2), ) = E(e2, E(e1, ))

	E(invoke(n), ) = E(V(n, ), )

	E(cond(e1, e2, e3), ) = if V(e1, )=T then E(e2, ) else E(e3, )

	E(bind(n, m, op, v), ) = bindq(n, m, apply(op, n, v, ), )

	E(node(l, f), ) = E(outer, E(f, [outer←(, local)](nullEnv)))


	V(id, nullEnv) = id
	V(id, ) = if <id>=none then V(id, (outer)) else (id)
	V(id.n, ) = V(n, (id))

	V(literal, ) = primitiveValue(literal)

	V(invoke(n), ) = V(V(n, ), )

	V(cond(e1, e2, e3), ) = if V(e1, )=T then V(e2, ) else V(e3, )

	V(node(l, f), ) = node(l, evalNode(f, ))

	bindq(id, m, v, ) =
		modifier(id, )=const => 
		m=assign		 => {
			    <id>=var	=> [id←(v, var)]()
			    <id>=none and modifier(id,)=var	=>
				[outer←(bindq(id, assign, v, (outer)), local)]()
			    T	=>  }
		T			 => [id←(v, m)]()

	bindq(id.n, m, v, ) = [id←bindq(n, m, v, (id))]()

	modifier(id, nullEnv)=none
	modifier(id, ) = if <id>=none then modifier(id, (outer)) else <id>

	apply(op, n, v, ) =	op=QUOTE	=> v
					op=PLUS	=> E(n, )+E(v, )
					. . .



How semantics are associated with an entire document:

Each environment initially contains only its "inherited" environment (bound to
the id "outer").  Most bindings take place directly in .  However, the value of a
bindq(id, assign, v) in an environment  will change  by rebinding id in the
"innermost" environment (following the chain of outer's) in which it is bound,
provided that binding has the modifier var.

When an id is referred to and <id>=none, then the value is sought recursively
in (outer).  Perverse explicit bindings to outer might create loops, leaving some
ids undefined, but there seems to be little reason to clutter up the semantics by
forbidding such assignments.



Semantics of labels:

A label #atom on a node gives that node membership in the set named by atom. 
Multiple labels place the node in multiple sets, and a unique label on a node
places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

Note that we should really be using this syntax above, both to define the
syntax of expressions, and in the left-hand side of the semantic equations.

The low-level syntax for InterDocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some contents, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] content* ")"
label ::= "#" id
content ::= literal | name | node | envTrans
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
envTrans ::= singleTrans | compoundTrans
singleTrans ::=  name ( "=" | ":" | ":=" | "←" ) rhs
rhs ::= [ op ] content | ["."] compoundTrans
compoundTrans ::= "{" singleTrans* "}"
op ::= "'" | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .

Notes:
node:	the effect of content* is obtained using compose
content:	if a literal, it becomes part of the fringe and has no effect	

Missing or in question:
	literal sequences
	when explaining semantics of labels, the set of nodes you get are those in
the dominant structure, not any nodes salted away in the environment that
happen to have labels.

*start*
04728 00024 USt
Date: 17 July 1981 10:38 am PDT (Friday)
From: Mitchell.PA
Subject: Current Level 0/1 Interdoc status/rev. 3
To: Interdoc

[The following is incomplete, and not internally consistent.  We broadcast it in
its present state to indicate the style and magnitude of the definition we are
proposing.  Please do not take the fine details overly seriously.]

We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, evaluating environment transformation functions as soon as
parsed (so that the environment of each piece of content is available during
parsing).  A separate function is used to compute the "value" of a node. 

Basic InterDoc Semantics

The kinds of values that can be represented in an InterDoc script are
	primitiveValue:
		NIL
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anAtom, #Paragraph
		the empty environment: nullEnv
		mode: {VAR, LOCAL, CONST, ASSIGN, NONE}
		and sequences of primitiveValues;	
	environment: id > value, mode
	function: environment > value
	node: labels, function

The "abstract syntax" of scripts involves the following constructors:
		-- by convention n: name, v: value, m: mode, e: expression
	literal
	name	-- id ( '. id)*
	compose(e1, e2)
	invoke(n)
	cond(e1, e2, e3)	-- if e1 then e2 else e3
	bind(n, m, op, v)	-- ( op in {', +, , *, /, and, or, ... })
	node(labels, function)

The semantics of these expressions are defined by the following evaluation
rules (E for evaluate, V for value,  denotes an environment; (id) is the value
bound to id in ; <id> is the LOCAL mode of id in ; [id←(v, m)]() means "
with id bound to (v, m)"):

	E(n, ) = 

	E(literal, ) = 

	E(compose(e1, e2), ) = E(e2, E(e1, ))

	E(invoke(n), ) = E(V(n, ), )

	E(cond(e1, e2, e3), ) = if V(e1, )=T then E(e2, ) else E(e3, )

	E(bind(n, m, op, v), ) = bindq(n, m, apply(op, n, v, ), )

	E(node(l, f), ) = E(outer, E(f, [outer←(, LOCAL)](nullEnv)))


	V(id, nullEnv) = id
	V(id, ) = if <id>=NONE then V(id, (outer)) else (id)
	V(id.n, ) = V(n, (id))

	V(literal, ) = primitiveValue(literal)

	V(invoke(n), ) = V(V(n, ), )

	V(cond(e1, e2, e3), ) = if V(e1, )=T then V(e2, ) else V(e3, )

	V(node(l, f), ) = node(l, evalNode(f, ))

	evalNode(f, ) = to be defined

	bindq(id, m, v, ) =
		mode(id, )=CONST => 
		m=ASSIGN		 => {
			    <id>=VAR	=> [id←(v, VAR)]()
			    <id>=NONE and mode(id,)=VAR	=>
				bindq(outer.id, ASSIGN, v, )
			    T	=>  }
		T			 => [id←(v, m)]()

	bindq(id.n, m, v, ) = [id←(bindq(n, m, v, (id)), LOCAL)]()

	mode(id, nullEnv)=NONE
	mode(id, ) = if <id>=NONE then mode(id, (outer)) else <id>

	apply(op, n, v, ) =	op=BLANK	=> V(v, )
					op=QUOTE	=> v
					op=PLUS	=> V(n, )+V(v, )
					. . .



How semantics are associated with an entire document:

Each environment initially contains only its "inherited" environment (bound to
the id "outer").  Most bindings take place directly in .  However, the value of a
bindq(id, ASSIGN, v, ) will change  by reBinding id in the "innermost"
environment (following the chain of outers) in which it is bound, provided that
binding has the mode VAR.

When an id is referred to and <id>=NONE, then the value is sought recursively
in (outer).  Perverse explicit bindings to outer might create loops, leaving some
ids undefined, but there seems to be little reason to clutter up the semantics by
forbidding such assignments.



Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

The low-level syntax for InterDocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some contents, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] content* ")"
label ::= "#" id
content ::= literal | name | node | binding
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
binding ::= singleBinding | compoundBinding
singleBinding ::=  name mode rhs
mode ::= "=" | ":" | ":=" | "←"
rhs ::= [ op ] content | ["."] compoundBinding
compoundBinding ::= "{" singleBinding* "}"
op ::= "'" | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .

Missing or in question:
	literal sequences

*start*
01260 00024 USt
Date: 21 July 1981 2:42 pm PDT (Tuesday)
From: Mitchell.PA
Subject: A Laurel document rendered in syntax of Interdoc 0/1 rev. 5
To: Horning.PA
cc: Mitchell


 (
   TextDoc				-- has style "TextDoc"
   justified←F			-- "←" means overridable default
   font←.{family=TimesRoman size=10 face←normal}
   margins←.{left←2540 right←19050}
   leading←.{x←1 y←1}		-- overridable default leadings
   MsgInfo=		-- Laurel information for easy access; none is changeable
      {
      pieces={hdr=#1 body=#2}		-- internal references to labelled nodes
      time=<18 June 1981 9:18 am PDT (Thursday)>
      from=<Mitchell.PA>			-- collected by Laurel; could use refs?
      subject=<A Sample Document Syntax>
      to=<Horning.PA>
      cc=<Mitchell, InterDoc↑.PA>
      authenticated=T
      }
    (#1:				-- "#1" is the label of this node
      Paragraph			-- it's a paragraph
      <Date: > MsgInfo.time		-- place the value of MsgInfo.time here
      <From: > MsgInfo.from
      <Subject: > MsgInfo.subject
      <cc: > MsgInfo.cc
    )
    (#2:
      leading.y←6				-- override outer y leading
      (Paragraph <text of paragraph>)	-- node which is a paragraph
      (Paragraph <text of paragraph>)
      (Paragraph <text of paragraph>)
    )
)
*start*
05942 00024 USt
Date: 17 July 1981 6:41 pm PDT (Friday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 5
To: Interdoc

[Incorporating corrections to the local errors noted during the meeting this
afternoon, plus a treatment of environment-valued expressions (see the new cases
in apply, E[inner], etc.).]

We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, evaluating environment transformation functions as soon as
parsed (so that the environment of each piece of content is available during
parsing).  A separate function is used to compute the "value" of a node. 

Basic Interdoc Semantics

The kinds of values that can be represented in an Interdoc script are
	primitiveValue:
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anId, #Paragraph
		the empty environment: nullEnv
		the empty list: NIL
	environments, which map ids to values and modes
	expressions

The "abstract syntax" of expressions involves the following constructors:
		-- by convention n: name, e: expression v: value,
	literal
	name	-- id ( "." id)*
	quote(e)
	compose(e1, e2)
	cond(e1, e2, e3)	-- if e1 then e2 else e3
	node(labels, e)
	bind(n, m, op, e)
where m is in { =, :, ←, := } (or CONST, VAR, ASSIGN, LOCAL, respectively)
	= denotes constant binding
	: denotes variable declaration and initialization
	← denotes assignment to a previously declared variable
	:= denotes a local binding (cannot be affected by subnodes)
and op is in { <empty>, ', +, , *, /, AND, OR, <braces>, .<braces>, ... }
		(or BLANK, QUOTE, PLUS, MINUS, TIMES, DIVIDE, ... )
	<empty> binds to the current value of e
	' binds to the expression e
	+, , *, /, AND, OR, ... bind to the result of a binary operation
		between the current value of n and the current value of e
	<braces> bind to a nested environment containing only the bindings
		resulting from e
	.<braces> uses e to update the bindings in the environment bound to n


The semantics of scripts are defined by the following evaluation rules, where
	E denotes the environment transformation function
	V denotes the value function
	C denotes an environment, generally the "current" one
	C(id) denotes the value bound to id in C
	C<id> denotes the mode bound to id in C (NONE, if id isn't bound in C)
	(C | id←v, m) means "C with (v, m) bound to id"

	E: expression > ( environment > environment )

	V: expression > ( environment > value )

	bindq: name, mode, value, environment > environment

	modeOf: id, environment > mode

	apply: op, mode, value, environment > value

	insert: value, list > list

E[literal](C) = C

E[n](C) = E[V[n](C)](C)

E[quote(n)](C) = C

E[](C) = C
E[e1 e*](C) = E[e*](E[e1](C))

E[cond(e1, e2, e3)](C) = if V[e1](C) then E[e2](E[e1](C)) else E[e3](E[e1](C))

E[node(l, f)](C) = V[outer](E[f](nullEnv | outer←C, LOCAL))

E[bind(n, m, op, e)](C) = bindq(n, m, apply(op, n, e, C), C)

E[{inner}](C) = (inner | outer←C, LOCAL)



V[literal](C) = literal

V[id](nullEnv) = id
V[id](C) = if C<id>=NONE then V[id](C(outer)) else C(id)
V[id.n](C) = V[n](V[id](C))

V[quote(e)](C) = e

V[] = NIL
V[e1 e*](C) = insert(V[e1](C), V[e*](E[e1](C)))

V[cond(e1, e2, e3)](C) = if V[e1](C) then V[e2](E[e1](C)) else V[e3](E[e1](C))

V[node(l, e)](C) = node(l, V[e](C))

V[bind(n, m, op, v)](C) = NIL

V[{inner}](C) = V[inner](C)    ?


bindq(id, m, v, C) =
	modeOf(id, C)=CONST => C
	m=ASSIGN		 => 
		  { C<id>=VAR		=> (C | id←v, VAR)
		    modeOf(id, C)=VAR	=> bindq(outer.id, ASSIGN, v, C)
		    T				=> C }
	T			 => (C | id←v, m)

bindq(id.n, m, v, C) = (C | id←bindq(n, m, v, C(id)), LOCAL)

modeOf(id, nullEnv)=NONE
modeOf(id, C) = if C<id>=NONE then modeOf(id, C(outer)) else C<id>

apply(op, n, e, C) =
	op=BLANK	=> V[e](C)
	op=QUOTE	=> e
	op=PLUS	=> V[n](C)+V[e](C)
	op=BRACES	=>
			(E[e](nullEnv | outer←C, LOCAL) | outer←nullEnv, LOCAL)
	op=DOTBRACES =>
			(E[e](V[n](C) | outer←C, LOCAL) | outer←nullEnv, LOCAL)
	. . .

-- insert(NIL, l) = l 



How semantics are associated with an entire document:

Each environment initially contains only its "inherited" environment (bound to
the id "outer").  Most bindings take place directly in C.  However, the value of a
bindq(id, ASSIGN, v, C) will change C by rebinding id in the "innermost"
environment (following the chain of outers) in which it is bound, if that
binding has the mode VAR.

When an id is referred to and C<id>=NONE, then the value is sought recursively
in C(outer).  Perverse explicit bindings to outer might create loops, leaving some
ids undefined, but there seems to be little reason to clutter up the semantics by
forbidding such assignments.



Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

The low-level syntax for Interdocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some contents, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] content* ")"
label ::= "#" id
content ::= literal | ["'"] name | node | binding
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
binding ::= singleBinding | compoundBinding
singleBinding ::=  name mode rhs
mode ::= "=" | ":" | ":=" | "←"
rhs ::= [ op ] content | ["."] compoundBinding
compoundBinding ::= "{" content* "}"
op ::= "'" | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .

Missing or in question:
	literal sequences
	syntax for conditionals

*start*
01294 00024 USt
Date: 21 July 1981 3:48 pm PDT (Tuesday)
From: Horning.pa
Subject: Re: A Laurel document rendered in syntax of Interdoc 0/1 rev. 5
In-reply-to: Your message of 21 July 1981 2:42 pm PDT (Tuesday)
To: Mitchell
cc: Horning

Jim,

That looks like a fairly reasonable rendition.  Do you think that it would be
worth including a discussion of the some of the available alternatives?  E.g.,
the "fields" of MsgInfo could be handled using labels, making repetitions OK,
and the external environment might well contain a definition of LaurelStyle

LaurelStyle=
'{
	TextDoc
	P←Paragraph
	justified←F
	font←.{family=TimesRoman size=10 face←normal}
	margins←.{left←2540 right←19050}
	leading←.{x←1 y←1}
	(#PrintForm:
	      P
	      <Date: > #time	
	      <From: > #from
	      <Subject: > #subject
	      <To: > #to
	      leading.y←6
	      #Body
	      <cc: > #cc
        )
}

Now the Laurel document would be described by the following script:

( (#Heading:
      (#time:<18 June 1981 9:18 am PDT (Thursday)>)
      (#from: authenticated=T <Mitchell.PA>)
      (#subject:<A Sample Document Syntax>)
      (#to:<Horning.PA>)
      (#cc:<Mitchell, InterDoc↑.PA>)
   )
  (#Body:
      (P <text of paragraph1>)
      (P <text of paragraph2>)
      (P <text of paragraph3>)
   )

)

*start*
08566 00024 USt
Date: 21 July 1981 4:39 pm PDT (Tuesday)
From: Mitchell.PA
Subject: A Laurel document rendered in syntax of Interdoc 0/1 rev. 6
To: Interdoc

Here follow two renderings of a sample Laurel message as an Interdoc script
using rev. 6 of the syntax, which is appended to this message.  Each assumes
some external definitions (e.g., font, margins), which are not specified here.  The
examples are intended to illustrate different ways of using the language; we
have not decided which we prefer.  Your comments would be appreciated.

 (#Rendering1:
   TextDoc				-- has style "TextDoc"
   justified←F			-- "←" means overridable default
   font←.{family=TimesRoman size=10 face←normal}
   margins←.{left←2540 right←19050}
   leading←.{x←1 y←1}		-- overridable default leadings
   LaurelInfo=	-- Laurel information for easy access; none is changeable
      {
      pieces={hdr=#Heading body=#Body}-- internal references to labelled nodes
      time=<18 June 1981 9:18 am PDT (Thursday)>
      from=<Mitchell.PA>
      subject=<A Sample Document Syntax>
      to=<Horning.PA>
      cc=<Mitchell, Interdoc↑.PA>
      authenticated=T
      }
    (#Heading:			-- "#Heading" is the label of this node
      Paragraph			-- it's a paragraph
      <Date: > LaurelInfo.time	-- place the value of LaurelInfo.time here
      <From: > LaurelInfo.from
      <Subject: > LaurelInfo.subject
      <cc: > LaurelInfo.cc
    )
    (#Body:
      leading.y←6				-- override outer y leading
      (Paragraph <text of paragraph>)	-- node which is a paragraph
      (Paragraph <text of paragraph>)
      (Paragraph <text of paragraph>)
    )
)

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

The "fields" of MsgInfo could be handled using labels, making repetitions OK,
and the external environment might well contain a definition of LaurelStyle

LaurelStyle=
'{
	TextDoc
	P←Paragraph
	justified←F
	font←.{family=TimesRoman size=10 face←normal}
	margins←.{left←2540 right←19050}
	leading←.{x←1 y←1}
	PrintForm=
	  '(
	      P
	      <Date: > #time	
	      <From: > #from
	      <Subject: > #subject
	      <To: > #to
	      leading.y←6
	      #Body
	      <cc: > #cc
         )
}

Now the Laurel document would be described by the following script:

(#Rendering2:
   LaurelStyle 
   (#Heading:
      (#time:<18 June 1981 9:18 am PDT (Thursday)>)
      (#from: authenticated=T <Mitchell.PA>)
      (#subject:<A Sample Document Syntax>)
      (#to:<Horning.PA>)
      (#cc:<Mitchell, Interdoc↑.PA>)
   )
  (#Body:
      (P <text of paragraph1>)
      (P <text of paragraph2>)
      (P <text of paragraph3>)
   )

)

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


Current Level 0/1 Interdoc status/rev. 6

[Incorporating corrections to the local errors noted during the meeting this
afternoon, plus a treatment of environment-valued expressions (see the new cases
in apply, E[inner], etc.).]

We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, evaluating environment transformation functions as soon as
parsed (so that the environment of each piece of content is available during
parsing).  A separate function is used to compute the "value" of a node. 

Basic Interdoc Semantics

The kinds of values that can be represented in an Interdoc script are
	primitiveValue:
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anId, #Paragraph
		the empty environment: nullEnv
		the empty list: NIL
	environments, which map ids to values and modes
	expressions

The "abstract syntax" of expressions involves the following constructors:
		-- by convention n: name, e: expression v: value,
	literal
	name	-- id ( "." id)*
	quote(e)
	compose(e1, e2)
	cond(e1, e2, e3)	-- if e1 then e2 else e3
	node(labels, e)
	bind(n, m, op, e)
where m is in { =, :, :=, ← } (or CONST, VAR, ASSIGN, LOCAL, respectively)
	= denotes constant binding
	: denotes variable declaration and initialization
	:= denotes assignment to a previously declared variable
	← denotes a local binding (cannot be affected by subnodes)
and op is in { <empty>, ', +, , *, /, AND, OR, <braces>, .<braces>, ... }
		(or BLANK, QUOTE, PLUS, MINUS, TIMES, DIVIDE, ... )
	<empty> binds to the current value of e
	' binds to the expression e
	+, , *, /, AND, OR, ... bind to the result of a binary operation
		between the current value of n and the current value of e
	<braces> bind to a nested environment containing only the bindings
		resulting from e
	.<braces> uses e to update the bindings in the environment bound to n


The semantics of scripts are defined by the following evaluation rules, where
	E denotes the environment transformation function
	V denotes the value function
	C denotes an environment, generally the "current" one
	C(id) denotes the value bound to id in C
	C<id> denotes the mode bound to id in C (NONE, if id isn't bound in C)
	(C | id←v, m) means "C with (v, m) bound to id"

	E: expression > ( environment > environment )

	V: expression > ( environment > value )

	bindq: name, mode, value, environment > environment

	modeOf: id, environment > mode

	apply: op, mode, value, environment > value

	insert: value, list > list

E[literal](C) = C

E[n](C) = E[V[n](C)](C)

E[quote(n)](C) = C

E[](C) = C
E[e1 e*](C) = E[e*](E[e1](C))

E[cond(e1, e2, e3)](C) = if V[e1](C) then E[e2](E[e1](C)) else E[e3](E[e1](C))

E[node(l, f)](C) = V[outer](E[f](nullEnv | outer←C, LOCAL))

E[bind(n, m, op, e)](C) = bindq(n, m, apply(op, n, e, C), C)

E[{inner}](C) = (inner | outer←C, LOCAL)



V[literal](C) = literal

V[id](nullEnv) = id
V[id](C) = if C<id>=NONE then V[id](C(outer)) else C(id)
V[id.n](C) = V[n](V[id](C))

V[quote(e)](C) = e

V[] = NIL
V[e1 e*](C) = insert(V[e1](C), V[e*](E[e1](C)))

V[cond(e1, e2, e3)](C) = if V[e1](C) then V[e2](E[e1](C)) else V[e3](E[e1](C))

V[node(l, e)](C) = node(l, V[e](C))

V[bind(n, m, op, v)](C) = NIL

V[{inner}](C) = V[inner](C) 


bindq(id, m, v, C) =
	modeOf(id, C)=CONST => C
	m=ASSIGN		 => 
		  { C<id>=VAR		=> (C | id←v, VAR)
		    modeOf(id, C)=VAR	=> bindq(outer.id, ASSIGN, v, C)
		    T				=> C }
	T			 => (C | id←v, m)

bindq(id.n, m, v, C) = (C | id←bindq(n, m, v, C(id)), LOCAL)

modeOf(id, nullEnv)=NONE
modeOf(id, C) = if C<id>=NONE then modeOf(id, C(outer)) else C<id>

apply(op, n, e, C) =
	op=BLANK	=> V[e](C)
	op=QUOTE	=> e
	op=PLUS	=> V[n](C)+V[e](C)
	op=BRACES	=>
			(E[e](nullEnv | outer←C, LOCAL) | outer←nullEnv, LOCAL)
	op=DOTBRACES =>
			(E[e](V[n](C) | outer←C, LOCAL) | outer←nullEnv, LOCAL)
	. . .

-- insert(NIL, l) = l 



How semantics are associated with an entire document:

Each environment initially contains only its "inherited" environment (bound to
the id "outer").  Most bindings take place directly in C.  However, the value of a
bindq(id, ASSIGN, v, C) will change C by rebinding id in the "innermost"
environment (following the chain of outers) in which it is bound, if that
binding has the mode VAR.

When an id is referred to and C<id>=NONE, then the value is sought recursively
in C(outer).  Perverse explicit bindings to outer might create loops, leaving some
ids undefined, but there seems to be little reason to clutter up the semantics by
forbidding such assignments.



Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

The low-level syntax for Interdocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some expression, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] expression* ")"
label ::= "#" id
expression ::= literal | ["'"] name | node | binding | conditional
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
binding ::= singleBinding | compoundBinding
singleBinding ::=  name mode rhs
mode ::= "=" | ":" | ":=" | "←"
rhs ::= [ op ] expression | ["."] compoundBinding
compoundBinding ::= "{" expression* "}"
op ::= "'" | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .
conditional ::= "IF(" expression "," expression [ "," expression ] ")"

Missing or in question:
	literal sequences
	relational operators

Jim H. and Jim M.
*start*
04250 00024 USt
Date: 22 July 1981 5:10 pm PDT (Wednesday)
From: Mitchell.PA
Subject: A Star document rendered in Interdoc/rev. 6.
To: Horning
cc: Mitchell

This example is taken from page 130 of the Star Functional Specification and
shows a page of a paginated document with a diagram and a footnote (I
recommend that you have that page in front of you when analyzing this
rendition):

Interdoc/Interchange/6.0	-- we probably should have some sort of header
(#p7: newPage
  (Paragraph		-- => justified←F
  <Many of these conclusions are based on prior experience>
  (footRef=#fn1 fn1ref←(FootnoteRef 1) fn1ref)	-- FootnoteRef style for
the contents, "1"
  < which has shown our techniques to be valid.  Other data can be collected by
future changes to your accounting and billing packages, which will allow us to
perform even better analyses and lead to better problem discovery and
correction.>
  )
  (Paragraph
  <The results of the sales analysis suggest that certain organizational changes
can improve the overall efficiency of the operation.  The March figures, in
particular, bear this out.  You will note below a suggested change that we feel
will correct the problems noted in the analysis above.>
  )
  (#Frame1:
  Frame
  frameProps←.{			-- defaults set by invoking Frame
    horizontal←flushLeft vertical←floating
    size←{height←7100 width←9300}
    edges.expandingRightEdge←T
    border←dots1} 
    (#r1: Rectangle
      upperleft←{x←2540 y←700} 
      rectProps←.{			-- defaults set by invoking Rectangle
        size←{height←1000 width←2700} lineType←solid2 shading←7}
        (Title <Headquarters>)
    )
--? perhaps rectProps shouldn't be a contained environment
    (#r2: Rectangle
      upperleft←{x←7300 y←1500} 
      rectProps←.{			-- defaults set by invoking Rectangle
        size←{height←1000 width←1800} lineType←solid2 shading←7}
        (Title <Staff Support>)
    )
    (#r3: Rectangle
      upperleft←{x←200 y←3000} 
      rectProps←.{			-- defaults set by invoking Rectangle
        size←{height←1300 width←2500} lineType←solid2 shading←7}
        (Title <Development>)
    )
    (#r4: Rectangle
      upperleft←{x←200 y←3000} 
      rectProps←.{			-- defaults set by invoking Rectangle
        size←{height←1300 width←2800} lineType←solid2 shading←7}
        (Title <Manufacturing>)
    )
    (#r5: Rectangle
      upperleft←{x←4200 y←5500} 
      rectProps←.{			-- defaults set by invoking Rectangle
        size←{height←1300 width←1600} lineType←solid2 shading←7}
        (Title <West Coast>)
    )
    (#r6: Rectangle
      upperleft←{x←6700 y←5500} 
      rectProps←.{			-- defaults set by invoking Rectangle
        size←{height←1300 width←1600} lineType←solid2 shading←7}
        (Title <East Coast>)
    )
    (#l1out: Line lineProps←.{lineType←solid2 from←#r1 to←#l24in})
    (#l2out: Line lineProps←.{lineType←solid2 from←#r2 to←#l1out})
    (#l3in: Line lineProps←.{lineType←solid2 from←#l-34in to←#r3})
    (#l-4in: Line lineProps←.{lineType←solid2 from←#l-34in to←#r4})
    (#l-34in: Line lineProps←.{lineType←solid2 from←#l3in to←#l4in})
    (#l4out: Line lineProps←.{lineType←solid2 from←#r4 to←#l56in})
    (#l56in: Line lineProps←.{lineType←solid2 from←#l5in to←#l6in})
    (#l5in: Line lineProps←.{lineType←solid2 from←#l56in to←#r5})
    (#l6in: Line lineProps←.{lineType←solid2 from←#l56in to←#6})
  )			-- end of #Frame1
  (Paragraph
  <The process of switching to this new organization will not be an easy one. 
However, the reports seem to suggest many reasons why it should not be
postponed.  In particular, the separation of Manufacturing from Development
should have significant impact.>
  )
  (Paragraph
  <Also, we feel strongly that merging East and West Coast Development will
help.  As we have suggested in past reports, there has always been considerable
replication of effort due to this geographic.  You will recall the events leading
up to the initial contract with our firm.>
  )
  (#fn1: Footnote
  fn1ref		-- place the node with the superscripted 1 here
  <See the 1970 report titled "Organizational Changes and Sales Margin" and other
documents referenced in that document.  Further reports are available if you
need them.>
  )
)			-- end of page

*start*
04028 00024 USt
Date: 23 July 1981 5:00 pm PDT (Thursday)
From: Mitchell.PA
Subject: A Star document rendered in Interdoc/rev. 6.
To: Interdoc

This example is taken from page 130 of the Star Functional Specification and
shows one page of a paginated document with a diagram and a footnote (I
recommend that you have that page in front of you when analyzing this
rendition):

. . .					-- pages 1 .. 6 supposedly precede this one
(#p7: newPage
  (Paragraph.justified←F		-- redefine Paragraph with justification off
  <Many of these conclusions are based on prior experience>
  fn1ref←(FootnoteRef footRef=#fn1 1)	-- FootnoteRef node with contents, "1"
  fn1ref					-- place the footnote ref
  < which has shown our techniques to be valid.  Other data can be collected by
future changes to your accounting and billing packages, which will allow us to
perform even better analyses and lead to better problem discovery and
correction.>
  )
  (Paragraph
  <The results of the sales analysis suggest that certain organizational changes
can improve the overall efficiency of the operation.  The March figures, in
particular, bear this out.  You will note below a suggested change that we feel
will correct the problems noted in the analysis above.>
  )
  (#Frame1: Frame		-- defaults are set by invoking Frame
  horizontal←flushLeft vertical←floating
  size←{height←7100 width←9300}
  edges.expandingRightEdge←T
  border←dots1 
    (#r1: Rectangle			-- defaults are set by invoking Rectangle
    upperleft←{x←2540 y←700} 
    size←{height←1000 width←2700} lineType←solid2 shading←7
      (Title <Headquarters>)
    )
    (#r2: Rectangle
    upperleft←{x←7300 y←1500} 
    size←{height←1000 width←1800} lineType←solid2
      (Title <Staff Support>)
    )
    (#r3: Rectangle
    upperleft←{x←200 y←3000} 
    size←{height←1300 width←2500} lineType←solid2
      (Title <Development>)
    )
    (#r4: Rectangle
    upperleft←{x←200 y←3000} 
    size←{height←1300 width←2800} lineType←solid2
      (Title <Manufacturing>) 
   )
    (#r5: Rectangle
    upperleft←{x←4200 y←5500} 
    size←{height←1300 width←1600} lineType←solid2
      (Title <West Coast>)
    )
    (#r6: Rectangle
    upperleft←{x←6700 y←5500} 
    size←{height←1300 width←1600} lineType←solid2
      (Title <East Coast>)
    )
    (#l1out: Line lineType←solid2 in←#r1 out←#l24in)
    (#l2out: Line lineType←solid2 in←#r2 out←#l1out)
    (#l3in:	Line lineType←solid2 in←#l-34in out←#r3)
    (#l-4in:	Line lineType←solid2 in←#l-34in out←#r4)
    (#l-34in:	Line lineType←solid2 in←#l3in out←#l4in)
    (#l4out: Line lineType←solid2 in←#r4 out←#l56in)
    (#l56in: Line lineType←solid2 in←#l5in out←#l6in)
    (#l5in:	Line lineType←solid2 in←#l56in out←#r5)
    (#l6in:	Line lineType←solid2 in←#l56in out←#6)
  )			-- end of #Frame1
  (Paragraph
  <The process of switching to this new organization will not be an easy one. 
However, the reports seem to suggest many reasons why it should not be
postponed.  In particular, the separation of Manufacturing from Development
should have significant impact.>
  )
  (Paragraph
  <Also, we feel strongly that merging East and West Coast Development will
help.  As we have suggested in past reports, there has always been considerable
replication of effort due to this geographic.  You will recall the events leading
up to the initial contract with our firm.>
  )
  (#fn1: Footnote
  fn1ref		-- place the node with the superscripted 1 here
  <See the 1970 report titled "Organizational Changes and Sales Margin" and other
documents referenced in that document.  Further reports are available if you
need them.>
  )
)			-- end of page



Here a few of the definitions of "styles" invoked in the above example (see page
148 of the Star spec for what they mean): 

Rectangle←{
    constraint←UNCONSTRAINED
    upperleft←{x←0 y←0} 
    size←{height←1000 width←2000}
    lineType←solid1
    shading←0
    }


Line←{
    constraint←UNCONSTRAINED
    lineType←solid1
    arrowHead←{in←none out←none}
    }

*start*
06264 00024 USt
Date: 24 July 1981 4:03 pm PDT (Friday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 7
To: Donahue
cc: Mitchell, Horning

[Jim D.,  We'd like you to put on your formal semanticist hat and constructively
criticize both the form and the content of the following.  Jim H. & Jim M.]

We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, evaluating environment transformation functions as soon as
parsed (so that the environment of each piece of content is available during
parsing).  A separate function is used to compute the "value" of a node. 

Basic Interdoc

The kinds of values that can be appear in an Interdoc script are
	literals:
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anId, #Paragraph
		the empty environment: nullEnv
		the empty list: NIL
	environments, which map ids to values and modes
	expressions

The "abstract syntax" of expressions involves the following constructors:
		-- by convention n: name, e: expression
	literal
	name: id ( "." id)*
	quote(e)
	compose(e1, e2)
	cond(e1, e2, e3)	-- if e1 then e2 else e3
	node(labels, e)
	bind(n, m, op, e)
where m is in { =, :, :=, ← } (or CONST, VAR, ASSIGN, LOCAL, respectively)
	= denotes constant binding
	: denotes variable declaration and initialization
	:= denotes assignment to a previously declared variable
	← denotes a local binding (cannot be affected by subnodes)
and op is in { <empty>, ', +, , *, /, AND, OR, <braces>, .<braces>, ... }
		(or BLANK, QUOTE, PLUS, MINUS, TIMES, DIVIDE, ... )
	<empty> binds to the current value of e
	' binds to the expression e
	+, , *, /, AND, OR, ... bind to the result of a binary operation
		between the current value of n and the current value of e
	<braces> bind to a nested environment containing only the bindings
		resulting from e
	.<braces> uses e to update the bindings in the environment bound to n


The semantics of scripts are defined by the following evaluation rules, where
	E denotes the environment transformation function
	V denotes the value function
	C denotes an environment, generally the "current" one
	C(id) denotes the value bound to id in C
	localMode(id, C) denotes the mode bound to id in C
		(NONE, if id isn't bound in C)
	(C | id←e, m) means "C with (e, m) bound to id"

	E: expression > ( environment > environment )

	V: expression > ( environment > value )

	bindq: name, mode, value, environment > environment

	modeOf: id, environment > mode

	apply: op, mode, value, environment > value

	insert: value, list > list

E[literal](C) = C

E[n](C) = if modeOf(n, C)=NONE then C else E[V[n](C)](C)

E[quote(n)](C) = C

E[](C) = C								-- Basis
E[e1 e*](C) = E[e*](E[e1](C))					-- Composition

E[cond(e1, e2, e3)](C) = if V[e1](C) then E[e2](E[e1](C)) else E[e3](E[e1](C))

E[node(l, e)](C) = V[outer](E[e](nullEnv | outer←C, LOCAL))

E[bind(n, m, op, e)](C) = bindq(n, m, apply(op, n, e, C), C)

E[{e}](C) = E[e](C)



V[literal](C) = literal

V[id](nullEnv) = id
V[id](C) = if localMode(id, C)=NONE then V[id](C(outer)) else C(id)
V[id.n](C) = V[n](V[id](C))

V[quote(e)](C) = e

V[] = NIL								-- Basis
V[e1 e*](C) = insert(V[e1](C), V[e*](E[e1](C)))		-- Composition

V[cond(e1, e2, e3)](C) = if V[e1](C) then V[e2](E[e1](C)) else V[e3](E[e1](C))

V[node(l, e)](C) = node(l, V[e](nullEnv | outer←C, LOCAL))

V[bind(n, m, op, e)](C) = NIL

V[{e}](C) = V[e](C) 


bindq(id, m, e, C) =
	modeOf(id, C)=CONST => C
	m=ASSIGN		 => 
		  { localMode(id, C)=VAR	=> (C | id←e, VAR)
		    modeOf(id, C)=VAR	=> bindq(outer.id, m, e, C)
		    T				=> C }
	T			 => (C | id←e, m)

bindq(id.n, m, e, C) = (C | id←bindq(n, m, e, V[id](C)), modeOf(id, C))

modeOf(n, nullEnv)=NONE
modeOf(id, C) = if localMode(id, C)=NONE then modeOf(id, C(outer))
			else localMode(id, C)
modeOf(id.n, C) = if localMode(id, C)=NONE then modeOf(id.n, C(outer))
			else modeOf(n, V[id](C))

apply(op, n, e, C) =
	op=BLANK	=> V[e](C)
	op=QUOTE	=> e
	op=PLUS	=> V[n](C)+V[e](C)
	. . .
	op=BRACES	=>
			(E[e](nullEnv | outer←C, LOCAL) | outer←nullEnv, LOCAL)
	op=DOTBRACES =>
			(E[e](V[n](C) | outer←C, LOCAL) | outer←nullEnv, LOCAL)

-- insert(NIL, l) = l 



How semantics are associated with an entire document:

Each environment, C, initially contains only its "inherited" environment (bound
to the id "outer").  Most bindings take place directly in C.  However, the value
of a bindq(id, ASSIGN, e, C) will change C by rebinding id in the "innermost"
environment (following the chain of outers) in which it is bound, if that
binding has the mode VAR.

When an id is referred to and localMode(id, C)=NONE, then the value is sought
recursively in C(outer).  Perverse explicit bindings to outer might create loops,
leaving some ids undefined, but there seems to be little reason to clutter up the
semantics by forbidding such assignments.



Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

The low-level syntax for Interdocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some expression, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] expression* ")"
label ::= "#" id
expression ::= literal | ["'"] name | node | binding | conditional
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
binding ::= singleBinding | compoundBinding
singleBinding ::=  name mode rhs
mode ::= "=" | ":" | ":=" | "←"
rhs ::= [ op ] expression | ["."] compoundBinding
compoundBinding ::= "{" expression* "}"
op ::= "'" | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .
conditional ::= "IF(" expression "," expression [ "," expression ] ")"

Missing or in question:
	literal sequences
	relational operators


*start*
07836 00024 USt
Date: 27 July 1981 10:22 am PDT (Monday)
From: Donahue.pa
Subject: Re: Current Level 0/1 Interdoc status/rev. 7
In-reply-to: Horning's message of 24 July 1981 4:03 pm PDT (Friday)
To: Horning
cc: Donahue, Mitchell

<<My comments are in brackets.  Mostly, I looked for errors in functionality of
the expressions -- Jim D. >>

<< General comments --

1. The most important missing piece is a clear description of the underlying
value spaces.  Several confusions noted below are caused by this.

2. After reading this, I wondered if a "denotational style" semantics is the right
way to go -- have you tried a more algebraic approach? >>


We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, evaluating environment transformation functions as soon as
parsed (so that the environment of each piece of content is available during
parsing).  A separate function is used to compute the "value" of a node. 

Basic Interdoc

The kinds of values that can be appear in an Interdoc script are
	literals:
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anId, #Paragraph
		the empty environment: nullEnv
		the empty list: NIL
	environments, which map ids to values and modes
	expressions

The "abstract syntax" of expressions involves the following constructors:
		-- by convention n: name, e: expression
	literal
	name: id ( "." id)*
	quote(e)
	compose(e1, e2)
	cond(e1, e2, e3)	-- if e1 then e2 else e3
	node(labels, e)
	bind(n, m, op, e)
where m is in { =, :, :=, ← } (or CONST, VAR, ASSIGN, LOCAL, respectively)
	= denotes constant binding
	: denotes variable declaration and initialization
	:= denotes assignment to a previously declared variable
	← denotes a local binding (cannot be affected by subnodes)

<< You don't say anywhere, but I take it that { =, :, :=, ← } form the set of legal
modes.  The use of the term mode here is somewhat confusing; if I were an
Algol68 freak, I would have read "mode" as meaning "type" and have been led
astray. >>

and op is in { <empty>, ', +, , *, /, AND, OR, <braces>, .<braces>, ... }
		(or BLANK, QUOTE, PLUS, MINUS, TIMES, DIVIDE, ... )
	<empty> binds to the current value of e
	' binds to the expression e
	+, , *, /, AND, OR, ... bind to the result of a binary operation
		between the current value of n and the current value of e
	<braces> bind to a nested environment containing only the bindings
		resulting from e
	.<braces> uses e to update the bindings in the environment bound to n


The semantics of scripts are defined by the following evaluation rules, where
	E denotes the environment transformation function
	V denotes the value function
	C denotes an environment, generally the "current" one
	C(id) denotes the value bound to id in C
	localMode(id, C) denotes the mode bound to id in C
		(NONE, if id isn't bound in C)
	(C | id←e, m) means "C with (e, m) bound to id"

<< I would put the brackets in here, i.e., (C | id ← <e,m>) >>

	E: expression > ( environment > environment )

	V: expression > ( environment > value )

	bindq: name, mode, value, environment > environment

<< Again, I would prefer
	bindq: [ name, (mode, value ] -> environment -> environment  >>

	modeOf: id, environment > mode

	apply: op, mode, value, environment > value

	insert: value, list > list

E[literal](C) = C

E[n](C) = if modeOf(n, C)=NONE then C else E[V[n](C)](C)

<<E[ V[n](C) ] is ill-formed; V produces a value, while E expects an expression. 
Don't confuse denotations and their meanings >>

E[quote(n)](C) = C

E[](C) = C								-- Basis
E[e1 e*](C) = E[e*](E[e1](C))					-- Composition

E[cond(e1, e2, e3)](C) = if V[e1](C) then E[e2](E[e1](C)) else E[e3](E[e1](C))

E[node(l, e)](C) = V[outer](E[e](nullEnv | outer←C, LOCAL))

<< I think there is some error in this equation, but I'm not sure what the fix is. 
The node label l does not appear in the right-hand side.. ? >>

E[bind(n, m, op, e)](C) = bindq(n, m, apply(op, n, e, C), C)

<< Same problem as before -- bindq takes an expression as its third argument,
while apply delivers a value as its result >>

E[{e}](C) = E[e](C)



V[literal](C) = literal

V[id](nullEnv) = id

<< Just curious -- looking up an identifier in an empty environment yields the
identifier??  Is this necessary because of other parts of the equations? >>

V[id](C) = if localMode(id, C)=NONE then V[id](C(outer)) else C(id)

<< How do I know that C(outer) yields an environment?  (Note that this makes
the value space reflexive:
	Env = Id -> Value
	Value = ... + Env ...)
If C(outer) is not an environment? >>

V[id.n](C) = V[n](V[id](C))

V[quote(e)](C) = e

V[] = NIL								-- Basis
V[e1 e*](C) = insert(V[e1](C), V[e*](E[e1](C)))		-- Composition

V[cond(e1, e2, e3)](C) = if V[e1](C) then V[e2](E[e1](C)) else V[e3](E[e1](C))

V[node(l, e)](C) = node(l, V[e](nullEnv | outer←C, LOCAL))

V[bind(n, m, op, e)](C) = NIL

V[{e}](C) = V[e](C) 


bindq(id, m, e, C) =
	modeOf(id, C)=CONST => C
	m=ASSIGN		 => 
		  { localMode(id, C)=VAR	=> (C | id←e, VAR)
		    modeOf(id, C)=VAR	=> bindq(outer.id, m, e, C)
		    T				=> C }
	T			 => (C | id←e, m)

bindq(id.n, m, e, C) = (C | id←bindq(n, m, e, V[id](C)), modeOf(id, C))

modeOf(n, nullEnv)=NONE
modeOf(id, C) = if localMode(id, C)=NONE then modeOf(id, C(outer))
			else localMode(id, C)
modeOf(id.n, C) = if localMode(id, C)=NONE then modeOf(id.n, C(outer))
			else modeOf(n, V[id](C))

<< Again, functionality problem -- V delivers a value, mode expects an
environment >>

apply(op, n, e, C) =
	op=BLANK	=> V[e](C)
	op=QUOTE	=> e
	op=PLUS	=> V[n](C)+V[e](C)
	. . .
	op=BRACES	=>
			(E[e](nullEnv | outer←C, LOCAL) | outer←nullEnv, LOCAL)
	op=DOTBRACES =>
			(E[e](V[n](C) | outer←C, LOCAL) | outer←nullEnv, LOCAL)

-- insert(NIL, l) = l 



How semantics are associated with an entire document:

Each environment, C, initially contains only its "inherited" environment (bound
to the id "outer").  Most bindings take place directly in C.  However, the value
of a bindq(id, ASSIGN, e, C) will change C by rebinding id in the "innermost"
environment (following the chain of outers) in which it is bound, if that
binding has the mode VAR.

When an id is referred to and localMode(id, C)=NONE, then the value is sought
recursively in C(outer).  Perverse explicit bindings to outer might create loops,
leaving some ids undefined, but there seems to be little reason to clutter up the
semantics by forbidding such assignments.



Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

The low-level syntax for Interdocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some expression, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] expression* ")"
label ::= "#" id
expression ::= literal | ["'"] name | node | binding | conditional
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
binding ::= singleBinding | compoundBinding
singleBinding ::=  name mode rhs
mode ::= "=" | ":" | ":=" | "←"
rhs ::= [ op ] expression | ["."] compoundBinding
compoundBinding ::= "{" expression* "}"
op ::= "'" | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .
conditional ::= "IF(" expression "," expression [ "," expression ] ")"

Missing or in question:
	literal sequences
	relational operators

*start*
09829 00024 USt
Date: 27 July 1981 11:34 am PDT (Monday)
From: Horning.pa
Subject: Re: Current Level 0/1 Interdoc status/rev. 7
In-reply-to: Donahue's message of 27 July 1981 10:22 am PDT (Monday)
To: Donahue
cc: Horning, Mitchell

Replies in placeholders.  Use Next to sequence through them.

<<My comments are in brackets.  Mostly, I looked for errors in functionality of
the expressions -- Jim D. >>

<< General comments --

1. The most important missing piece is a clear description of the underlying
value spaces.  Several confusions noted below are caused by this.

Yes, I think we confused you in several places.  The most important thing to
note is that the value space contains expressions.  This resolves several of your
"type errors."

2. After reading this, I wondered if a "denotational style" semantics is the right
way to go -- have you tried a more algebraic approach? >>

No, I haven't tried doing it algebraically.  My first guess is that it is about the
same complexity, and I'm not sure about readability.


We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, evaluating environment transformation functions as soon as
parsed (so that the environment of each piece of content is available during
parsing).  A separate function is used to compute the "value" of a node. 

Basic Interdoc

The kinds of values that can be appear in an Interdoc script are
	literals:
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anId, #Paragraph
		the empty environment: nullEnv
		the empty list: NIL
	environments, which map ids to values and modes
	expressions

The "abstract syntax" of expressions involves the following constructors:
		-- by convention n: name, e: expression
	literal
	name: id ( "." id)*
	quote(e)
	compose(e1, e2)
	cond(e1, e2, e3)	-- if e1 then e2 else e3
	node(labels, e)
	bind(n, m, op, e)
where m is in { =, :, :=, ← } (or CONST, VAR, ASSIGN, LOCAL, respectively)
	= denotes constant binding
	: denotes variable declaration and initialization
	:= denotes assignment to a previously declared variable
	← denotes a local binding (cannot be affected by subnodes)

<< You don't say anywhere, but I take it that { =, :, :=, ← } form the set of legal
modes.  The use of the term mode here is somewhat confusing; if I were an
Algol68 freak, I would have read "mode" as meaning "type" and have been led
astray. >>

Yes, these are the allowed "binding operators."  We used "binding" for a time,
but found that "mode" confused us less.  Any suggestions?

and op is in { <empty>, ', +, , *, /, AND, OR, <braces>, .<braces>, ... }
		(or BLANK, QUOTE, PLUS, MINUS, TIMES, DIVIDE, ... )
	<empty> binds to the current value of e
	' binds to the expression e
	+, , *, /, AND, OR, ... bind to the result of a binary operation
		between the current value of n and the current value of e
	<braces> bind to a nested environment containing only the bindings
		resulting from e
	.<braces> uses e to update the bindings in the environment bound to n


The semantics of scripts are defined by the following evaluation rules, where
	E denotes the environment transformation function
	V denotes the value function
	C denotes an environment, generally the "current" one
	C(id) denotes the value bound to id in C
	localMode(id, C) denotes the mode bound to id in C
		(NONE, if id isn't bound in C)
	(C | id←e, m) means "C with (e, m) bound to id"

<< I would put the brackets in here, i.e., (C | id ← <e,m>) >>

I'm responsible for editing out the brackets.  Since everything within the
parentheses has to be understood as a unit anyhow, these brackets are totally
redundant, and I thought they cluttered the equations more than they clarified
them.  Maybe I should reconsider; brevity isn't everything.

	E: expression > ( environment > environment )

	V: expression > ( environment > value )

	bindq: name, mode, value, environment > environment

<< Again, I would prefer
	bindq: [ name, (mode, value ] -> environment -> environment  >>

bindq, modeOf, apply, and insert are all auxiliary functions used purely within
the definitions of E and V.  Since they are always invoked with all arguments
supplied, I don't see the advantage of currying.  Please elaborate.

	modeOf: id, environment > mode

	apply: op, mode, value, environment > value

	insert: value, list > list

E[literal](C) = C

E[n](C) = if modeOf(n, C)=NONE then C else E[V[n](C)](C)

<<E[ V[n](C) ] is ill-formed; V produces a value, while E expects an expression. 
Don't confuse denotations and their meanings >>

The environment transformation denoted by a name is the one denoted by the
expression that has been bound to that name in the current environment, if
any.

E[quote(n)](C) = C

E[](C) = C								-- Basis
E[e1 e*](C) = E[e*](E[e1](C))					-- Composition

E[cond(e1, e2, e3)](C) = if V[e1](C) then E[e2](E[e1](C)) else E[e3](E[e1](C))

E[node(l, e)](C) = V[outer](E[e](nullEnv | outer←C, LOCAL))

<< I think there is some error in this equation, but I'm not sure what the fix is. 
The node label l does not appear in the right-hand side.. ? >>

Right, the labels on a node have no effect on the environment transformation it
denotes.

E[bind(n, m, op, e)](C) = bindq(n, m, apply(op, n, e, C), C)

<< Same problem as before -- bindq takes an expression as its third argument,
while apply delivers a value as its result >>

The value had better be an expression.  (Note the rules for V.)  We have
deliberately omitted specification of error cases to keep the equations simple.

E[{e}](C) = E[e](C)



V[literal](C) = literal

V[id](nullEnv) = id

<< Just curious -- looking up an identifier in an empty environment yields the
identifier??  Is this necessary because of other parts of the equations? >>

You read it correctly.  This is because the set of "primitives" with which editors
deal, such as Bold, Paragraph, and TimesRoman, is completely open-ended.  I.e.,
any identifier that isn't bound is treated as a primitive.

V[id](C) = if localMode(id, C)=NONE then V[id](C(outer)) else C(id)

<< How do I know that C(outer) yields an environment?  (Note that this makes
the value space reflexive:
	Env = Id -> Value
	Value = ... + Env ...)
If C(outer) is not an environment? >>

This rule is intended to "apply" only if V[id](nullEnv) = id doesn't.  I think
that you will find that each rule that creates a non-null environment binds
outer to an existing environment.

V[id.n](C) = V[n](V[id](C))

V[quote(e)](C) = e

V[] = NIL								-- Basis
V[e1 e*](C) = insert(V[e1](C), V[e*](E[e1](C)))		-- Composition

V[cond(e1, e2, e3)](C) = if V[e1](C) then V[e2](E[e1](C)) else V[e3](E[e1](C))

V[node(l, e)](C) = node(l, V[e](nullEnv | outer←C, LOCAL))

V[bind(n, m, op, e)](C) = NIL

V[{e}](C) = V[e](C) 


bindq(id, m, e, C) =
	modeOf(id, C)=CONST => C
	m=ASSIGN		 => 
		  { localMode(id, C)=VAR	=> (C | id←e, VAR)
		    modeOf(id, C)=VAR	=> bindq(outer.id, m, e, C)
		    T				=> C }
	T			 => (C | id←e, m)

bindq(id.n, m, e, C) = (C | id←bindq(n, m, e, V[id](C)), modeOf(id, C))

modeOf(n, nullEnv)=NONE
modeOf(id, C) = if localMode(id, C)=NONE then modeOf(id, C(outer))
			else localMode(id, C)
modeOf(id.n, C) = if localMode(id, C)=NONE then modeOf(id.n, C(outer))
			else modeOf(n, V[id](C))

<< Again, functionality problem -- V delivers a value, mode expects an
environment >>

The value bound to id in C must itself be an environment.  Should we call out
these error cases, at least in comments?

apply(op, n, e, C) =
	op=BLANK	=> V[e](C)
	op=QUOTE	=> e
	op=PLUS	=> V[n](C)+V[e](C)
	. . .
	op=BRACES	=>
			(E[e](nullEnv | outer←C, LOCAL) | outer←nullEnv, LOCAL)
	op=DOTBRACES =>
			(E[e](V[n](C) | outer←C, LOCAL) | outer←nullEnv, LOCAL)

-- insert(NIL, l) = l 



How semantics are associated with an entire document:

Each environment, C, initially contains only its "inherited" environment (bound
to the id "outer").  Most bindings take place directly in C.  However, the value
of a bindq(id, ASSIGN, e, C) will change C by rebinding id in the "innermost"
environment (following the chain of outers) in which it is bound, if that
binding has the mode VAR.

When an id is referred to and localMode(id, C)=NONE, then the value is sought
recursively in C(outer).  Perverse explicit bindings to outer might create loops,
leaving some ids undefined, but there seems to be little reason to clutter up the
semantics by forbidding such assignments.



Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

The low-level syntax for Interdocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some expression, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] expression* ")"
label ::= "#" id
expression ::= literal | ["'"] name | node | binding | conditional
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
binding ::= singleBinding | compoundBinding
singleBinding ::=  name mode rhs
mode ::= "=" | ":" | ":=" | "←"
rhs ::= [ op ] expression | ["."] compoundBinding
compoundBinding ::= "{" expression* "}"
op ::= "'" | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .
conditional ::= "IF(" expression "," expression [ "," expression ] ")"

Missing or in question:
	literal sequences
	relational operators



*start*
00397 00024 USt
Date: 23 July 1981 12:14 pm PDT (Thursday)
From: Haeberli.PA
Subject: BravoX External Format Documentation
To: Mitchell
cc: Haeberli

Jim,
In our conversation yesterday you expressed interest in the documentation for
BravoX External Format.

It can be found on:
[Ibis]<APS2>Documentation>ExternalFormat.press

Please let me know if you have any further questions.

Martin

*start*
01533 00024 US 
Date: 22 July 1981 1:12 pm PDT (Wednesday)
From: Horning.pa
Subject: FYI: BravoX
To: Mitchell, Reid

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

Date: 22 July 1981 1:07 pm PDT (Wednesday)
From: bott.PA
Subject: Re: BravoX Help system
In-reply-to: Horning's message of 22 July 1981 9:51 am PDT (Wednesday)
To: Horning
cc: Bott, Fiala, Lampson

Jim,
As far as I know, using BravoX on Dolphins still is not a working proposition: 
Bravox will occassionally trash the disk badly.  Given how difficult these disks
are to scavenge, this issue is serious.

The problem is a bug in the Dophin microcode.  I've heard a rumor that someone
in El Segundo might try to look into this, but there is no guarantee.  (As you
probably know, Xerox has dropped all support of BravoX.  This is regrettable in
my opinion, but there is nothing that I can do about it.)

However, BravoX is quite robust and very nice to use on a widebody Alto
(preferably 192 or 256K, but it will run in 128K).  If you have access to one of
these, I encourage you to give it a try.  The nearest satisfied user is probably
Brian Reid.  In addition, there is a fairly detailed Help system which I recently
wrote for BravoX which should make it learnable with very little startup time.  If
it turns out to be feasible for you to use BravoX, send me a message and I'll send
you details and command files for setting both BravoX and the help system up.

Ross

(PS: Tyronne Davis no longer works for Xerox.)

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

*start*
00759 00024 USt
Date: 28 July 1981 10:07 am PDT (Tuesday)
From: Horning.pa
Subject: Interdoc: Functionality of Expressions and Environments
To: Mitchell, Donahue
cc: Horning

Jims,

I am currently trying to see if I can get any mileage out of the following
"re-currying" of the functionalities:

MEnv[C]: Expression > Expression

MExp[e]: Environment > Environment

This is not "semantically" different from the V and E functions we wrote before,
but it perhaps gives a more intuitive perspective on what is happening: An
environment tells how to reduce an expression to one involving only "primitive"
identifiers; an expression generally produces a new environment for the subtree
to its right.

I'll let you know if anything comes of it.

Jim H.

*start*
06076 00024 USt
Date: 28 July 1981 3:45 pm PDT (Tuesday)
From: Mitchell.PA
Subject: Current Level 0/1 Interdoc status/rev. 9
To: Mitchell, Horning

We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, alternately
- reducing each expression to "primitives" by evaluating constant subexpressions
and replacing names by the values to which they are bound in the current
environment, and
- transforming the environment as indicated by the expressions.

Basic Interdoc

Expressions in an Interdoc script may denote
	literal values:
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anId, #Paragraph
		the empty environment: nullEnv
		the empty list: NIL
	environments
	unevaluated expressions

The "abstract syntax" of expressions involves the following constructors:
		-- by convention n: name, e: expression
	literal
	name: id ( "." id)*
	quote(e)
	compose(e1, e2)
	cond(e1, e2, e3)	-- if e1 then e2 else e3
	node(labels, e)
	bind(n, m, op, e)
where m is in { =, :, :=, ← } (or CONST, VAR, ASSIGN, LOCAL, respectively)
	= denotes constant binding
	: denotes variable declaration and initialization
	:= denotes assignment to a previously declared variable
	← denotes a local binding (cannot be affected by subnodes)
and op is in { <empty>, ', +, , *, /, AND, OR, <braces>, .<braces>, ... }
		(or BLANK, QUOTE, PLUS, MINUS, TIMES, DIVIDE, ... )
	<empty> binds to the current value of e
	' binds to the expression e
	+, , *, /, AND, OR, ... bind to the result of a binary operation
		between the current value of n and the current value of e
	<braces> bind to a nested environment containing only the bindings
		resulting from e
	.<braces> uses e to update the bindings in the environment bound to n


The semantics of scripts are defined by the following evaluation rules, where
	E denotes the environment transformation function
	V denotes the value function
	C denotes an environment, generally the "current" one
	C(id) denotes the value bound to id in C
	localMode(id, C) denotes the mode bound to id in C
		(NONE, if id isn't bound in C)
	(C | id←e, m) means "C with (e, m) bound to id"

	E: expression > ( environment > environment )

	V: expression > ( environment > value )

	bindq: name, mode, value, environment > environment

	modeOf: id, environment > mode

	apply: op, mode, value, environment > value

	insert: value, list > list

E[literal](C) = C

E[n](C) = if modeOf(n, C)=NONE then C else E[V[n](C)](C)

E[quote(n)](C) = C

E[](C) = C								-- Basis
E[e1 e*](C) = E[e*](E[e1](C))					-- Composition

E[IF(e1, e2, e3)](C) = if V[e1](C) then E[e2](E[e1](C)) else E[e3](E[e1](C))

E[node(l, e)](C) = V[outer](E[e](nullEnv | outer←C, CONST))

E[bind(n, m, op, e)](C) = bindq(n, m, apply(op, n, e, C), C)

E[{e}](C) = E[e](C)



V[literal](C) = literal

V[id](nullEnv) = id
V[id](C) = if localMode(id, C)=NONE then V[id](C(outer)) else C(id)
V[id.n](C) = V[n](V[id](C))

V[quote(n)](C) = n

V[] = NIL								-- Basis
V[e1 e*](C) = insert(V[e1](C), V[e*](E[e1](C)))		-- Composition

V[IF(e1, e2, e3)](C) = if V[e1](C) then V[e2](E[e1](C)) else V[e3](E[e1](C))

V[node(l, e)](C) = node(l, V[e](nullEnv | outer←C, CONST))

V[bind(n, m, op, e)](C) = NIL

V[{e}](C) = V[e](C) 


bindq(id, m, e, C) =
	modeOf(id, C)=CONST => C
	m=ASSIGN		 =>  assign(id, e, C)
	T			 => (C | id←e, m)

bindq(id.n, m, e, C) = (C | id←bindq(n, m, e, V[id](C)), modeOf(id, C))

modeOf(n, nullEnv)=NONE
modeOf(id, C) = if localMode(id, C)=NONE then modeOf(id, C(outer))
			else localMode(id, C)
modeOf(id.n, C) = if localMode(id, C)=NONE then modeOf(id.n, C(outer))
			else modeOf(n, V[id](C))

assign(id, e, C) = localMode(id, C)=VAR	=> (C | id←e, VAR)
		     modeOf(id, C)=VAR	=> bindq(outer.id, ASSIGN, e, C)
		     T				=> C 

apply(op, n, e, C) =
	op=BLANK	=> V[e](C)
	op=QUOTE	=> e
	op=PLUS	=> V[n](C)+V[e](C)
	. . .
	op=BRACES	=>
			(E[e](nullEnv | outer←C, CONST) | outer←nullEnv, CONST)
	op=DOTBRACES =>
			(E[e](V[n](C) | outer←C, CONST) | outer←nullEnv, CONST)

-- insert(NIL, l) = l 



How semantics are associated with an entire document:

Each environment, C, initially contains only its "inherited" environment (bound
to the id "outer").  Most bindings take place directly in C.  However, the value
of a bindq(id, ASSIGN, e, C) will change C by rebinding id in the "innermost"
environment (following the chain of outers) in which it is bound, if that
binding has the mode VAR.

When an id is referred to and localMode(id, C)=NONE, then the value is sought
recursively in C(outer).  Perverse explicit bindings to outer might create loops,
leaving some ids undefined, but there seems to be little reason to clutter up the
semantics by forbidding such assignments.



Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

The low-level syntax for Interdocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some expression, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] expression* ")"
label ::= "#" id
expression ::= literal | name | "'" name | conditional | node | binding |
		"{" expression* "}" 
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
binding ::= name mode [ op ] expression
mode ::= "=" | ":" | ":=" | "←"
op ::= "'" | "." | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .
conditional ::= "IF(" expression "," expression [ "," expression ] ")"

Missing or in question:
	literal sequences
	binary & relational operators
	quote expressions in general

*start*
08976 00024 USt
Date: 28 July 1981 7:49 pm PDT (Tuesday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 10
To: Mitchell, Horning
cc: Donahue

 Bring the syntax up front.
 Further develop parallelism between grammar and semantic equations.
 Quote general expressions.
 V, E, C > R, T, E .
 [...] > <...> for quotation of script expressions.
 (E | id←e, m) > [E | id←e, m] for local binding.


We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, alternately
- reducing each expression to "primitives" by evaluating constant subexpressions
and replacing names by the values to which they are bound in the current
environment, and
- transforming the environment as indicated by the expressions.

				BASIC INTERDOC

GRAMMAR

node ::= "(" labels expression* ")"
labels ::= [label* ":"]
label ::= "#" id
expression ::= literal | name | "'" expression | conditional | binding | node |
	"{" expression* "}" 
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
conditional ::= "IF(" expression "," expression [ "," expression ] ")"
binding ::= name mode op expression
mode ::= "=" | ":" | ":=" | "←"
op ::=   | "." | "+" | "-" | "*" | "/" | "AND" | "OR" | . . . 

SEMANTIC EQUATIONS

	R denotes the expression reduction function
	T denotes the environment transformation function
	E denotes an environment, generally the "current" one
	E(id) denotes the value bound to id in E
	localMode(id, E) denotes the mode bound to id in E
		(None, if id isn't bound in E)
	[E | id←e, m] means "E with (e, m) bound to id"

R: expression > ( environment > expression )
T: expression > ( environment > environment )

R<> = <>								-- Basis
R<e1 e*>(E) = <R<e1>(E) R<e*>(T<e1>(E))>			-- Composition

R<literal>(E) = <literal>

R<id>(NullEnv) = <id>
R<id>(E) = if localMode(id, E)=None then <R<id>(E(Outer))> else <E(id)>
R<id.n>(E) = <R<n>(R<id>(E))>

R<"'" e>(E) = <e>

R<"IF(" e1 "," e2 "," e3 ")">(E) =
	if R<e1>(E) then <R<e2>(T<e1>(E))> else <R<e3>(T<e1>(E))>

R<n m op e>(E) = <>

R<"(" labels e* ")">(E) = <"(" labels R<e*>([NullEnv | Outer←E, Const]) ")">

R<"{" e "}">(E) = <R<e>(E)>


T<>(E) = E								-- Basis
T<e1 e*>(E) = T<e*>(T<e1>(E))					-- Composition

T<literal>(E) = E

T<n>(E) = if modeOf(n, E)=None then E else T<R<n>(E)>(E)

T<"'" e>(E) = E

T<"IF(" e1 "," e2 "," e3 ")">(E) =
	if R<e1>(E) then T<e2>(T<e1>(E)) else T<e3>(T<e1>(E))

T<n m op e>(E) = bindq(n, m, apply(op, n, e, E), E)

T<"(" labels e* ")">(E) = R<Outer>(T<e>([NullEnv | Outer←E, Const]))

T<"{" e "}">(E) = T<e>(E)


modeOf(n, NullEnv) = None
modeOf(id, E) = if localMode(id, E)=None then modeOf(id, E(Outer))
			else localMode(id, E)
modeOf(id.n, E) = modeOf(n, R<id>(E))

bindq(id, m, e, E) =
	modeOf(id, E)=Const => E
	m=Assign		 => assign(id, e, E)
	True			 => [E | id←e, m]

bindq(id.n, m, e, E) = [E | id←bindq(n, m, e, R<id>(E)), modeOf(id, E)]

assign(id, e, E) = localMode(id, E)=Var	=> [E | id←e, Var]
		     modeOf(id, E)=Var	=> bindq(Outer.id, Assign, e, E)
		     True			=> E 

apply(op, n, e, E) =
	op=BLANK	=> R<e>(E)
	op=QUOTE	=> e
	op=PLUS	=> R<n>(E)+R<e>(E)
	. . .
	op=BRACES	=>
			[T<e>[NullEnv | Outer←E, Const] | Outer←NullEnv, Const]
	op=DOTBRACES =>
			[T<e>[R<n>(E) | Outer←E, Const] | Outer←NullEnv, Const]


Missing or in question:
	literal sequences
	binary & relational operators
	e.id?


-------------------
Expressions in an Interdoc script may denote
	literal values:
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anId, #Paragraph
		the empty environment: nullEnv
		the empty list: NIL
	environments
	unevaluated expressions

The "abstract syntax" of expressions involves the following constructors:
		-- by convention n: name, e: expression
	literal
	name: id ( "." id)*
	quote(e)
	compose(e1, e2)
	cond(e1, e2, e3)	-- if e1 then e2 else e3
	node(labels, e)
	bind(n, m, op, e)
where m is in { =, :, :=, ← } (or CONST, VAR, ASSIGN, LOCAL, respectively)
	= denotes constant binding
	: denotes variable declaration and initialization
	:= denotes assignment to a previously declared variable
	← denotes a local binding (cannot be affected by subnodes)
and op is in { <empty>, ', +, , *, /, AND, OR, <braces>, .<braces>, ... }
		(or BLANK, QUOTE, PLUS, MINUS, TIMES, DIVIDE, ... )
	<empty> binds to the current value of e
	' binds to the expression e
	+, , *, /, AND, OR, ... bind to the result of a binary operation
		between the current value of n and the current value of e
	<braces> bind to a nested environment containing only the bindings
		resulting from e
	.<braces> uses e to update the bindings in the environment bound to n


The semantics of scripts are defined by the following evaluation rules, where
	E denotes the environment transformation function
	V denotes the value function
	C denotes an environment, generally the "current" one
	C(id) denotes the value bound to id in C
	localMode(id, C) denotes the mode bound to id in C
		(NONE, if id isn't bound in C)
	(C | id←e, m) means "C with (e, m) bound to id"

	E: expression > ( environment > environment )

	V: expression > ( environment > value )

	bindq: name, mode, value, environment > environment

	modeOf: id, environment > mode

	apply: op, mode, value, environment > value

	insert: value, list > list

E[literal](C) = C

E[n](C) = if modeOf(n, C)=NONE then C else E[V[n](C)](C)

E[quote(n)](C) = C

E[](C) = C								-- Basis
E[e1 e*](C) = E[e*](E[e1](C))					-- Composition

E[IF(e1, e2, e3)](C) = if V[e1](C) then E[e2](E[e1](C)) else E[e3](E[e1](C))

E[node(l, e)](C) = V[outer](E[e](nullEnv | outer←C, CONST))

E[bind(n, m, op, e)](C) = bindq(n, m, apply(op, n, e, C), C)

E[{e}](C) = E[e](C)



V[literal](C) = literal

V[id](nullEnv) = id
V[id](C) = if localMode(id, C)=NONE then V[id](C(outer)) else C(id)
V[id.n](C) = V[n](V[id](C))

V[quote(n)](C) = n

V[] = NIL								-- Basis
V[e1 e*](C) = insert(V[e1](C), V[e*](E[e1](C)))		-- Composition

V[IF(e1, e2, e3)](C) = if V[e1](C) then V[e2](E[e1](C)) else V[e3](E[e1](C))

V[node(l, e)](C) = node(l, V[e](nullEnv | outer←C, CONST))

V[bind(n, m, op, e)](C) = NIL

V[{e}](C) = V[e](C) 


bindq(id, m, e, C) =
	modeOf(id, C)=CONST => C
	m=ASSIGN		 =>  assign(id, e, C)
	T			 => (C | id←e, m)

bindq(id.n, m, e, C) = (C | id←bindq(n, m, e, V[id](C)), modeOf(id, C))

modeOf(n, nullEnv)=NONE
modeOf(id, C) = if localMode(id, C)=NONE then modeOf(id, C(outer))
			else localMode(id, C)
modeOf(id.n, C) = if localMode(id, C)=NONE then modeOf(id.n, C(outer))
			else modeOf(n, V[id](C))

assign(id, e, C) = localMode(id, C)=VAR	=> (C | id←e, VAR)
		     modeOf(id, C)=VAR	=> bindq(outer.id, ASSIGN, e, C)
		     T				=> C 

apply(op, n, e, C) =
	op=BLANK	=> V[e](C)
	op=QUOTE	=> e
	op=PLUS	=> V[n](C)+V[e](C)
	. . .
	op=BRACES	=>
			(E[e](nullEnv | outer←C, CONST) | outer←nullEnv, CONST)
	op=DOTBRACES =>
			(E[e](V[n](C) | outer←C, CONST) | outer←nullEnv, CONST)

-- insert(NIL, l) = l 



How semantics are associated with an entire document:

Each environment, C, initially contains only its "inherited" environment (bound
to the id "outer").  Most bindings take place directly in C.  However, the value
of a bindq(id, ASSIGN, e, C) will change C by rebinding id in the "innermost"
environment (following the chain of outers) in which it is bound, if that
binding has the mode VAR.

When an id is referred to and localMode(id, C)=NONE, then the value is sought
recursively in C(outer).  Perverse explicit bindings to outer might create loops,
leaving some ids undefined, but there seems to be little reason to clutter up the
semantics by forbidding such assignments.



Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

The low-level syntax for Interdocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some expression, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] expression* ")"
label ::= "#" id
expression ::= literal | name | "'" name | conditional | node | binding |
		"{" expression* "}" 
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
binding ::= name mode [ op ] expression
mode ::= "=" | ":" | ":=" | "←"
op ::= "'" | "." | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .
conditional ::= "IF(" expression "," expression [ "," expression ] ")"
-------------------

*start*
07854 00024 USt
Date: 28 July 1981 12:32 pm PDT (Tuesday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 8
To: Mitchell, Donahue
cc: Horning

[Primarily, have a look at SECOND TRY.]

We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, alternately
- reducing each expression to "primitives" by evaluating constant subexpressions
and replacing names by the values to which they are bound in the current
environment, and
- transforming the environment as indicated by the expressions.

Basic Interdoc

Expressions in an Interdoc script may denote
	literal values:
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anId, #Paragraph
		the empty environment: nullEnv
		the empty list: NIL
	environments
	unevaluated expressions

The "abstract syntax" of expressions involves the following constructors:
		-- by convention n: name, e: expression
	literal
	name: id ( "." id)*
	quote(e)
	compose(e1, e2)
	cond(e1, e2, e3)	-- if e1 then e2 else e3
	node(labels, e)
	bind(n, m, op, e)
where m is in { =, :, :=, ← } (or CONST, VAR, ASSIGN, LOCAL, respectively)
	= denotes constant binding
	: denotes variable declaration and initialization
	:= denotes assignment to a previously declared variable
	← denotes a local binding (cannot be affected by subnodes)
and op is in { <empty>, ', +, , *, /, AND, OR, <braces>, .<braces>, ... }
		(or BLANK, QUOTE, PLUS, MINUS, TIMES, DIVIDE, ... )
	<empty> binds to the current value of e
	' binds to the expression e
	+, , *, /, AND, OR, ... bind to the result of a binary operation
		between the current value of n and the current value of e
	<braces> bind to a nested environment containing only the bindings
		resulting from e
	.<braces> uses e to update the bindings in the environment bound to n

 [FIRST TRY]
The semantics of scripts are defined by the following equations, where
	MEnv denotes the "meaning" of an environment
	MExp denotes the meaning" of an expression
	C denotes an environment, generally the "current" one

	MEnv: Environment > ( Expression > Expression )

	MExp: Expression > ( Environment > Environment )

	lookup: Name, Environment > Expression


MEnv(C)[literal] = literal

MEnv(C)[n] = lookup(n, C)

MEnv(C)[quote(e)] = e

MEnv(C)[] = NIL							      -- Basis
MEnv(C)[e1 e*] = insert(MEnv(C)[e1], MEnv[e*](MExp[e1](C)))  -- Composition


HALT-- THIS DOESN'T LOOK LIKE AN IMPROVEMENT


 [SECOND TRY]
TYPE Environment
OPERATORS
	null: > Environment
	bindq: Id, Mode, Expression, Environment > Environment
	enter: Environment > Environment
	exit: Environment > Environment
	lookup: Id, Environment > Expression
	bindable: Id, Mode, Environment > Boolean
	persistent: Id, Environment > Boolean
AXIOMS
	lookup(id, null) == id
	lookup(id, bindq(id', m, e, C)) == if id = id' and bindable(id', m, C)
		then e
		else lookup(id, C)
	lookup(id, enter(C)) == lookup(id, C)

	exit(null) == null		-- or "undefined"?
	exit(bindq(id, m, e, C)) == if m = ASSIGN and persistent(id, C)
		then bindq(id, m, e, exit(C))
		else exit(C)
	exit(enter(C)) == C

	bindable(id, m, null) == TRUE
	bindable(id, m, bindq(id', m', e, C)) == if id = id'
		then (m' ~= CONST) and (m = ASSIGN => m' = VAR) and
			bindable(id, CONST, C)
		else bindable(id, m, C)
	bindable(id, m, enter(C)) == bindable(id, m, C)

	persistent(id, null) == FALSE
	persistent(id, bindq(id', m', e, C)) == persistent(id, C) and
		(id = id' => m' = ASSIGN)
	persistent(id, enter(C)) == bindable(id, ASSIGN, C)



The semantics of scripts are defined by the following evaluation rules, where
	E denotes the environment transformation function
	V denotes the value function
	C denotes an environment, generally the "current" one
	C(id) denotes the value bound to id in C
	localMode(id, C) denotes the mode bound to id in C
		(NONE, if id isn't bound in C)
	(C | id←e, m) means "C with (e, m) bound to id"

	E: expression > ( environment > environment )

	V: expression > ( environment > value )

	bindq: name, mode, value, environment > environment

	modeOf: id, environment > mode

	apply: op, mode, value, environment > value

	insert: value, list > list

E[literal](C) = C

E[n](C) = if modeOf(n, C)=NONE then C else E[V[n](C)](C)

E[quote(n)](C) = C

E[](C) = C								-- Basis
E[e1 e*](C) = E[e*](E[e1](C))					-- Composition

E[cond(e1, e2, e3)](C) = if V[e1](C) then E[e2](E[e1](C)) else E[e3](E[e1](C))

E[node(l, e)](C) = V[outer](E[e](nullEnv | outer←C, LOCAL))

E[bind(n, m, op, e)](C) = bindq(n, m, apply(op, n, e, C), C)

E[{e}](C) = E[e](C)



V[literal](C) = literal

V[id](nullEnv) = id
V[id](C) = if localMode(id, C)=NONE then V[id](C(outer)) else C(id)
V[id.n](C) = V[n](V[id](C))

V[quote(e)](C) = e

V[] = NIL								-- Basis
V[e1 e*](C) = insert(V[e1](C), V[e*](E[e1](C)))		-- Composition

V[cond(e1, e2, e3)](C) = if V[e1](C) then V[e2](E[e1](C)) else V[e3](E[e1](C))

V[node(l, e)](C) = node(l, V[e](nullEnv | outer←C, LOCAL))

V[bind(n, m, op, e)](C) = NIL

V[{e}](C) = V[e](C) 


bindq(id, m, e, C) =
	modeOf(id, C)=CONST => C
	m=ASSIGN		 => 
		  { localMode(id, C)=VAR	=> (C | id←e, VAR)
		    modeOf(id, C)=VAR	=> bindq(outer.id, m, e, C)
		    T				=> C }
	T			 => (C | id←e, m)

bindq(id.n, m, e, C) = (C | id←bindq(n, m, e, V[id](C)), modeOf(id, C))

modeOf(n, nullEnv)=NONE
modeOf(id, C) = if localMode(id, C)=NONE then modeOf(id, C(outer))
			else localMode(id, C)
modeOf(id.n, C) = if localMode(id, C)=NONE then modeOf(id.n, C(outer))
			else modeOf(n, V[id](C))

apply(op, n, e, C) =
	op=BLANK	=> V[e](C)
	op=QUOTE	=> e
	op=PLUS	=> V[n](C)+V[e](C)
	. . .
	op=BRACES	=>
			(E[e](nullEnv | outer←C, LOCAL) | outer←nullEnv, LOCAL)
	op=DOTBRACES =>
			(E[e](V[n](C) | outer←C, LOCAL) | outer←nullEnv, LOCAL)

-- insert(NIL, l) = l 



How semantics are associated with an entire document:

Each environment, C, initially contains only its "inherited" environment (bound
to the id "outer").  Most bindings take place directly in C.  However, the value
of a bindq(id, ASSIGN, e, C) will change C by rebinding id in the "innermost"
environment (following the chain of outers) in which it is bound, if that
binding has the mode VAR.

When an id is referred to and localMode(id, C)=NONE, then the value is sought
recursively in C(outer).  Perverse explicit bindings to outer might create loops,
leaving some ids undefined, but there seems to be little reason to clutter up the
semantics by forbidding such assignments.



Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.



Interdoc Syntax:

The low-level syntax for Interdocs is the following (basically it represents the
dominant tree structure by the nonterminal "node", each of which can have
some set of labels, some expression, which may be actual data (the body of the
document), transformations on the environment, or subtrees:

node ::= "(" [label* ":"] expression* ")"
label ::= "#" id
expression ::= literal | ["'"] name | node | binding | conditional
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
binding ::= singleBinding | compoundBinding
singleBinding ::=  name mode rhs
mode ::= "=" | ":" | ":=" | "←"
rhs ::= [ op ] expression | ["."] compoundBinding
compoundBinding ::= "{" expression* "}"
op ::= "'" | "+" | "-" | "*" | "/" | "AND" | "OR" | . . .
conditional ::= "IF(" expression "," expression [ "," expression ] ")"

Missing or in question:
	literal sequences
	relational operators


*start*
05746 00024 USt
Date: 29 July 1981 7:46 pm PDT (Wednesday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 11
To: Mitchell, Horning
cc: Donahue

[This is shorter, more general, and I hope cleaner than previous versions. 
Numerous small bugs have been fixed as I tracked down subtleties.
I'd particularly like scrutiny of the equations involving nested environments,
marked by interior s.]

 Bring the syntax up front.
 Further develop parallelism between grammar and semantic equations.
 Quote general expressions.
 V, E, C > R, T, E .
 [...] > <...> for quotation of script expressions.
 (E | id←e, m) > [E | id←e, m] for local binding.
 Introduce primary to disambiguate expression* , factor lhs from binding.
 Introduce Sub component to initialize nodes.
 Debug (?) semantics of braces and dot.
 Mode > binding.


We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, alternately
- reducing each expression to "primitives" by evaluating constant subexpressions
and replacing names by the values to which they are bound in the current
environment, and
- transforming the environment as indicated by the expressions.

				BASIC INTERDOC

GRAMMAR

node ::= "(" labels expression* ")"
labels ::= [label* ":"]
label ::= "#" name
expression ::= [ lhs ] [ "'" ] primary	 
primary ::= literal | id | primary "." id | conditional | node | "{" expression* "}"
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
conditional ::= "IF(" expression "," expression [ "," expression ] ")"
lhs ::= name binding op
binding ::= "=" | ":" | ":=" | "←"
op ::=   | "." | "+" | "-" | "*" | "/" | "AND" | "OR" | . . . 

SEMANTICS

R denotes the expression reduction function:
	R: expression > ( environment > expression )

T denotes the environment transformation function:
	T: expression > ( environment > environment )

Environments bind expressions and "modes" to identifiers:
	Null denotes the "empty" environment
	[E | id←e, m] means "E with (e, m) bound to id"
	E(id) denotes the value bound to id in E
		Null(id) = id
		[E | id'←e, m](id) = if id=id' then e else E(id)
	locBinding(id, E) denotes the binding mode of id in E
		locBinding(id, Null) = None
		locBinding(id, [E | id'←e, m]) =
			if id=id' then m else locBinding(id, E)
		bound(id, E) = (locBinding(id, E) ~= None)

R<>(E) = ""								-- Basis
T<>(E) = E

R<e1 e*>(E) = R<e1>(E) R<e*>(T<e1>(E))				-- Composition
T<e1 e*>(E) = T<e*>(T<e1>(E))

R<"'" p>(E) = p
T<"'" p>(E) = E

R<literal>(E) = literal
T<literal>(E) = E

R<id>(E) =
	bound(id, E)		=> E(id)
	bound(Outer, E)	=> R<id>(E(Outer))
	True			=> id
T<id>(E) = if R<id>(E)=id then E else T<R<id>(E)>(E)

R<p "." id>(E) = R<id>(R<p>(E))
T<p "." id>(E) = T<R<p "." id>(E)>(E)

R<"IF(" e1 "," e2 "," e3 ")">(E) =
	if R<e1>(E) then R<e2>(T<e1>(E)) else R<e3>(T<e1>(E))
T<"IF(" e1 "," e2 "," e3 ")">(E) =
	if R<e1>(E) then T<e2>(T<e1>(E)) else T<e3>(T<e1>(E))

R<n m op p>(E) = ""
T<n m op p>(E) = bindq(n, m, apply(op, n, p, E), E)

R<"(" labels e* ")">(E) = "(" labels R<Sub e*>([Null | Outer←E, Const]) ")"
T<"(" labels e* ")">(E) = (T<Sub e*>([Null | Outer←E, Const]))(Outer)

R<"{" e* "}">(E) = [T<"{" e* "}">(E) | Outer←Null, Const] ?
T<"{" e* "}">(E) = T<e*>([Null | Outer←E, Const]) ?


bindingOf(id, E) =
	if ~bound(id, E) and bound(Outer, E) then bindingOf(id, E(Outer))
	else locBinding(id, E)

bindq(id, m, e, E) =
	bindingOf(id, E) = "="	=> E
	m = ":="			=> assign(id, e, E)
	True				=> [E | id←e, m]

bindq(id.n, m, e, E) = [E | id←bindq(n, m, e, R<id>(E)), bindingOf(id, E)]

assign(id, e, E) = locBinding(id, E) = ":"	=> [E | id←e, ":"]
		     bindingOf(id, E) = ":"	=> bindq(Outer.id, ":=", e, E)
		     True			=> E 

apply(op, n, p, E) =
	op = ""	=> R<p>(E)
	op = "." 	=> R<p>([R<n>(E) | Outer←E, Const]) ?
	op = "+"	=> R<n>(E)+R<p>(E)
	. . .


Missing or in question:
	literal sequences
	binary & relational operators

-------------------
Expressions in an Interdoc script may denote
	literal values:
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
		label: #A123, #anId, #Paragraph
		the empty environment: nullEnv
		the empty list: NIL
	environments
	unevaluated expressions


How semantics are associated with an entire document:

Each environment, E, initially contains only its "inherited" environment (bound
to the id Outer).  Most bindings take place directly in E.  However, the value
of a bindq(id, ":=", p, E) will change E by rebinding id in the "innermost"
environment (following the chain of Outers) in which it is bound, if that
binding has the binding ":" (Var).  Identifiers bound with binding "=" (Const)
may not be rebound in inner environments.

When an id is referred to and locBinding(id, E)=None, then the value is sought
recursively in E(Outer).  Perverse explicit bindings to outer might create loops,
leaving some ids undefined, but there seems to be little reason to clutter up the
semantics by forbidding such assignments.

The contents of each node are implicitly prefixed by Sub, which will generally
be bound to an environment transformation in the containing environment.

Braces create a nested environment; if preceded by a dot, it is initialized to the
value of the name in the binding.


Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.

*start*
06157 00024 USt
Date: 30 July 1981 6:49 pm PDT (Thursday)
From: Mitchell.PA
Subject: Current Level 0/1 Interdoc status/rev. 12
To: Mitchell, Horning
cc: Donahue

 Bring the syntax up front.
 Further develop parallelism between grammar and semantic equations.
 Write semantic equations in terms of concrete syntax.
 Quote general expressions.
 V, E, C > R, T, E .
 [...] > <...> for quotation of script expressions.
 (E | id←e, m) > [E | id←e, m] for local binding.
 Introduce primary to disambiguate expression* , factor lhs from binding.
 Introduce Sub component to initialize nodes.
 Debug semantics of braces and dot.
 Mode > binding.
 Debug semantics of <id> (fix up indirection).
 Add VAL. 


We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, alternately
- reducing each expression to "primitives" by evaluating constant subexpressions
and replacing names by the values to which they are bound in the current
environment, and
- transforming the environment as indicated by the expressions.

				BASIC INTERDOC

GRAMMAR

node ::= "(" labels expression* ")"
labels ::= [label* ":"]
label ::= "#" name
expression ::= [ lhs ] [ "'" ] primary	 
primary ::= literal | id | primary "." id | conditional | node |
	[ "VAL" ] "{" expression* "}"
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
conditional ::= "IF(" expression "," expression* [ "," expression* ] ")"
lhs ::= name binding op
binding ::= "=" | ":" | ":=" | "←"
op ::=   | "." | "+" | "-" | "*" | "/" | "AND" | "OR" | . . . 

SEMANTICS

R denotes the expression reduction function:
	R: expression > ( environment > expression )

T denotes the environment transformation function:
	T: expression > ( environment > environment )

Environments bind expressions and "modes" to identifiers:
	Null denotes the "empty" environment
	[E | id←e, m] means "E with (e, m) bound to id"
	E(id) denotes the value locally bound to id in E
		Null(id) = id
		[E | id'←e, m](id) = if id=id' then e else E(id)
	locBinding(id, E) denotes the binding mode of id in E
		locBinding(id, Null) = None
		locBinding(id, [E | id'←e, m]) =
			if id=id' then m else locBinding(id, E)

							-- Basis
R<>(E) = ""							-- Empty list
T<>(E) = E							-- Identity

							-- Expression sequence
R<e1 e*>(E) = R<e1>(E) R<e*>(T<e1>(E))			-- List insert
T<e1 e*>(E) = T<e*>(T<e1>(E))				-- Composition

R<"'" p>(E) = p
T<"'" p>(E) = E

R<literal>(E) = literal
T<literal>(E) = E

R<id>(E) = if valOf(id, E)=id then id else R<valOf(id, E)>(E)
T<id>(E) = if valOf(id, E)=id then E else T<valOf(id, E)>(E)

R<p "." id>(E) = R<id>(R<p>(E))
T<p "." id>(E) = if valOf(id, R<p>(E))=id then E else T<valOf(id, R<p>(E))>(E)

R<"IF(" e1 "," e2* "," e3* ")">(E) =
	if R<e1>(E) then R<e2*>(T<e1>(E)) else R<e3*>(T<e1>(E))
T<"IF(" e1 "," e2* "," e3* ")">(E) =
	if R<e1>(E) then T<e2*>(T<e1>(E)) else T<e3*>(T<e1>(E))

R<n m op p>(E) = ""						-- Empty list
T<n m op p>(E) = bindq(n, m, apply(op, n, p, E), E)

R<"(" labels e* ")">(E) = "(" labels R<Sub e*>([Null | Outer←E, Const]) ")"
T<"(" labels e* ")">(E) = (T<Sub e*>([Null | Outer←E, Const]))(Outer)

R<"{" e* "}">(E) = [T<"{" e* "}">(E) | Outer←Null, Const]
T<"{" e* "}">(E) = T<e*>([Null | Outer←E, Const])

R<"VAL{" e* "}">(E) = R<e*>(E)
T<"VAL{" e* "}">(E) = E


whereBound(id, E) =				-- Finds innermost binding
	locBinding(id, E) ~= None		=> E
	locBinding(Outer, E) ~= None	=> whereBound(id, E(Outer))
	True					=> Null

valOf(id, E) = (whereBound(id, E))(id)		-- Gets innermost value

bindingOf(id, E) = locBinding(id, whereBound(id, E)) -- Gets innermost binding

bindq(id, m, e, E) =
	bindingOf(id, E) = "="	=> E
	m = ":="			=> assign(id, e, E)
	True				=> [E | id←e, m]

bindq(id.n, m, e, E) = [E | id←bindq(n, m, e, R<id>(E)), bindingOf(id, E)]

assign(id, e, E) = locBinding(id, E) = ":"	=> [E | id←e, ":"]
		     bindingOf(id, E) = ":"	=> bindq(Outer.id, ":=", e, E)
		     True			=> E 

apply(op, n, p, E) =
	op = ""	=> R<p>(E)
	op = "." 	=> R<p>([R<n>(E) | Outer←E, Const])
	op = "+"	=> R<n>(E)+R<p>(E)
	. . .


Missing or in question:
	literal sequences
	binary & relational operators

-------------------
Expressions in an Interdoc script may denote
	literal values:
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		label: #A123, #anId, #Paragraph
		the empty environment: Null
		the empty list: NIL
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
			(unless bound, taken to denote a primitive)
	environments
	unevaluated expressions


How semantics are associated with an entire document:

Each environment, E, initially contains only its "inherited" environment (bound
to the id Outer).  Most bindings take place directly in E.  However, the value
of a bindq(id, ":=", p, E) will change E by rebinding id in the "innermost"
environment (following the chain of Outers) in which it is bound, if that
binding has the binding ":" (Var).  Identifiers bound with binding "=" (Const)
may not be rebound in inner environments.

When an id is referred to and locBinding(id, E)=None, then the value is sought
recursively in E(Outer).  Perverse explicit bindings to outer might create loops,
leaving some ids undefined, but there seems to be little reason to clutter up the
semantics by forbidding such assignments.

The contents of each node are implicitly prefixed by Sub, which will generally
be bound to an environment transformation in the containing environment.

Braces create a nested environment; if preceded by a dot, it is initialized to the
value of the name in the binding; if preceded by VAL, it is executed for value,
and the environment is then discarded.


Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.

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

*start*
06841 00024 USt
Date: 30 July 1981 9:55 pm PDT (Thursday)
From: Mitchell.PA
Subject: Current Level 0/1 Interdoc status/rev. 13
To: Mitchell, Horning


Last edited by Mitchell, 30 July 1981 9:21 pm PDT (Thursday):  Changed
grammar to allow more complete expression syntax; required changing CONST
binding op ("=") to "=="; couldn't use "<" or ">" as operators because they delimit
strings.  Moved history log to end of message.

We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, alternately
- reducing each expression to "primitives" by evaluating constant subexpressions
and replacing names by the values to which they are bound in the current
environment, and
- transforming the environment as indicated by the expressions.

				BASIC INTERDOC

GRAMMAR

node ::= "(" labels expression* ")"
labels ::= [label* ":"]
label ::= "#" name
expression ::= [ lhs ] [ "'" ] disjunction
disjunction ::= [ disjunction "OR" ] conjunction
conjunction ::= [ conjunction  "AND" ] negation
negation ::= [ "NOT" ] relation
relation ::= [ sum relOp ] sum
relOp ::= "LT" | " LE" | "EQ" | "NE" | "GE" | "GT"
sum ::= [ sum addOp ] product
addOp ::= "+" | "-"
product ::= [ product multOp ] primary
multOp ::= "*" | "/" | "MOD"
primary ::= literal | id | primary "." id | conditional | node |
		[ "VAL" ] "{" expression* "}" 
literal ::= Boolean | integer | hexint | real | string | label
name ::= id ( "." id)*
id ::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
conditional ::= "IF{" expression "," expression* [ "," expression* ] "}"
lhs ::= name binding op
binding ::= "==" | ":" | ":=" | "←"
op ::=   | "." | addOp | multOp 

a:='NOT VAL{leftMargin=120} r==12.5*pt IF{a=b, leftMargin←5, leftMargin←10}

SEMANTICS

R denotes the expression reduction function:
	R: expression > ( environment > expression )

T denotes the environment transformation function:
	T: expression > ( environment > environment )

Environments bind expressions and "modes" to identifiers:
	Null denotes the "empty" environment
	[E | id←e, m] means "E with (e, m) bound to id"
	E(id) denotes the value locally bound to id in E
		Null(id) = id
		[E | id'←e, m](id) = if id=id' then e else E(id)
	locBinding(id, E) denotes the binding mode of id in E
		locBinding(id, Null) = None
		locBinding(id, [E | id'←e, m]) =
			if id=id' then m else locBinding(id, E)

							-- Basis
R<>(E) = nothing						-- just what it says
T<>(E) = E							-- Identity

							-- Expression sequence
R<nothing e*>(E) = R<e*>(E)				-- "nothing" disappears
R<e1 e*>(E) = R<e1>(E) R<e*>(T<e1>(E))			-- List insert
T<e1 e*>(E) = T<e*>(T<e1>(E))				-- Composition

R<"'" p>(E) = p
T<"'" p>(E) = E

R<literal>(E) = literal
T<literal>(E) = E

R<id>(E) = if valOf(id, E)=id then id else R<valOf(id, E)>(E)
T<id>(E) = if valOf(id, E)=id then E else T<valOf(id, E)>(E)

R<p "." id>(E) = R<id>(R<p>(E))
T<p "." id>(E) = if valOf(id, R<p>(E))=id then E else T<valOf(id, R<p>(E))>(E)

R<"IF(" e1 "," e2* "," e3* ")">(E) =
	if R<e1>(E) then R<e2*>(T<e1>(E)) else R<e3*>(T<e1>(E))
T<"IF(" e1 "," e2* "," e3* ")">(E) =
	if R<e1>(E) then T<e2*>(T<e1>(E)) else T<e3*>(T<e1>(E))

R<n m op p>(E) = ""						-- Empty list
T<n m op p>(E) = bindq(n, m, apply(op, n, p, E), E)

R<"(" labels e* ")">(E) = "(" labels R<Sub e*>([Null | Outer←E, Const]) ")"
T<"(" labels e* ")">(E) = (T<Sub e*>([Null | Outer←E, Const]))(Outer)

R<"{" e* "}">(E) = [T<"{" e* "}">(E) | Outer←Null, Const]
T<"{" e* "}">(E) = T<e*>([Null | Outer←E, Const])

R<"VAL{" e* "}">(E) = R<e*>(E)
T<"VAL{" e* "}">(E) = E


whereBound(id, E) =				-- Finds innermost binding
	locBinding(id, E) ~= None		=> E
	locBinding(Outer, E) ~= None	=> whereBound(id, E(Outer))
	True					=> Null

valOf(id, E) = (whereBound(id, E))(id)		-- Gets innermost value

bindingOf(id, E) = locBinding(id, whereBound(id, E)) -- Gets innermost binding

bindq(id, m, e, E) =
	bindingOf(id, E) = "=="	=> E
	m = ":="			=> assign(id, e, E)
	True				=> [E | id←e, m]

bindq(id.n, m, e, E) = [E | id←bindq(n, m, e, R<id>(E)), bindingOf(id, E)]

assign(id, e, E) = locBinding(id, E) = ":"	=> [E | id←e, ":"]
		     bindingOf(id, E) = ":"	=> bindq(Outer.id, ":=", e, E)
		     True			=> E 

apply(op, lhs, rhs, E) =
	op = ""	=> R<rhs>(E)
	op = "." 	=> R<rhs>([R<lhs>(E) | Outer←E, Const])
	op = "+"	=> R<lhs>(E)+R<rhs>(E)
	. . .


Missing or in question:
	literal sequences
	binary & relational operators

-------------------
Expressions in an Interdoc script may denote
	literal values:
		Boolean: {F, T}
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		label: #A123, #anId, #Paragraph
		the empty environment: Null
		the empty list: NIL
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
			(unless bound, taken to denote a primitive)
	environments
	unevaluated expressions


How semantics are associated with an entire document:

Each environment, E, initially contains only its "inherited" environment (bound
to the id Outer).  Most bindings take place directly in E.  However, the value
of a bindq(id, ":=", p, E) will change E by rebinding id in the "innermost"
environment (following the chain of Outers) in which it is bound, if that
binding has the binding ":" (Var).  Identifiers bound with binding "==" (Const)
may not be rebound in inner environments.

When an id is referred to and locBinding(id, E)=None, then the value is sought
recursively in E(Outer).  Perverse explicit bindings to outer might create loops,
leaving some ids undefined, but there seems to be little reason to clutter up the
semantics by forbidding such assignments.

The contents of each node are implicitly prefixed by Sub, which will generally
be bound to an environment transformation in the containing environment.

Braces create a nested environment; if preceded by a dot, it is initialized to the
value of the name in the binding; if preceded by VAL, it is executed for value,
and the environment is then discarded.


Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.


Log of Changes

 Bring the syntax up front.
 Further develop parallelism between grammar and semantic equations.
 Write semantic equations in terms of concrete syntax.
 Quote general expressions.
 V, E, C > R, T, E .
 [...] > <...> for quotation of script expressions.
 (E | id←e, m) > [E | id←e, m] for local binding.
 Introduce primary to disambiguate expression* , factor lhs from binding.
 Introduce Sub component to initialize nodes.
 Debug semantics of braces and dot.
 Mode > binding.
 Debug semantics of <id> (fix up indirection).
 Add VAL. 


*start*
08096 00024 USt
Date: 30 July 1981 11:04 pm PDT (Thursday)
From: Mitchell.PA
Subject: First cut at some Interdoc level 2 issues - Comments appreciated
To: Horning
cc: Mitchell

Last Edited by Mitchell, 30 July 1981 11:01 pm PDT (Thursday)
Began to flesh out section on CONVENTIONS, esp. some standard definitions for
paragraphs, fonts, etc. and notions of editor-specific and interchange-standard
scripts.

			TOWARDS AN INTERCHANGE LANGUAGE
				FOR EDITABLE DOCUMENTS

INTRODUCTION
	* Rationale and background
	* Overview
	Scope
	Exclusions
	* Feasibility

* CONCEPTS AND GUIDING PRINCIPLES
	Descriptive with a procedural basis
	Maintaining document structure over edits
	Using limited editors on rich documents
	An open-ended standard

EXAMPLES [hardcopy, private representation, Interdoc script]
	Laurel message
	BravoX document with styles
	Star document with a bar chart, a simple curve, a table, or a form
	A GML example (from SIGOA paper)

THE BASE LANGUAGE
	Syntax
	Primitive and sequence data types and literals
	Labels and references

PROPERTIES
	Environments, names, and values
	Transformations: binding, definitions, and invocations
	Scope and persistence
	Standard properties

CONVENTIONS

Node Types:

From an editor's point of view, each node in an Interdoc script has a set of types
associated with it.  For example, a node might be a textDocument and a
LaurelMessage, meaning that it can be expected to have, roughly speaking, the
union of the attributes normally associated with a textDocument and a
LaurelMessage.  A type is associated with a node by adding a binding of the
form typeName=T to the attribute TYPE (which must be an environment) in the
local environment.  Thus, to assert that a node is both a textDocument and a
LaurelMessage, the following bindings would have to be done in the context of
the node:

	TYPE.textDocument←T
	TYPE.LaurelMessage←T

An editor can then determine all the types of a node by enumerating the TYPE
component of the node's environment.

Standard and Editor-Specific Renderings:

We need a two-level structure for documents expressed in the base language to
be both (a) interchangeable among different editors, and (b) retain information
of special significance to a specific editor.  Let us call (a) the interchange
standard information, or standard information and (b) editor-specific information.

Basically, an editor X is free to couch attributes in its own terms, which can
make it easy for it to consume an Interdoc script produced by itself, but it must
provide a set of mappings which will transform attributes into the interchange
standard.  The recommended method for doing this is to invoke its name as the
very first expression in any node that it has produced in its X-specific variant
(the rules for inheritance of properties mean that often only the root node of a
document will need to have this property, but there is nothing wrong with
nodes being in different editor-specific terms provided they invoke the
appropriate editor properties).  

Now, to be a valid standard script, the document must have the definition of X
placed in the script itself (Although there is nothing wrong with having
libraries of editor-specific -> standard mappings in a library of some sort to avoid
having copies of them in each script).  

When X parses an X-specific script, it will use its X-specific attributes and never
invoke the mappings from X-specific information to standard terms.  However,
when a document is to be interpreted by some other editor Y, any time it tries to
access a standard name, the mapping associated with that name will be invoked
to compute its value in terms of the X-specific values in the script.  What
guarantee is there that this can always be done?

It is worth noting first that we are speaking here of a script being interpreted by
an editor, rather than produced.  Consequently, it will never need to access
standard names in left-hand contexts; i.e., it need do no bindings that are not
part of the script in order to interpret it.  It may, however, need to access the
components of environments in order to map the script into its private format. 
These are always values in right-hand side contexts, and must be computed in
terms of the X-specific information that X put in the script.  We can examine this
issue on a case-by-case basis.  Below is a list of examples of possible
editor-specific uses of the base language and the mappings that would allow
another editor to treat the document in standard terms: 

Symbolic values used instead of numbers: supply standard values for the
symbolic values; e.g.,
Editor-specific:
	Paragraph.leading.betweenLines←single
mapping:
	'{single=2*pt}

Different names used for standard names: supply a binding to the standard name
from the editor-specific name using a quoted expression so that it is only
evaluated when needed in a right-hand side context; e.g.,
Editor-specific:
	Paragraph←.{
		Space←{
			BetweenLines←single
			BeforePara←double
			AfterPara←single
			}
		}
mapping:
	Paragraph←.{
		leading←.{
			betweenLines←'Paragraph.Space.BetweenLines
			beforePara ← 'Paragraph.Space.BeforePara
			afterPara ← 'Paragraph.Space.AfterPara
			}
		}

In general, one can use the facilities of the base language to write essentially
arbitrary programs that can, by being quoted, be bound to a standard identifier
to cause the appropriate value to be computed based on editor-specific
information put in the document by the editor that produced it.  Moreover, since
the mappings provided by editor X can be overridden in any subtree of the
document, an editor that does not "understand" some subtree of a document
produced by another editor Y can simply leave that subtree intact when
producing an edited version of the original script except to ensure that that
subtree's root node's first expression is an invocation of "Y", which will cause Y's
editor-specific mappings to obtain in that subtree.
 
	[Property definitions to be shared by various editor classes]
	Text
	Messages
	Standard External Environment:
UNITS: internally distances are kept in meters and angles are kept in degrees
	meter==1.0
	mica==1.E-5*meter
	inch==.0254*meter
	pt==inch/72.	-- actual Anglo/American standard is pt==.013837*inch
	pica==12*pt
	tenPitch==inch/10.
	twelvePitch==inch/12.

In general, the following definitions are not bound as CONST ("==") because it
seems perfectly reasonable to embellish them with other attributes.  The base
language doesn't allow one to delete bindings, so we are guaranteed that every
instance of a Font environment, for instance, will contain values for family,
face, size, and position.

Font←{
	family←ITCTiffany	-- a font name
	face←{
		weight←normal	-- IN {extralight light normal book demi
						medium semibold heavy bold black}
		slant←none		-- IN {none italic oblique}
		underlined←F
		smallCaps←F
		}
	size←10*pt			-- distance
	position←0		-- distance: rel. to baseline; for subscripting, etc.
       }

Paragraph←{TYPE.para←T
	margins←{
		left←1.*inch	-- distance
		right←7.5*inch	-- distance
		}
	alignment←flushLeft	-- IN {flushLeft centered flushRight}
	justified←F	-- Boolean
	leading←{
		betweenLines←1*pt	-- distance
		beforePara ← 12*pt	-- distance
		afterPara ← 0		-- distance
		}
	fonts←{		use SUB for this?
		normal←{Font.family←TimesRoman}
		emphasis1←{Font←normal Font.face.italic←T}
		emphasis2←{Font←normal Font.face.bold←T}
	       }
	hyphenation←F
	keep←NIL	-- IN {NIL, heading, start, continue, a distance} bX: 5.9
	}

Frame←{
	scale←{			-- default is the identity transformation
		X←1			-- expression
		Y←1			-- expression
	       }
	topMargin←1.0*inch	-- distance
	bottomMargin←1.0*inch	-- distance
	leftMargin←1.*inch		-- distance
	rightMargin←7.5*inch	-- distance
	transformation←'VAL{VAL{1 0 0} VAL{0 1 0} VAL {0 0 1}} ?
	}
	
	* Fonts and formats
	* Hierarchical documents
	* Styles
	XXX Graphics

PRAGMATICS
	* Private encodings and private representations
	XXX Conversion efficiency

XXX APPENDICES
	GLOSSARY
	FORMAL SEMANTIC DEFINITION
	RELATION TO OTHER STANDARDS

XXX INDEX
*start*
00808 00024 USt
Date: 31 July 1981 10:39 am PDT (Friday)
From: Horning.pa
Subject: Re: Current Level 0/1 Interdoc status/rev. 13
In-reply-to: Your message of 30 July 1981 9:55 pm PDT (Thursday)
To: Mitchell
cc: Horning

Jim,

Given the expected infrequency of Boolean expressions (or infix operators), I
guess I'm not enamoured of adding that much syntax for precedence. 
Left-to-right plus explicit bracketing will be OK.

I suggest instead

expression ::= [ lhs ] [ "'"  | "." | op ] primary

primary ::= literal | id | primary "." id | conditional | node |
		[ "VAL" ] "{" expression ( [ op ] expression )* "}" 

op ::= "+" | "" | "*" | "/" | "MOD" | "NOT" | "AND" | "OR" |
	"LT" | " LE" | "EQ" | "NE" | "GE" | "GT"

Note that since you use EQ, "=" is still available for Const binding.

Jim H.

*start*
07079 00024 USt
Date: 31 July 1981 4:28 pm PDT (Friday)
From: Mitchell.PA
Subject: Current Level 0/1 Interdoc status/rev. 14
To: Mitchell, Horning

Last edited by Mitchell, 31 July 1981 12:20 pm PDT (Friday)
Simplified expression syntax.  Expressions with embedded binary operators are
simply interpreted in a right-to-left fashion; e.g., x←a*b+c means x←a*(b+c). 
Fixed up semantic equations to reflect this.  Exchanged the use of {}s and ()s.

We envision an Interdoc script being processed in any manner equivalent to the
following:

Parse the script, alternately
- reducing each expression to "primitives" by evaluating constant subexpressions
and replacing names by the values to which they are bound in the current
environment, and
- transforming the environment as indicated by the expressions.

				BASIC INTERDOC

GRAMMAR

node	::= "{" labels expression* "}"
labels	::= [label* ":"]
label	::= "#" name
expression ::= [ lhs ] [ "'"  | "." | op ] rhs
rhs	::= [ "NOT" ] primary ( op primary )*
primary ::= literal | id | primary "." id | conditional | node |
	     [ "VAL" ] "(" expression* ")" 
literal	::= Boolean | integer | hexint | real | string | label
name	::= id ( "." id)*
id	::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
conditional ::= "IF(" expression "," expression* [ "," expression* ] ")"
lhs	::= name binding
binding ::= "=" | ":" | ":=" | "←"
op	::= "+" | "" | "*" | "/" | "MOD" | "AND" | "OR" |
	   "LT" | " LE" | "EQ" | "NE" | "GE" | "GT" 

SYNTACTIC EXAMPLES:

{#examplenode:
a:='NOT margins.left EQ 120 margins.left←100 r=12.5*pt
IF(a, leftMargin←+5, leftMargin←+10)
<text for this node>
}

SEMANTICS

R denotes the expression reduction function:
	R: expression > ( environment > expression )

T denotes the environment transformation function:
	T: expression > ( environment > environment )

Environments bind expressions and "modes" to identifiers:
	Null denotes the "empty" environment
	[E | id←e, m] means "E with (e, m) bound to id"
	E(id) denotes the value locally bound to id in E
		Null(id) = id
		[E | id'←e, m](id) = if id=id' then e else E(id)
	locBinding(id, E) denotes the binding mode of id in E
		locBinding(id, Null) = None
		locBinding(id, [E | id'←e, m]) =
			if id=id' then m else locBinding(id, E)

							-- Basis
R<>(E) = nothing						-- just what it says
T<>(E) = E							-- Identity

							-- Expression sequence
R<nothing e*>(E) = R<e*>(E)				-- "nothing" disappears
R<e1 e*>(E) = R<e1>(E) R<e*>(T<e1>(E))			-- List insert
T<e1 e*>(E) = T<e*>(T<e1>(E))				-- Composition

R<"'" p>(E) = p
T<"'" p>(E) = E

R<literal>(E) = literal
T<literal>(E) = E

R<id>(E) = if valOf(id, E)=id then id else R<valOf(id, E)>(E)
T<id>(E) = if valOf(id, E)=id then E else T<valOf(id, E)>(E)

R<p "." id>(E) = R<id>(R<p>(E))
T<p "." id>(E) = if valOf(id, R<p>(E))=id then E else T<valOf(id, R<p>(E))>(E)

R<"IF(" e1 "," e2* "," e3* ")">(E) =
	if R<e1>(E) then R<e2*>(T<e1>(E)) else R<e3*>(T<e1>(E))
T<"IF(" e1 "," e2* "," e3* ")">(E) =
	if R<e1>(E) then T<e2*>(T<e1>(E)) else T<e3*>(T<e1>(E))

R<p1 op p2>(E) = apply(op, p1, p2, E)
T<p1 op p2>(E) = E

R<"NOT" p>(E) = if R<p>(E)=True then False else True
T<"NOT" p>(E) = E

R<n m op e>(E) = nothing						-- Empty list
T<n m op e>(E) = bindq(n, m, apply(op, n, e, E), E)

R<"(" labels e* ")">(E) = "(" labels R<Sub e*>([Null | Outer←E, Const]) ")"
T<"(" labels e* ")">(E) = (T<Sub e*>([Null | Outer←E, Const]))(Outer)

R<"(" e* ")">(E) = [T<"(" e* ")">(E) | Outer←Null, Const]
T<"(" e* ")">(E) = T<e*>([Null | Outer←E, Const])

R<"VAL(" e* ")">(E) = R<e*>(E)
T<"VAL(" e* ")">(E) = E


whereBound(id, E) =				-- Finds innermost binding
	locBinding(id, E) ~= None		=> E
	locBinding(Outer, E) ~= None	=> whereBound(id, E(Outer))
	True					=> Null

valOf(id, E) = (whereBound(id, E))(id)		-- Gets innermost value

bindingOf(id, E) = locBinding(id, whereBound(id, E)) -- Gets innermost binding

bindq(id, m, e, E) =
	bindingOf(id, E) = "="	=> E
	m = ":="			=> assign(id, e, E)
	True				=> [E | id←e, m]

bindq(id.n, m, e, E) = [E | id←bindq(n, m, e, R<id>(E)), bindingOf(id, E)]

assign(id, e, E) = locBinding(id, E) = ":"	=> [E | id←e, ":"]
		     bindingOf(id, E) = ":"	=> bindq(Outer.id, ":=", e, E)
		     True			=> E 

apply(op, lhs, rhs, E) =
	op = ""	=> R<rhs>(E)
	op = "." 	=> R<rhs>([R<lhs>(E) | Outer←E, Const])
	op = "+"	=> R<lhs>(E)+R<rhs>(E)
	. . .


Missing or in question:
	literal sequences
	binary & relational operators

-------------------
Expressions in an Interdoc script may denote
	literal values:
		Boolean: (F, T)
		integer: ... -3, -2, -1, 0, 1, 2, 3, ...
		real: 1.2E5, . . .
		string: <this is a string>
		label: #A123, #anId, #Paragraph
		the empty environment: Null
		the empty list: NIL
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
			(unless bound, taken to denote a primitive)
	environments
	unevaluated expressions


How semantics are associated with an entire document:

Each environment, E, initially contains only its "inherited" environment (bound
to the id Outer).  Most bindings take place directly in E.  However, the value
of a bindq(id, ":=", p, E) will change E by rebinding id in the "innermost"
environment (following the chain of Outers) in which it is bound, if that
binding has the binding ":" (Var).  Identifiers bound with binding "=" (Const)
may not be rebound in inner environments.

When an id is referred to and locBinding(id, E)=None, then the value is sought
recursively in E(Outer).  Perverse explicit bindings to outer might create loops,
leaving some ids undefined, but there seems to be little reason to clutter up the
semantics by forbidding such assignments.

The contents of each node are implicitly prefixed by Sub, which will generally
be bound to an environment transformation in the containing environment.

Braces create a nested environment; if preceded by a dot, it is initialized to the
value of the name in the binding; if preceded by VAL, it is executed for value,
and the environment is then discarded.


Semantics of labels:

A label #id on a node in the dominant structure gives that node membership in
the set named by id.  Multiple labels place the node in multiple sets, and a
unique label on a node places it in a singleton set, i.e., identifies it uniquely.


				HISTORY LOG

 Bring the syntax up front.
 Further develop parallelism between grammar and semantic equations.
 Write semantic equations in terms of concrete syntax.
 Quote general expressions.
 V, E, C > R, T, E .
 [...] > <...> for quotation of script expressions.
 (E | id←e, m) > [E | id←e, m] for local binding.
 Introduce primary to disambiguate expression* , factor lhs from binding.
 Introduce Sub component to initialize nodes.
 Debug semantics of braces and dot.
 Mode > binding.
 Debug semantics of <id> (fix up indirection).
 Add VAL. 

Last edited by Mitchell, 30 July 1981 9:21 pm PDT (Thursday):  Changed
grammar to allow more complete expression syntax; couldn't use "<" or ">" as
operators because they delimit strings.  Moved history log to end of message.