*start*
05228 00024 USm
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*
04792 00024 USm
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*
05190 00024 USm
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 USm
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*
05044 00024 USm
Subject: Current Level 0/1 Interdoc status/rev. 4
To: Interdoc

[Incorporating corrections to the local errors noted during the meeting this afternoon.]

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
	expressions  -- (unevaluated) syntax given below

The "abstract syntax" of scripts involves the following constructors:
		-- by convention n: name, v: value, m: mode, e: expression
	literal
	name	-- id ( '. id)*
	quote(e)
	compose(e1, e2)
	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 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

	apply: op, mode, value, environment > value

	insert: value, list > list

	modeOf: id, environment > mode

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[bind(n, m, o, v)](C) = bindq(n, m, apply(o, n, v, C), C)

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

Compound binding, with & without "."


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[bind(n, m, o, v)](C) = NIL

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

Compound binding, with & without "."



bindq(id, m, v, C) =
	modeOf(id, C)=CONST => C
	m=ASSIGN		 => {
		    C<id>=VAR	=> (C | id←v, VAR)
		    C<id>=NONE and 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(o, n, v, C) =	o=BLANK	=> V[v](C)
			o=QUOTE	=> v
			o=PLUS	=> V[n](C)+V[v](C)
			. . .

/* 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*
05942 00024 USm
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*
08566 00024 USm
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 USm
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*
06264 00024 USm
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*
07854 00024 USm
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*
06076 00024 USm
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 USm
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*
05746 00024 USm
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 USm
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 USm
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*
00808 00024 USm
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*
04028 00024 USm
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*
07079 00024 USm
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.

*start*
07201 00024 US 
Date: 7 Aug. 1981 4:41 pm PDT (Friday)
From: Mitchell.PA
Subject: Current Level 0/1 Interdoc status/rev. 15
To: Mitchell, Horning

Last edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging 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.

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.
*start*
07956 00024 US 
Date: 13 Aug. 1981 5:36 pm PDT (Thursday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 16
To: Mitchell, Horning

[Jim,

I did a fair amount of doodling, primarily in an attempt to transform the semantic
equations to a form where their correctness will be "more nearly obvious."  Some
of the changes I like, but I'm not really wedded to any of them.]

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
In question:
	treatment of primitive identifiers
	side effects in expressions
	operations on nested environments: font←.(size←10)

Missing:
	literal sequences

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

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 |
	     [ "ENV" ] "(" 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 bindingMode
bindingMode ::= "=" | ":" | ":=" | "←"
op	::= "." | "+" | "" | "*" | "/" | "MOD" | "AND" | "OR" |
	   "LT" | " LE" | "EQ" | "NE" | "GE" | "GT" 

SYNTACTIC EXAMPLE:

{#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 identifiers to expressions, in various modes ("=", ":", ":=", "←"):
	Null denotes the "empty" environment
	[E | id m e] means "E with id mode m bound to e"
	locBinding(id, E) denotes the binding mode of id in E
		locBinding(id, Null) = None
		locBinding(id, [E | id' m e]) =
			if id=id' then m else locBinding(id, E)
	locVal(id, E) denotes the value locally bound to id in E,
			if locBinding(id, E) ~= None
		locVal(id, [E | id' m e]) = if id=id' then e else locVal(id, E)

N. B.
	T<construct>(E) = E , if no explicit value is given below.

							-- Basis
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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


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

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

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

bind(id, m, e, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":="			=> assign(id, e, E)	-- Assign at right level
	True				=> [E | id m e]

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

assign(id, e, E) = locBinding(id, E) = ":"	=> [E | id ":" e]
		     bindingOf(id, E) = ":"	=> bind("Outer".id, ":=", e, E)
		     True			=> E 		-- Can only assign to vars


-------------------
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 bind(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 locVal("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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.


*start*
00301 00024 USm
From: dawson.pa
Date: 14-Aug-81 15:23:11 PDT
Subject: DocumentInterchange↑.pa
To: Horning
cc: Dawson

I would like to add my name to this DL but can't using Maintain.
Maintain says it doesn't exist.  Is there a funny character in the
name, or has it gone away, or what?   John
*start*
07201 00024 USm
Date: 7 Aug. 1981 4:41 pm PDT (Friday)
From: Mitchell.PA
Subject: Current Level 0/1 Interdoc status/rev. 15
To: Mitchell, Horning

Last edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging 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.

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.
*start*
07956 00024 USm
Date: 13 Aug. 1981 5:36 pm PDT (Thursday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 16
To: Mitchell, Horning

[Jim,

I did a fair amount of doodling, primarily in an attempt to transform the semantic
equations to a form where their correctness will be "more nearly obvious."  Some
of the changes I like, but I'm not really wedded to any of them.]

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
In question:
	treatment of primitive identifiers
	side effects in expressions
	operations on nested environments: font←.(size←10)

Missing:
	literal sequences

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

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 |
	     [ "ENV" ] "(" 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 bindingMode
bindingMode ::= "=" | ":" | ":=" | "←"
op	::= "." | "+" | "" | "*" | "/" | "MOD" | "AND" | "OR" |
	   "LT" | " LE" | "EQ" | "NE" | "GE" | "GT" 

SYNTACTIC EXAMPLE:

{#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 identifiers to expressions, in various modes ("=", ":", ":=", "←"):
	Null denotes the "empty" environment
	[E | id m e] means "E with id mode m bound to e"
	locBinding(id, E) denotes the binding mode of id in E
		locBinding(id, Null) = None
		locBinding(id, [E | id' m e]) =
			if id=id' then m else locBinding(id, E)
	locVal(id, E) denotes the value locally bound to id in E,
			if locBinding(id, E) ~= None
		locVal(id, [E | id' m e]) = if id=id' then e else locVal(id, E)

N. B.
	T<construct>(E) = E , if no explicit value is given below.

							-- Basis
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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


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

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

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

bind(id, m, e, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":="			=> assign(id, e, E)	-- Assign at right level
	True				=> [E | id m e]

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

assign(id, e, E) = locBinding(id, E) = ":"	=> [E | id ":" e]
		     bindingOf(id, E) = ":"	=> bind("Outer".id, ":=", e, E)
		     True			=> E 		-- Can only assign to vars


-------------------
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 bind(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 locVal("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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.


*start*
08870 00024 USm
Date: 17 Aug. 1981 11:40 am PDT (Monday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 17
To: Mitchell, Horning

[Jim,

For discussion this afternoon.

Jim H.]

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

-------------------
In question:
	treatment of primitive identifiers (vs. labels)
	side effects in expressions (why only in conditionals?)
	operations on nested environments: font←.(size←10)
	merging environments
	reduced transformations

Missing:
	literal sequences
	operations on sequences (subscripting)

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

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 |
	     [ "ENV" ] "(" 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 bindingMode
bindingMode ::= "=" | ":" | ":=" | "←"
op	::= "." | "+" | "" | "*" | "/" | "MOD" | "AND" | "OR" |
	   "LT" | " LE" | "EQ" | "NE" | "GE" | "GT" 

SYNTACTIC EXAMPLE:

{#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 )

R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)
	R&T: ( expression, environment ) > ( expression, environment )

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


R&T<>(E) = ""; E

R&T<e1 e*>(E) = R<e1>(E) R<e*>(T<e1>(E)); T<e*>(T<e1>(E))

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

R&T<id>(E) = if bindingOf(id, E)=None then id; E else R&T<valOf(id, E)>(E)

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

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

R&T<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E ?]); E
	op = "+"	=> R<p1>(E)+R<p2>(E); E
	. . .

R&T<n m e>(E) 	= ""; bind(n, m, R<e>(E), E)
R&T<n m "'" e>(E) 	= ""; bind(n, m, e, E)
R&T<n m op e>(E) 	= ""; bind(n, m, R<n op e>(E), E)

R&T<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}";
			  locVal("Outer", (T<Sub e*>([Null | "Outer" = E])))

R&T<"(" e* ")">(E) = R<e*>(E); E

R&T<"ENV(" e* ")">(E) = [T<e*>(E) | "Outer" = Null]; T<e*>(E) ?


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

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

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

bind(id, m, e, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":="			=> assign(id, e, E)	-- Assign at right level
	True				=> [E | id m e]

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

assign(id, e, E) = locBinding(id, E) = ":"	=> [E | id ":" e]
		     bindingOf(id, E) = ":"	=> bind("Outer".id, ":=", e, E)
		     True			=> E 		-- Can only assign to vars


-------------------
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 bind(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 locVal("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.

Parentheses create a nested environment; if preceded by a dot, it is initialized to
the value of the name in the binding; if not preceded by ENV, 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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

*start*
09077 00024 USm
Date: 17 Aug. 1981 7:05 pm PDT (Monday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 18
To: Mitchell, Horning

[Jim,


Jim H.]

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

-------------------
In question:
	operations on nested environments: font←.(size←10)
	merging environments
	reduced transformations
	structured labels
	getEnv operator
	labels outside dominant structure
	non-printing nodes

Missing:
	operations on sequences and environments (subscripting and enumeration)
	substitution of  for Null, Nil, etc.

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

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	::= "{" expression* "}"
expression ::= [ lhs ] [ "'"  | op ] | name ":!"	-- :! for label declaration
rhs	::= [ "NOT" ] primary ( op primary )* 
primary ::= literal | id | primary "." id | conditional | node |
	     [ "ENV" ] "(" expression* ")" | label
literal	::= Boolean | integer | hexint | real | string | label
name	::= id ( "." id)*
id	::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
label	::= name "!"
conditional ::= "IF(" expression "," expression* [ "," expression* ] ")"
lhs	::= name bindingMode
bindingMode ::= "=" | ":" | ":=" | "←"
op	::= "." | "+" | "" | "*" | "/" | "MOD" | "AND" | "OR" |
	   "LT" | " LE" | "EQ" | "NE" | "GE" | "GT" 

SYNTACTIC EXAMPLE:

{node.example!
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 )

R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)
	R&T: ( expression, environment ) > ( expression, environment )

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


R&T<>(E) = ""; E

R&T<e1 e*>(E) = R<e1>(E) R<e*>(T<e1>(E)); T<e*>(T<e1>(E))

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

R&T<id>(E) = if bindingOf(id, E)=None then id; E else R&T<valOf(id, E)>(E)

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

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

R&T<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E ?]); E
	op = "+"	=> R<p1>(E)+R<p2>(E); E
	. . .

R&T<n m e>(E) 	= ""; bind(n, m, R<e>(E), E)
R&T<n m "'" e>(E) 	= ""; bind(n, m, e, E)
R&T<n m op e>(E) 	= ""; bind(n, m, R<n op e>(E), E)

R&T<"{" e* "}">(E) = "{" R<Sub e*>([Null | "Outer" = E]) "}";
			  locVal("Outer", (T<Sub e*>([Null | "Outer" = E])))

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

R&T<"ENV(" e* ")">(E) = [T<e*>(E) | "Outer" = Null]; T<e*>(E) ?


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

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

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

bind(id, m, e, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":="			=> assign(id, e, E)	-- Assign at right level
	True				=> [E | id m e]

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

assign(id, e, E) = locBinding(id, E) = ":"	=> [E | id ":" e]
		     bindingOf(id, E) = ":"	=> bind("Outer".id, ":=", e, E)
		     True			=> E 		-- Can only assign to vars


-------------------
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 bind(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 locVal("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.

Parentheses create a nested environment; if preceded by a dot, it is initialized to
the value of the name in the binding; ? if not preceded by ENV, 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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""


*start*
09690 00024 USm
Date: 19 Aug. 1981 9:58 am PDT (Wednesday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 19
To: Mitchell, Horning, Lampson


Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

-------------------
In question:
	subscripting: sequences, yes; nodes, labels, sets, environments, no
		evaluation of subscript expressions
	merging environments
	labels outside dominant structure
	non-printing nodes
	generalize apply to non-literal operands (distribute over sequences?)
	IF, NOT, apply when arguments are not literals, partial evaluation
	bind op in environment?

Missing:
	operations on sequences and environments (subscripting and enumeration)
	substitution of  for Null, Nil, etc.

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

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	::= "{" expression* "}"
expression ::= [ lhs ] [ "'" | op ] | name ":!"	-- :! for label declaration
rhs	::= [ "NOT" ] primary ( op primary )* 
primary ::= literal | id | primary "." id | conditional | node |
	     [ "ENV" ] "(" expression* ")" | label
literal	::= Boolean | integer | hexint | real | string | label
name	::= id ( "." id)*
id	::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
label	::= name "!"
conditional ::= "IF(" expression "," expression* [ "," expression* ] ")"
lhs	::= name bindingMode
bindingMode ::= "=" | ":" | ":=" | "←"
op	::= "%" | "+" | "" | "*" | "/" | "MOD" | "AND" | "OR" |
	   "LT" | " LE" | "EQ" | "NE" | "GE" | "GT" 

SYNTACTIC EXAMPLE:

{node.example!
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 )

R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)
	R&T: ( expression, environment ) > ( expression, environment )

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


R&T<>(E) = ""; E

R&T<e1 e*>(E) = R<e1>(E) R<e*>(T<e1>(E)); T<e*>(T<e1>(E))

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

R&T<id>(E) = if bindingOf(id, E)=None then id; E else R&T<valOf(id, E)>(E)

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

-- Subscript should go here

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

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

R&T<p1 "'" p2>(E)	= p2; E
R&T<p1 "%" p2>(E)	= R<p2>([R<p1>(E) | "Outer" = E]);
			 [T<p2>([R<p1>(E) | "Outer" = E]) | "Outer" = Null]
R&T<p1 op p2>(E)	= apply(R<p1>(E), op, R<p2>(E)); E

R&T<n m e>(E) = ""; bind(n, m, R<e>(E), E)
	<n m op e> = <n m n op e>			-- Syntactic sugar

R&T<"{" e* "}">(E) = "{" R<Sub e*>([Null | "Outer" = E]) "}";
			  locVal("Outer", (T<Sub e*>([Null | "Outer" = E])))

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


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

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

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

apply(arg1, op, arg2) =
	op = "+"	=> arg1+arg2
	. . .

bind(id, m, e, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, e, E)	-- Assign at right level
	True				=> [E | id m e]

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

assign(id, e, E) =
	locBinding(id, E) = ":"	=> [E | id ":" e]
	bindingOf(id, E) = ":"	=>
				[E | "Outer" "=" bind(id, ":=", e, locVal("Outer", E))]
	True				=> E 			-- Can only assign to vars


-------------------
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 bind(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 locVal("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.

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


Semantics of labels:

A label name! on a node gives that node membership in the sets identified by
name (and its prefixes); the "main" identifier of a set name must be declared at
the root of a subtree containing all its members.  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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes


*start*
10516 00024 USm
Date: 19 Aug. 1981 6:56 pm PDT (Wednesday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 20
To: Mitchell, Horning, Lampson


Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.

-------------------
In question:
	merging environments (OPEN)
	declaration of "main" labels
	labels outside dominant structure
	non-printing nodes (semicolon?)
	bind op names in environment?
		structured primitive names, naming authorities
	how to syntactically distinguish operator application
	infix vs. prefix for general operators (APL?)
	treatment of unbound qualified names
	 as id vs. binary op vs. sign on numbers

Missing:
	enumeration over sequences and environments
	substitution of  for Null, Nil, etc., as appropriate

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

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	::= "{" expression* "}"
expression ::= [ lhs ] rhs | name ":!"	-- :! for label declaration
rhs	::= [ "NOT" ] primary ( op primary )* 
primary ::= literal | id | primary "." id | conditional | node |
	     [ "ENV" ] "(" expression* ")"
literal	::= Boolean | integer | hexint | real | string | label | atom
name	::= id ( "." id)*
id	::= (letter | "" ) ( letter | "" | digit )*	-- "" is the null id
label	::= name "!"
atom	::= "$" id
conditional ::= "IF(" expression "," expression* [ "," expression* ] ")"
lhs	::= name bindingMode [  "'" | op ]
bindingMode ::= "=" | ":" | ":=" | "←"
op	::= "+" | "" | "*" | "/" | "MOD" | "AND" | "OR" |
	   "LT" | " LE" | "EQ" | "NE" | "GE" | "GT" | "SUB"

SYNTACTIC EXAMPLE:

{node.example!
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 )

R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)
	R&T: ( expression, environment ) > ( expression, environment )

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


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

R&T<id>(E) = if bindingOf(id, E)=None then "$" id; E else R&T<valOf(id, E)>(E)

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

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

R&T<"NOT" p>(E) = NOT R<p>(E); E

R&T<p1 "'" p2>(E)	= p2; E
R&T<p1 op p2>(E)	= apply(R<p1>(E), op, R<p2>(E)); E

R&T<n m e>(E) = ""; bind(n, m, R<e>(E), E)
	<n m op e> = <n m n op e>			-- Syntactic sugar

R&T<>(E) = ""; E

R&T<e1 e*>(E) = R<e1>(E) R<e*>(T<e1>(E)); T<e*>(T<e1>(E))

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

R&T<"ENV(" e* ")">(E) = [T<e*>([Null | "Outer" = E]) | "Outer" = Null]; E

R&T<"{" e* "}">(E) = "{" R<Sub e*>([Null | "Outer" = E]) "}";
			  locVal("Outer", (T<Sub e*>([Null | "Outer" = E])))

R&T<name ":!">(E) = 


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

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

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

apply(arg1, op, arg2) =
	op = "+"	=> arg1+arg2
	. . .
	op = "SUB"	=> arg1[arg2]

bind(id, m, e, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, e, E)	-- Assign at right level
	True				=> [E | id m e]

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

assign(id, e, E) =
	locBinding(id, E) = ":"	=> [E | id ":" e]
	bindingOf(id, E) = ":"	=>
				[E | "Outer" "=" bind(id, ":=", e, locVal("Outer", E))]
	True				=> E 			-- Can only assign to vars


-------------------
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		primitive properties and operators: $id
		the empty environment: Null
		the empty list: NIL
	unevaluated expressions
	environments
	sets (sequences) of nodes with given labels


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 bind(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 locVal("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 in the containing environment to a quoted expression performing an
environment transformation, and perhaps supplying some properties.

Parentheses are used purely for grouping (e.g., creating a sequence value for a
binding).  ENV is used to create a new environment, which behaves much like
a record.


Semantics of labels:

A label name! on a node gives that node membership in the sets identified by
name (and its prefixes); the "main" identifier of a set name must be declared at
the root of a subtree containing all its members.  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.


				OTHER NOTES

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its properties.
	(Variant: all properties on the path back to the root.)


				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 GENSYM IS AN EDITOR, NOT AN INTERCHANGE, FUNCTION.

 STANDARDIZE CONCEPTS, NOT NAMES.


				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

*start*
10548 00024 USm
Subject: Current Level 0/1 Interdoc status/rev. 21
To: Mitchell, Horning, Lampson


Edited by Jim H. on 20 Aug. 1981 1:27 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish between properties (marks) and labels.
	only the "main" id of a label is declared.
	eliminate  an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.

-------------------
In question:
	labels outside dominant structure
	non-printing nodes (semicolon?)
	bind op names in environment?
		structured primitive names, naming authorities
	treatment of unbound qualified names

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

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

item ::=  expression | binding | id ":!"	-- :! for label declaration
expression ::= id | expression "." id | literal | application | property | node 
id	::= letter ( letter | digit )*
literal	::= Boolean | integer | hexint | real | string | label | external
label	::= name "!"
name	::= id ( "." id)*
external ::= "$" name
application ::= ( op | expression ) "(" item*  ( "," item* )* ")"
op	::= "'" | "+" | "" | "*" | "/" 
property ::= expression "#"
node	::= "{" item* "}"
binding ::= name [ op ] bindingMode ( expression | "(" item* ")" )
bindingMode ::= "=" | ":" | ":=" | "←"

SYNTACTIC EXAMPLE:

{node.example!				-- Places this in node and node.example
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a nonstandard property
a:='(NOT(EQ(margins.left, 120))) margins.left←100 r=*(12.5,pt)
IF(a, margins.left+←5 margins.right←5, margins.left+←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 )

R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)
	R&T: ( expression, environment ) > ( expression, environment )

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


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

R&T<id>(E) = if bindingOf(id, E)=None then "$" id; E else R&T<valOf(id, E)>(E)

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

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

R&T<"NOT" p>(E) = NOT R<p>(E); E

R&T<p1 "'" p2>(E)	= p2; E
R&T<p1 op p2>(E)	= apply(R<p1>(E), op, R<p2>(E)); E

R&T<n m e>(E) = ""; bind(n, m, R<e>(E), E)
	<n m op e> = <n m n op e>			-- Syntactic sugar

R&T<>(E) = ""; E

R&T<e1 e*>(E) = R<e1>(E) R<e*>(T<e1>(E)); T<e*>(T<e1>(E))

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

R&T<"ENV(" e* ")">(E) = [T<e*>([Null | "Outer" = E]) | "Outer" = Null]; E

R&T<"{" e* "}">(E) = "{" R<Sub e*>([Null | "Outer" = E]) "}";
			  locVal("Outer", (T<Sub e*>([Null | "Outer" = E])))

R&T<name ":!">(E) = 


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

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

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

apply(arg1, op, arg2) =
	op = "+"	=> arg1+arg2
	. . .
	op = "SUB"	=> arg1[arg2]

bind(id, m, e, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, e, E)	-- Assign at right level
	True				=> [E | id m e]

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

assign(id, e, E) =
	locBinding(id, E) = ":"	=> [E | id ":" e]
	bindingOf(id, E) = ":"	=>
				[E | "Outer" "=" bind(id, ":=", e, locVal("Outer", E))]
	True				=> E 			-- Can only assign to vars


-------------------
		id:  (the null id), bold, thisIsAnId, Helvetica, . . .
Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		primitive properties and operators: $id
		the empty environment: Null
		the empty list: NIL
	unevaluated expressions
	environments
	sets (sequences) of nodes with given labels


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 bind(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 locVal("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 in the containing environment to a quoted expression performing an
environment transformation, and perhaps supplying some properties.

Parentheses are used purely for grouping (e.g., creating a sequence value for a
binding).  ENV is used to create a new environment, which behaves much like
a record.


Semantics of labels:

A label name! on a node gives that node membership in the sets identified by
name (and its prefixes); the "main" identifier of a set name must be declared at
the root of a subtree containing all its members.  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.


				OTHER NOTES

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its properties.
	(Variant: all properties on the path back to the root.)


				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 GENSYM IS AN EDITOR, NOT AN INTERCHANGE, FUNCTION.

 STANDARDIZE CONCEPTS, NOT NAMES.


				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.


*start*
11578 00024 USm
Date: 20 Aug. 1981 5:40 pm PDT (Thursday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 22
To: Mitchell, Horning, Lampson

[Jim,

I think I've fixed the syntax problems we discussed.  However, we should discuss
how palatable this syntax is--I made a number of relatively arbitrary decisions
for the sake of getting something definite as soon as possible.

Jim H.]


Edited by Jim H. on 20 Aug. 1981 5:29 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish syntactically between properties (marks) and labels.
	only the "main" id of a label is declarable.
	eliminate  as an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.
	update semantic equations for new grammar, etc.
	fix treatment of unbound qualified names (now produce Nil).

-------------------
Not done:
	State the formal semantics of labels and properties.

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

We envision an Interdoc script being input and viewed in any manner
equivalent to the following:

Parse the script, alternately
- reducing each expression to its "dominant structure," containing only literals,
by replacing identifiers by the values to which they are bound in the current
environment, by applying operators, and by removing binding items, and 
- transforming the environment as indicated by the binding items.

				BASIC INTERDOC

GRAMMAR

item ::=  primary | binding | id ":!"	-- :! for label declaration
primary ::= id | primary "." id | literal | application | property | node 
id	::= letter ( letter | digit )*
literal	::= Boolean | integer | hexint | real | string | label | external
label	::= name "!"
name	::= id ( "." id)*
external ::= "$" name
application ::= ( op | primary ) "(" item*  ( "," item* )* ")"
op	::= "'" | "+" | "" | "*" | "/" 
property ::= primary "#"
node	::= "{" item* "}"
binding ::= name [ op ] bindingMode ( primary | "(" item* ")" )
bindingMode ::= "=" | ":" | ":=" | "←"

SYNTACTIC EXAMPLE:

{Book.example!				-- Places this in Book and Book.example
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a nonstandard property
a:='(NOT(EQ(margins.left, 120))) margins.right←100 r=*(12.5, pt)
IF(a, margins.left+←5 margins.right←5, margins.left+←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 )

R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)
	R&T: ( expression, environment ) > ( expression, environment )

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


R&T<id>(E) = R&T<valOf(id, E)>(E)

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

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

R&T<op "(" arg* ")">(E) = operate(op, arg*, E)
R&T<p "(" arg* ")">(E) = operate(R<p>(E), arg*, E)

R&T<p "#">(E) = R<p>(E) "#"; E

R&T<"{" item* "}">(E) = "{" R<"Sub" item*>([Null | "Outer" = E]) "}";
			  locVal("Outer", (T<"Sub" item*>([Null | "Outer" = E])))

R&T<n m p>(E) = ""; bind(n, m, R<p>(E), E)
	<n op m p> = <n m op "(" n "," p ")" >			-- Syntactic sugar
	<n op m "(" arg* ")"> = <n m op "(" n "," arg* ")" >

R&T<"(" item* ")">(E) = R&T<item*>(E)

R&T<>(E) = ""; E

R&T<item1 item*>(E) = R<item1>(E) R<item*>(T<item1>(E));
			    T<item*>(T<item1>(E))

R&T<id ":!">(E) = 


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

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

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

operate(op, arg*, E) = 
	op = $QUOTE	=> arg*; E
	op = $HIDE		=> ""; E
	op = $ENV		=> [T<arg*>([Null | "Outer" = E]) | "Outer" = Null]; E
	True			=> apply(op, eval(arg*, E))

apply(op, val1, ... , valn) =
	op = $IF			=> if val1.R then val2 else val3
	op = "+" OR op = $PLUS 	=> val1.R + ... + valn.R; E
	...
	op = $LIST			=> val1
	op = $SUBSCRIPT		=> val1[val2.R]   -- val1: sequence, val2.R: int

eval("", E) = Nil
eval(arg1 arg*, E) = R&T<arg1>(E), eval(arg*, E)

bind(id, m, val, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, val, E)	-- Assign at right
level
	True				=> [E | id m val]

bind(id.n, m, val, E) = [E | id bindingOf(id, E) bind(n, m, val, R<id>(E))]

assign(id, val, E) =
	locBinding(id, E) = ":"	=> [E | id ":" val]
	bindingOf(id, E) = ":"	=>
				[E | "Outer" "=" bind(id, ":=", val, locVal("Outer", E))]
	True				=> E 			-- Can only assign to vars


-------------------
Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		external names: $name
		the empty environment: Null
		the empty list: NIL
	sequences of values
	unevaluated expressions
	environments
	sets (sequences) of nodes with given labels


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 bind(id, ":=", val, 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 locVal("Outer").  The (implicit) "outermost" environment binds
each id to the external name $id.

The contents of each node are implicitly prefixed by Sub, which will generally
be bound in the containing environment to a quoted expression performing an
environment transformation, and perhaps supplying some properties.

Parentheses are used for grouping (e.g., creating a sequence value for a
binding), and to delimit the argument list of an operator.  The operator $ENV is
used to create a new environment, which behaves much like a record.


Semantics of labels:

A label name! on a node gives that node membership in the sets identified by
name (and its prefixes); the "main" identifier of a set name must be declared at
the root of a subtree containing all its members.  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.


				OTHER NOTES

It should be clarified that the "view" of the dominant structure is ALWAYS
controlled by the properties of its nodes.  (E.g., text is not always there to be
"shown".)

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its (local) properties, and don't
remove any of them OR if you understand ALL properties of ALL nodes in the
path back to the root.

The presentation of this material could be clarified by a table that relates
constructions in the notation to their intended uses and meanings.

We should check our characterset for disjointness with Interpress.DoubtfulChars.


				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 GENSYM IS AN EDITOR, NOT AN INTERCHANGE, FUNCTION.

 STANDARDIZE CONCEPTS, NOT NAMES.


				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.


*start*
11654 00024 USm
Date: 21 Aug. 1981 6:58 pm PDT (Friday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 23
To: Mitchell, Horning, Lampson

Edited by Jim H. on 21 Aug. 1981 6:58 pm PDT (Friday).
	restore $val.
	move quoting to rhs, allow quoted primaries without parentheses.
	allow an op to be the rhs of a definition.
	eliminate the functions operate, apply, eval by back substitution.
	change semantics of () to allow "record" construction without $env.

-------------------
Not done:
	State the formal semantics of labels and properties.
	Sets of properties, etc. (Cf. Mitchell's Font example.)
	Sort out "records" vs. quoted bindings.

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

We envision an Interdoc script being input and viewed in any manner
equivalent to the following:

Parse the script, alternately
- reducing each expression to its "dominant structure," containing only literals,
by replacing identifiers by the values to which they are bound in the current
environment, by applying operators, and by removing binding items, and 
- transforming the environment as indicated by the binding items.

				BASIC INTERDOC

GRAMMAR

item		::= primary | binding
primary	::= id | primary "." id | literal | application | property | node 
id		::= letter ( letter | digit )*
literal		::= Boolean | integer | hexint | real | string | label | external
label		::= name "!"
name		::= id ( "." id)*
external	::= "$" name | op
op		::= "+" | "" | "*" | "/" 
application	::= primary "(" item*  ( "," item* )* ")"
property	::= primary "#"
node		::= "{" item* "}"
binding	::= name [ op ] bindingMode rhs | id ":!"
bindingMode ::= "=" | ":" | ":=" | "←"
rhs		::= [ "'" ] ( primary | "(" item* ")" )

SYNTACTIC EXAMPLE:

{Book.example!				-- Places this in Book and Book.example
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a nonstandard property
a:='NOT(EQ(margins.left, 120)) margins.right←100 r=*(12.5, pt)
IF(a, margins.left+←5 margins.right←5, margins.left+←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 )

R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)
	R&T: ( expression, environment ) > ( expression, environment )

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


R&T<id>(E) = R&T<valOf(id, E)>(E)

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

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

R&T<p "(" arg1 "," ... "," argn ")">(E) =
    CASE R<p>(E) OF
	$if		=> if R<arg1>(E) then R&T<arg2>(E) else R&T<arg3>(E)
	"+"	 	=> R<arg1>(E) + ... + R<argn>(E); E
	...
	$val		=> R<arg1>(E); E
	$list		=> R&T<arg1>(E)
	$sub		=> R&T<arg1>(E)[R<arg2>(E)]
					-- Subscript, arg1: sequence | node, arg2.R: int
	$hide		=> ""; E

R&T<p "#">(E) = R<p>(E) "#"; E

R&T<"{" item* "}">(E) = "{" R<"Sub" item*>([Null | "Outer" = E]) "}";
	      locVal("Outer", (T<"Sub" item*>([Null | "Outer" = E])))

R&T<>(E) = ""; E

R&T<item1 item*>(E) = R<item1>(E) R<item*>(T<item1>(E));
			    T<item*>(T<item1>(E))

R&T<n m rhs>(E) = ""; bind(n, m, R<rhs>(E), E)
	<n op m p> = <n m op "(" n "," p ")" >			-- Syntactic sugar
	<n op m "(" arg* ")"> = <n m op "(" n "," arg* ")" >

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

R&T<"(" item* ")">(E) = [T<item*>([Null | "Outer" = E]) | "Outer" = Null]; E
					-- Construct a "record" environment value

R&T<"'(" item* ")">(E) = item*; E

R&T<id ":!">(E) = ??; E


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

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

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

bind(id, m, val, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, val, E)	-- Assign at right
level
	True				=> [E | id m val]

bind(id "." n, m, val, E) = [E | id bindingOf(id, E) bind(n, m, val, R<id>(E))]

assign(id, val, E) =
	locBinding(id, E) = ":"	=> [E | id ":" val]
	bindingOf(id, E) = ":"	=>
				[E | "Outer" "=" bind(id, ":=", val, locVal("Outer", E))]
	True				=> E 			-- Can only assign to vars


-------------------
Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		external names: $name
		the empty environment: Null
		the empty list: NIL
	sequences of values
	unevaluated expressions
	environments
	sets (sequences) of nodes with given labels


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 bind(id, ":=", val, 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 locVal("Outer").  The (implicit) "outermost" environment binds
each id to the external name $id.

The contents of each node are implicitly prefixed by Sub, which will generally
be bound in the containing environment to a quoted expression performing an
environment transformation, and perhaps supplying some properties.

Parentheses are used for grouping (e.g., creating a sequence value for a
binding), and to delimit the argument list of an operator.  The operator $ENV is
used to create a new environment, which behaves much like a record.


Semantics of labels:

A label name! on a node gives that node membership in the sets identified by
name (and its prefixes); the "main" identifier of a set name must be declared at
the root of a subtree containing all its members.  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.


				OTHER NOTES

It should be clarified that the "view" of the dominant structure is ALWAYS
controlled by the properties of its nodes.  (E.g., text is not always there to be
"shown".)

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its (local) properties, and don't
remove any of them OR if you understand ALL properties of ALL nodes in the
path back to the root.

The presentation of this material could be clarified by a table that relates
constructions in the notation to their intended uses and meanings.

We should check our characterset for disjointness with Interpress.DoubtfulChars.


				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 GENSYM IS AN EDITOR, NOT AN INTERCHANGE, FUNCTION.

 STANDARDIZE CONCEPTS, NOT NAMES.


				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.

Edited by Jim H. on 20 Aug. 1981 5:29 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish syntactically between properties (marks) and labels.
	only the "main" id of a label is declarable.
	eliminate  as an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.
	update semantic equations for new grammar, etc.
	fix treatment of unbound qualified names (now produce Nil).


*start*
12386 00024 USm
Date: 24 Aug. 1981 6:42 pm PDT (Monday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 24
To: Mitchell, Horning

Edited by Jim H. on 24 Aug. 1981 6:08 pm PDT (Monday).
	"It's OK to edit a node if you understand ALL of its (local) properties, and
		either don't remove any of them or also understand ALL properties
		of its parent."
	"Put in contents if:				Put in environment if: ..."
	Add connection syntax to syntactically rule out a+←'b.


-------------------
Not done:
	Determine the (informal) semantics of labels.
	State the formal semantics of labels and properties.
	Sets of properties, etc. (Cf. Mitchell's Font example.)
		SET/LIST operators ($append $union ?)
		notation for list constants
	Sort out "records" vs. quoted bindings.
	Some syntactic marker to replace $env.
	Consider style for use of temporary local definitions.

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

We envision an Interdoc script being input and viewed in any manner
equivalent to the following:

Parse the script, alternately
- reducing each expression to its "dominant structure," containing only literals,
by replacing identifiers by the values to which they are bound in the current
environment, by applying operators, and by removing binding items, and 
- transforming the environment as indicated by the binding items.

				BASIC INTERDOC

GRAMMAR

item		::= primary | binding
primary	::= id | primary "." id | literal | application | property | node 
id		::= letter ( letter | digit )*
literal		::= Boolean | integer | hexint | real | string | label | external
label		::= name "!"
name		::= id ( "." id)*
external	::= "$" name | op
op		::= "+" | "" | "*" | "/" 
application	::= primary "(" item*  ( "," item* )* ")"
property	::= primary "#"
node		::= "{" item* "}"
binding	::= name connection rhs | id ":!"
connection	::= bindingMode | op bindingMode | bindingMode "'"
bindingMode ::= "=" | ":" | ":=" | "←"
rhs		::= primary | "(" item* ")"

SYNTACTIC EXAMPLE:

{Book.example!				-- Places this in Book and Book.example
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a property
a:='NOT(EQ(margins.left, 120)) margins.right←100 r=*(12.5, pt)
IF(a, margins.left+←5 margins.right←5, margins.left+←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 )

R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)
	R&T: ( expression, environment ) > ( expression, environment )

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


R&T<id>(E) = R&T<valOf(id, E)>(E)

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

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

R&T<p "(" arg1 "," ... "," argn ")">(E) =
    CASE R<p>(E) OF
	$if		=> if R<arg1>(E) then R&T<arg2>(E) else R&T<arg3>(E)
	"+"	 	=> R<arg1>(E) + ... + R<argn>(E); E
	...
	$val		=> R<arg1>(E); E
	$list		=> R&T<arg1>(E)
	$sub		=> R&T<arg1>(E)[R<arg2>(E)]
					-- Subscript, arg1: sequence | node, arg2.R: int
	$hide		=> ""; E

R&T<p "#">(E) = R<p>(E) "#"; E

R&T<"{" item* "}">(E) = "{" R<"Sub" item*>([Null | "Outer" = E]) "}";
	      locVal("Outer", (T<"Sub" item*>([Null | "Outer" = E])))

R&T<>(E) = ""; E

R&T<item1 item*>(E) = R<item1>(E) R<item*>(T<item1>(E));
			    T<item*>(T<item1>(E))

R&T<n m rhs>(E) = ""; bind(n, m, R<rhs>(E), E)
	<n op m p> = <n m op "(" n "," p ")" >			-- Syntactic sugar
	<n op m "(" arg* ")"> = <n m op "(" n "," arg* ")" >

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

R&T<"(" item* ")">(E) = [T<item*>([Null | "Outer" = E]) | "Outer" = Null]; E
					-- Construct a "record" environment value

R&T<"'(" item* ")">(E) = item*; E

R&T<id ":!">(E) = ??; E


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

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

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

bind(id, m, val, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, val, E)	-- Assign at right
level
	True				=> [E | id m val]

bind(id "." n, m, val, E) = [E | id bindingOf(id, E) bind(n, m, val, R<id>(E))]

assign(id, val, E) =
	locBinding(id, E) = ":"	=> [E | id ":" val]
	bindingOf(id, E) = ":"	=>
				[E | "Outer" "=" bind(id, ":=", val, locVal("Outer", E))]
	True				=> E 			-- Can only assign to vars


-------------------
Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		external names: $name
		the empty environment: Null
		the empty list: NIL
	sequences of values
	unevaluated expressions
	environments
	sets (sequences) of nodes with given labels


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 bind(id, ":=", val, 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 locVal("Outer").  The (implicit) "outermost" environment binds
each id to the external name $id.

The contents of each node are implicitly prefixed by Sub, which will generally
be bound in the containing environment to a quoted expression performing an
environment transformation, and perhaps supplying some properties.

Parentheses are used for grouping (e.g., creating a sequence value for a
binding), and to delimit the argument list of an operator.  The operator $ENV is
used to create a new environment, which behaves much like a record.


Semantics of labels:

A label name! on a node gives that node membership in the sets identified by
name (and its prefixes); the "main" identifier of a set name must be declared at
the root of a subtree containing all its members.  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.


				OTHER NOTES

It should be clarified that the "view" of the dominant structure is ALWAYS
controlled by the properties of its nodes.  (E.g., text is not always there to be
"shown".)

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its (local) properties, and either
don't remove any of them or also understand ALL properties of its parent.

The presentation of this material could be clarified by a table that relates
constructions in the notation to their intended uses and meanings.

We should check our characterset for disjointness with Interpress.DoubtfulChars.

Put in contents if:				Put in environment if:
	effect is local to node			has scope
	is directly edited				is only indirectly edited
	is to be bound locally			needs delayed or global binding


				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 GENSYM IS AN EDITOR, NOT AN INTERCHANGE, FUNCTION.

 STANDARDIZE CONCEPTS, NOT NAMES.


				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.

Edited by Jim H. on 20 Aug. 1981 5:29 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish syntactically between properties (marks) and labels.
	only the "main" id of a label is declarable.
	eliminate  as an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.
	update semantic equations for new grammar, etc.
	fix treatment of unbound qualified names (now produce Nil).

Edited by Jim H. on 21 Aug. 1981 6:58 pm PDT (Friday).
	restore $val.
	move quoting to rhs, allow quoted primaries without parentheses.
	allow an op to be the rhs of a definition.
	eliminate the functions operate, apply, eval by back substitution.
	change semantics of () to allow "record" construction without $env.


*start*
13389 00024 USm
Date: 25 Aug. 1981 11:34 am PDT (Tuesday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 25
To: Mitchell, Horning

Edited by Jim H. on 25 Aug. 1981 11:33 am PDT (Tuesday).
	Syntactically separate label references and name invocation.
	Put in distinct syntax in rhs for environment construction.
	Informal semantics of labels.
	( ... ) > [ ... ] in applications; permitting ( ... ) as a primary.

-------------------
Open questions:
	Use of ( ... ) vs. [ ... ] (especially in application).
	Sort out "records" vs. quoted bindings.
	Sets of properties, etc. (Cf. Mitchell's Font example.)
		SET/LIST operators ($append $union ?)
		semantics of $list
	Non-uniform semantics of quote.
		Subtle distinctions between quoted and unquoted ( ... )
		Semantics of quoted [ ... ] ?
	We should check our characterset for disjointness with
		Interpress.DoubtfulChars.


Not done:
	State the formal semantics of labels and properties.
	Consider style for use of temporary local definitions.

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

We envision an Interdoc script being input and viewed in any manner
equivalent to the following:

Parse the script, repeatedly
- reducing each expression to its "dominant structure," containing only literals,
by replacing identifiers by the values to which they are bound in the current
environment, by applying operators, and by removing binding items,
- transforming the environment as indicated by the binding items, and
- recording the links indicated by label references and marks.

				BASIC INTERDOC

SYNTACTIC EXAMPLE:

{Book.example!		      -- Links to this from Book@ and Book.example@
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a property
a:='NOT[EQ[margins.left, 120]] margins.right←100 r=*[12.5, pt]
IF[a, margins.left+←5 margins.right←5, margins.left+←10]
<text for this node>
}

GRAMMAR

item		::= primary | binding | label
primary	::= literal | invocation | application | property | node | "(" item* ")"
literal		::= Boolean | integer | hexint | real | string | external | op
external	::= "$" name
name		::= id ( "." id)*
id		::= letter ( letter | digit )*
op		::= "+" | "" | "*" | "/"
invocation	::= id | primary "." id
application	::= primary "[" item*  ( "," item* )* "]"
property	::= primary "#"
node		::= "{" item* "}"
binding	::= name connection rhs
connection	::= bindingMode | op bindingMode | bindingMode "'"
bindingMode ::= "=" | ":" | ":=" | "←"
rhs		::= primary | "[" item* "]"
label		::= id ":!" | name "!" | name "@"

SEMANTICS

R&T<id>(E) = R&T<valOf(id, E)>(E)

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

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

R&T<p "(" arg1 "," ... "," argn ")">(E) =
    CASE R<p>(E) OF
	$if		=> if R<arg1>(E) then R&T<arg2>(E) else R&T<arg3>(E)
	"+"	 	=> R<arg1>(E) + ... + R<argn>(E); E
	...
	$val		=> R<arg1>(E); E
	$list		=> R&T<arg1>(E)
	$subscript	=> R&T<arg1>(E)[R<arg2>(E)]
						-- arg1: sequence | node, arg2.R: int
	$hide		=> "" ; E

R&T<p "#">(E) = R<p>(E) "#"; E

R&T<"{" item* "}">(E) = "{" R<"Sub" item*>([Null | "Outer" = E]) "}";
	      locVal("Outer", (T<"Sub" item*>([Null | "Outer" = E])))

R&T<"(" item* ")">(E) = "(" R<item*>(E) ")" ; E			-- List constructor

R&T<"[" item* "]">(E) = [T<item*>([Null | "Outer" = E]) | "Outer" = Null]; E
					-- Construct a "record" environment value

R&T<>(E) = ""; E

R&T<item1 item*>(E) = R<item1>(E) R<item*>(T<item1>(E));
			    T<item*>(T<item1>(E))

R&T<n m rhs>(E) = "" ; bind(n, m, R<rhs>(E), E)
	<n op m rhs> = <n m op "(" n "," rhs ")">		-- Syntactic sugar
	<n op m "(" arg* ")"> = <n m op "(" n "," arg* ")">

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

R&T<"'(" item* ")">(E) = item*; E  ??

R&T<"'[" item* "]">(E) = ??

R&T<label>(E) = label; E


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

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

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

bind(id, m, val, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, val, E)	-- Assign at right
level
	True				=> [E | id m val]

bind(id "." n, m, val, E) = [E | id bindingOf(id, E) bind(n, m, val, R<id>(E))]

assign(id, val, E) =
	locBinding(id, E) = ":"	=> [E | id ":" val]
	bindingOf(id, E) = ":"	=>
				[E | "Outer" "=" bind(id, ":=", val, locVal("Outer", E))]
	True				=> E 			-- Can only assign to vars


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

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

R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)
	R&T: ( expression, environment ) > ( expression, environment )

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


-------------------
Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		external names: $name
		the empty environment: Null
		the empty list: NIL
	sequences of values
	unevaluated expressions
	environments
	sets (sequences) of nodes with given labels


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 bind(id, ":=", val, 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 locVal("Outer").  The (implicit) "outermost" environment binds
each id to the external name $id.

The contents of each node are implicitly prefixed by Sub, which will generally
be bound in the containing environment to a quoted expression performing an
environment transformation, and perhaps supplying some properties.

Parentheses are used for grouping (e.g., creating a sequence value for a
binding), and to delimit the argument list of an operator.  The operator $ENV is
used to create a new environment, which behaves much like a record.


Semantics of labels:

A mark name! on a node makes that node a "target" of the label name (and its
prefixes); a reference name@ makes it a "source."  The "main" identifier of a
label must be declared (using name:!) at the root of a subtree containing all its
sources and targets.  The label represents a set of directed arcs, one from each of
its sources to each of its destinations.  Multiple marks make the node a target of
in multiple labels.  A unique label on a node places it in a singleton set, i.e.,
identifies it uniquely.


				OTHER NOTES

It should be clarified that the "view" of the dominant structure is ALWAYS
controlled by the properties of its nodes.  (E.g., text is not always there to be
"shown".)

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its (local) properties, and either
don't remove any of them or also understand ALL properties of its parent.
-It's OK to copy a node if that doesn't move any labels outside their scope, and
you understand ALL properties of its new parent.
-it's OK to delete a (subtree rooted at a) node if you understand ALL properties
of its parent.

The presentation of this material could be clarified by a table that relates
constructions in the notation to their intended uses and meanings.

Put in contents if:				Put in environment if:
	effect is local to node			has scope
	is directly edited				is only indirectly edited
	is to be bound locally			needs delayed or global binding


				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 GENSYM IS AN EDITOR, NOT AN INTERCHANGE, FUNCTION.

 STANDARDIZE CONCEPTS, NOT NAMES.


				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.

Edited by Jim H. on 20 Aug. 1981 5:29 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish syntactically between properties (marks) and labels.
	only the "main" id of a label is declarable.
	eliminate  as an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.
	update semantic equations for new grammar, etc.
	fix treatment of unbound qualified names (now produce Nil).

Edited by Jim H. on 21 Aug. 1981 6:58 pm PDT (Friday).
	restore $val.
	move quoting to rhs, allow quoted primaries without parentheses.
	allow an op to be the rhs of a definition.
	eliminate the functions operate, apply, eval by back substitution.
	change semantics of () to allow "record" construction without $env.

Edited by Jim H. on 24 Aug. 1981 6:08 pm PDT (Monday).
	"It's OK to edit a node if you understand ALL of its (local) properties, and
		either don't remove any of them or also understand ALL properties
		of its parent."
	"Put in contents if:				Put in environment if: ..."
	Add connection syntax to syntactically rule out a+←'b.


*start*
14892 00024 USm
Date: 25 Aug. 1981 4:08 pm PDT (Tuesday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 26
To: Mitchell, Horning

Edited by Jim H. on 25 Aug. 1981 4:08 pm PDT (Tuesday).
	Add sequence as a nonterminal to the syntax.
	State the formal semantics of labels and properties.
	Reorder presentation (hopefully to improve readability).

-------------------
Open questions:
	Use of ( ... ) vs. [ ... ] (especially in application).
	Sort out "records" vs. quoted bindings.
	Sets of properties, etc. (Cf. Mitchell's Font example.)
		SET/LIST operators ($append $union ?)
		semantics of $list
	Non-uniform semantics of quote.
		Subtle distinctions between quoted and unquoted ( ... )
		Semantics of quoted [ ... ] ?
	We should rethink our character assignments.
		check our characterset for disjointness with
			Interpress.DoubtfulChars.
		use of various bracket pairs.
		enlarge op with a few more single-character operators?
	Possible node operators (purely in semantic domain, not operators?).
		$properties: node, environment > sequence	-- All #'s
		$marks: node, environment > sequence		-- All !'s
		$references: node, environment > sequence	-- All @'s
		$contents: node, environment > sequence	-- The rest (fringe)
	Consider restricting $subscript just to sequences, not nodes.
	Note that $if is the only operator that requires multiple sequences (hence
		commas, different syntax for argument list and sequence).  Worth
		going back to treating it as a special case?


Not done:
	Consider style for use of temporary local definitions.

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

We envision an Interdoc script being input and viewed in any manner
equivalent to the following:

Parse the script, repeatedly
- reducing each expression to its "dominant structure," containing only literals,
by replacing identifiers by the values to which they are bound in the current
environment, by applying operators, and by removing binding items,
- transforming the environment as indicated by the binding items, and
- recording the links indicated by label references and marks.

				BASIC INTERDOC

SYNTACTIC EXAMPLE:

{Book.example!		      -- Links to this from Book@ and Book.example@
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a property
a:='NOT[EQ[margins.left, 120]] margins.right←100 r=*[12.5, pt]
IF[a, margins.left+←5 margins.right←5, margins.left+←10]
<text for this node>
}

GRAMMAR

item		::= primary | binding | label
primary	::= literal | invocation | application | property | node | sequence
literal		::= Boolean | integer | hexint | real | string | external | op
external	::= "$" name
name		::= id ( "." id)*
id		::= letter ( letter | digit )*
op		::= "+" | "" | "*" | "/"
invocation	::= id | primary "." id
application	::= primary "[" item*  ( "," item* )* "]"
property	::= primary "#"
node		::= "{" item* "}"
sequence	::= "(" item* ")"
binding	::= name connection rhs
connection	::= bindingMode | op bindingMode | bindingMode "'"
bindingMode ::= "=" | ":" | ":=" | "←"
rhs		::= primary | "[" item* "]"
label		::= id ":!" | name "!" | name "@"

SEMANTICS

R: expression > environment > expression			-- Reduction
T: expression > environment > environment			-- Transformation
R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)

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

R&T<id>(E) = R&T<valOf(id, E)>(E)

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

R&T<p "[" arg1 "," ... "," argn "]">(E) =
    CASE R<p>(E) OF
	$if		=> if R<arg1>(E) then R&T<arg2>(E) else R&T<arg3>(E)
	"+"	 	=> R<arg1>(E) + ... + R<argn>(E); E
	...
	$val		=> R<arg1>(E); E
	$list		=> R&T<arg1>(E)
	$subscript	=> R&T<arg1>(E)[R<arg2>(E)]
						-- arg1: sequence | node, arg2.R: int
	$hide		=> "" ; E

R&T<p "#">(E) = R<p>(E) "#"; E

R&T<"{" item* "}">(E) = "{" R<"Sub" item*>([Null | "Outer" = E]) "}";
	      locVal("Outer", (T<"Sub" item*>([Null | "Outer" = E])))

R&T<"(" item* ")">(E) = "(" R<item*>(E) ")" ; E			-- List constructor

R&T<"[" item* "]">(E) = [T<item*>([Null | "Outer" = E]) | "Outer" = Null]; E
					-- Construct a "record" environment value

R&T<>(E) = ""; E

R&T<item1 item*>(E) = R<item1>(E) R<item*>(T<item1>(E));
			    T<item*>(T<item1>(E))

R&T<n m rhs>(E) = "" ; bind(n, m, R<rhs>(E), E)
	<n op m rhs> = <n m op "[" n "," rhs "]">		-- Syntactic sugar
	<n op m "(" arg* ")"> = <n m op "[" n "," arg* "]">	??

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

R&T<"'(" item* ")">(E) = item*; E  ??

R&T<"'[" item* "]">(E) = ??

R&T<label>(E) = label; E


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

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

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

bind(id, m, val, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, val, E) -- Assign at right level
	True				=> [E | id m val]

bind(id "." n, m, val, E) = [E | id bindingOf(id, E) bind(n, m, val, R<id>(E))]

assign(id, val, E) =
	locBinding(id, E) = ":"	=> [E | id ":" val]
	bindingOf(id, E) = ":"	=>
				[E | "Outer" "=" bind(id, ":=", val, locVal("Outer", E))]
	True				=> E 			-- Can only assign to vars

SEMANTICS OF PROPERTIES, MARKS, REFERENCES (uses)

P: expression > environment > expression		-- Sequence of properties
M: expression > environment > expression		-- Sequence of marks
U: expression > environment > expression		-- Sequence of references
P&M&U<e>(E) denotes the triple  P<e>(E); M<e>(E); U<e>(E)

These functions all return the empty list, Nil, except as specified below:

P<p "#">(E) = R<p>(E)

M<name "!">(E) = prefixes(name)

U<name "@">(E) = prefixes(name)

P&M&U<invocation>(E) = P&M&U<R<invocation>(E)>(E)

P&M&U<"(" item* ")">(E) = P&M&U<item*>(E)

P&M&U<item1 item*>(E) = P<item1>(E) P<item*>(T<item1>(E));
				M<item1>(E) M<item*>(T<item1>(E));
				U<item1>(E) U<item*>(T<item1>(E))

prefixes(id) = id
prefixes(name "." id) = name "." id prefixes(name)

NOTATION FOR ENVIRONMENTS

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

VALUE SPACE

Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		external names: $name
		the empty environment: Null
		the empty list: NIL
	sequences of values
	unevaluated expressions
	environments

DISCUSSION

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 bind(id, ":=", val, 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 locVal("Outer").  The (implicit) "outermost" environment binds
each id to the external name $id.

Nodes are delimited by brackets.  The contents of each node are implicitly
prefixed by Sub, which will generally be bound in the containing environment
to a quoted expression performing an environment transformation, and perhaps
supplying some properties and marks.

Parentheses are used to denote a sequence value.  to delimit the argument list of
an operator.  Square brackets are used to denote a new environment value, which
behaves much like a record.


Semantics of labels:

A mark name! on a node makes that node a "target" of the label name (and its
prefixes); a reference name@ makes it a "source."  The "main" identifier of a
label must be declared (using name:!) at the root of a subtree containing all its
sources and targets.  The label represents a set of directed arcs, one from each of
its sources to each of its destinations.  Multiple marks make the node a target of
in multiple labels.  A unique label on a node places it in a singleton set, i.e.,
identifies it uniquely.


				OTHER NOTES

It should be clarified that the "view" of the dominant structure is ALWAYS
controlled by the properties of its nodes.  (E.g., text is not always there to be
"shown".)

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its (local) properties, and either
don't remove any of them or also understand ALL properties of its parent.
-It's OK to copy a node if that doesn't move any labels outside their scope, and
you understand ALL properties of its new parent.
-it's OK to delete a (subtree rooted at a) node if you understand ALL properties
of its parent.

The presentation of this material could be clarified by a table that relates
constructions in the notation to their intended uses and meanings.

Put in contents if:				Put in environment if:
	effect is local to node			has scope
	is directly edited				is only indirectly edited
	is to be bound locally			needs delayed or global binding


				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 GENSYM IS AN EDITOR, NOT AN INTERCHANGE, FUNCTION.

 STANDARDIZE CONCEPTS, NOT NAMES.


				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.

Edited by Jim H. on 20 Aug. 1981 5:29 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish syntactically between properties (marks) and labels.
	only the "main" id of a label is declarable.
	eliminate  as an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.
	update semantic equations for new grammar, etc.
	fix treatment of unbound qualified names (now produce Nil).

Edited by Jim H. on 21 Aug. 1981 6:58 pm PDT (Friday).
	restore $val.
	move quoting to rhs, allow quoted primaries without parentheses.
	allow an op to be the rhs of a definition.
	eliminate the functions operate, apply, eval by back substitution.
	change semantics of () to allow "record" construction without $env.

Edited by Jim H. on 24 Aug. 1981 6:08 pm PDT (Monday).
	"It's OK to edit a node if you understand ALL of its (local) properties, and
		either don't remove any of them or also understand ALL properties
		of its parent."
	"Put in contents if:				Put in environment if: ..."
	Add connection syntax to syntactically rule out a+←'b.

Edited by Jim H. on 25 Aug. 1981 11:33 am PDT (Tuesday).
	Syntactically separate label references and name invocation.
	Put in distinct syntax in rhs for environment construction.
	Informal semantics of labels.
	( ... ) > [ ... ] in applications; permitting ( ... ) as a primary.


*start*
15206 00024 USm
Subject: Current Level 0/1 Interdoc status/rev. 27
To: Mitchell, Horning

Edited by Jim H. on 26 Aug. 1981 11:43 am PDT (Wednesday).
	' ... ' in rhs
	Restore infix operators, right to left.
	Modify syntax to rule out more nonsense, add semantically meaningful
		nonterminals.
	Introduce special syntax for selections.

-------------------
Open questions:
	We should rethink our character assignments.
		check our characterset for disjointness with
			Interpress.DoubtfulChars.
		use of various bracket pairs.
		enlarge op with a few more single-character operators?
	Possible node operators (purely in semantic domain, not operators?).
		$properties: node, environment > sequence	-- All #'s
		$marks: node, environment > sequence		-- All !'s
		$references: node, environment > sequence	-- All @'s
		$contents: node, environment > sequence	-- The rest (fringe)
	Consider restricting $subscript just to sequences, not nodes.
  	Syntax for selections.


Not done:
	Consider style for use of temporary local definitions.
	disallow [ ... ] as independent item (semantically?)

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

We envision an Interdoc script being input and viewed in any manner
equivalent to the following:

Parse the script, repeatedly
- reducing each expression to its "dominant structure," containing only literals,
by replacing identifiers by the values to which they are bound in the current
environment, by applying operators, and by removing binding items,
- transforming the environment as indicated by the binding items, and
- recording the links indicated by label references and marks.

				BASIC INTERDOC

SYNTACTIC EXAMPLE:

{Book.example!		      -- Links to this from Book@ and Book.example@
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a property
a:='NOT[EQ[margins.left 120]]' margins.right←100 r=12.5*pt
IF a (margins.left←+5 margins.right←5) margins.left+←10	-- Implicit FI
	 a | (margins.left←+5 margins.right←5) | margins.left+←10 
	 (a | margins.left←+5 margins.right←5 | margins.left+←10)  -- Algol 68
<text for this node>
}

GRAMMAR

item		::= term | node | sequence | binding | property | label
term		::= primary ( op term )* | selection	-- Ops apply right to left
primary	::= literal | invocation | application
literal		::= Boolean | integer | hexint | real | string | external | op
external	::= "$" name
name		::= id ( "." id )*
id		::= letter ( letter | digit )*
op		::= "+" | "" | "*" | "/"
invocation	::= id | lookup "." id
lookup	::= invocation | external	  -- Syntactically subsumed by primary
application	::= lookup "[" item* "]"
selection	::= IF term item item
	 selection	::= term "|" item "|" item 
	 selection	::= "(" term "|" item* "|" item* ")" 
node		::= "{" item* "}"
sequence	::= "(" item* ")"
binding	::= name bindingMode rhs
bindingMode ::= "=" | ":" | ":=" | "←"
rhs		::= item | op term | "'" item* "'" | "[" item* "]"
property	::= lookup "#"
label		::= id ":!" | name "!" | name "@"

SEMANTICS

R: expression > environment > expression			-- Reduction
T: expression > environment > environment			-- Transformation
R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)

[Unless explicitly given below, T<construct>(E) = E.]

R<primary op term>(E) = R<primary>(E) op R<term>(E)

R<literal>(E) = literal

R&T<id>(E) = R&T<valOf(id, E)>(E)

R&T<lookup "." id>(E) = R&T<valOf(id, R<lookup>(E))>(E)

R&T<lookup "[" item1 ... itemn "]">(E) =
    CASE R<lookup>(E) OF
	$val		=> R<item1 ... itemn>(E); E
	$list		=> "(" R<item1 ... itemn>(E) ")" ; E
	$subscript	=> R&T<item1>(E)[R<item2>(E)]
						-- item1: sequence | node, item2: int
	$hide		=> Nil ; E
	...

R&T<"IF" term item1 item2>(E) =
			if R<term>(E) then R&T<item1>(E) else R&T<item2>(E)

R&T<"{" item* "}">(E) = "{" R<"Sub" item*>([Null | "Outer" = E]) "}";
	      locVal("Outer", (T<"Sub" item*>([Null | "Outer" = E])))

R<"(" item* ")">(E) = "(" R<item*>(E) ")"

R<>(E) = Nil

R&T<item1 item*>(E) = R<item1>(E) R<item*>(T<item1>(E));
					  T<item*>(T<item1>(E))

R&T<n m rhs>(E) = Nil ; bind(n, m, R<rhs>(E), E)
	<n m op term> = <n m n op term>		-- Syntactic sugar

R<"'" item* "'">(E) = item*			--Usable only in rhs of binding

R<"[" item* "]">(E) = [T<item*>([Null | "Outer" = E]) | "Outer" = Null], E)
	-- Construct a "record" environment value; usable only in rhs of binding

R<lookup "#">(E) = R<lookup>(E) "#"

R<label>(E) = label


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

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

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

bind(id, m, val, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, val, E) -- Assign at right level
	True				=> [E | id m val]

bind(id "." n, m, val, E) = [E | id bindingOf(id, E) bind(n, m, val, R<id>(E))]

assign(id, val, E) =
	locBinding(id, E) = ":"	=> [E | id ":" val]
	bindingOf(id, E) = ":"	=>
				[E | "Outer" "=" bind(id, ":=", val, locVal("Outer", E))]
	True				=> E 			-- Can only assign to vars

SEMANTICS OF PROPERTIES, MARKS, REFERENCES (uses)

P: expression > environment > expression		-- Sequence of properties
M: expression > environment > expression		-- Sequence of marks
U: expression > environment > expression		-- Sequence of references
P&M&U<e>(E) denotes the triple  P<e>(E); M<e>(E); U<e>(E)

[These functions all return the empty list, Nil, except as specified below.]

P<primary "#">(E) = R<primary>(E)

M<name "!">(E) = prefixes(name)

U<name "@">(E) = prefixes(name)

P&M&U<invocation>(E) = P&M&U<R<invocation>(E)>(E)

P&M&U<"(" item* ")">(E) = P&M&U<item*>(E)

P&M&U<item1 item*>(E) = P<item1>(E) P<item*>(T<item1>(E));
				M<item1>(E) M<item*>(T<item1>(E));
				U<item1>(E) U<item*>(T<item1>(E))

prefixes(id) = id
prefixes(name "." id) = name "." id prefixes(name)

NOTATION FOR ENVIRONMENTS

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

VALUE SPACE

Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		external names: $name
		the empty environment: Null
		the empty list: NIL
	sequences of values
	unevaluated expressions
	environments

DISCUSSION

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 bind(id, ":=", val, 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 locVal("Outer").  The (implicit) "outermost" environment binds
each id to the external name $id.

Nodes are delimited by brackets.  The contents of each node are implicitly
prefixed by Sub, which will generally be bound in the containing environment
to a quoted expression performing an environment transformation, and perhaps
supplying some properties and marks.

Parentheses are used to denote a sequence value.  to delimit the argument list of
an operator.  Square brackets are used to denote a new environment value, which
behaves much like a record.


Semantics of labels:

A mark name! on a node makes that node a "target" of the label name (and its
prefixes); a reference name@ makes it a "source."  The "main" identifier of a
label must be declared (using name:!) at the root of a subtree containing all its
sources and targets.  The label represents a set of directed arcs, one from each of
its sources to each of its destinations.  Multiple marks make the node a target of
in multiple labels.  A unique label on a node places it in a singleton set, i.e.,
identifies it uniquely.


				OTHER NOTES

It should be clarified that the "view" of the dominant structure is ALWAYS
controlled by the properties of its nodes.  (E.g., text is not always there to be
"shown".)

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its (local) properties, and either
don't remove any of them or also understand ALL properties of its parent.
-It's OK to copy a node if that doesn't move any labels outside their scope, and
you understand ALL properties of its new parent.
-it's OK to delete a (subtree rooted at a) node if you understand ALL properties
of its parent.

The presentation of this material could be clarified by a table that relates
constructions in the notation to their intended uses and meanings.

Put in contents if:				Put in environment if:
	effect is local to node			has scope
	is directly edited				is only indirectly edited
	is to be bound locally			needs delayed or global binding


				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 GENSYM IS AN EDITOR, NOT AN INTERCHANGE, FUNCTION.

 STANDARDIZE CONCEPTS, NOT NAMES.


			CONSCIOUSLY POSTPONED

Lambda expressions, function definition.

	Sets of properties, etc. (Cf. Mitchell's Font example.)
		SET/LIST operators ($append $union ?)



				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.

Edited by Jim H. on 20 Aug. 1981 5:29 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish syntactically between properties (marks) and labels.
	only the "main" id of a label is declarable.
	eliminate  as an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.
	update semantic equations for new grammar, etc.
	fix treatment of unbound qualified names (now produce Nil).

Edited by Jim H. on 21 Aug. 1981 6:58 pm PDT (Friday).
	restore $val.
	move quoting to rhs, allow quoted primaries without parentheses.
	allow an op to be the rhs of a definition.
	eliminate the functions operate, apply, eval by back substitution.
	change semantics of () to allow "record" construction without $env.

Edited by Jim H. on 24 Aug. 1981 6:08 pm PDT (Monday).
	"It's OK to edit a node if you understand ALL of its (local) properties, and
		either don't remove any of them or also understand ALL properties
		of its parent."
	"Put in contents if:				Put in environment if: ..."
	Add connection syntax to syntactically rule out a+←'b.

Edited by Jim H. on 25 Aug. 1981 11:33 am PDT (Tuesday).
	Syntactically separate label references and name invocation.
	Put in distinct syntax in rhs for environment construction.
	Informal semantics of labels.
	( ... ) > [ ... ] in applications; permitting ( ... ) as a primary.

Edited by Jim H. on 25 Aug. 1981 4:08 pm PDT (Tuesday).
	Add sequence as a nonterminal to the syntax.
	State the formal semantics of labels and properties.
	Reorder presentation (hopefully to improve readability).


*start*
15461 00024 USm
Subject: Current Level 0/1 Interdoc status/rev. 28
To: Mitchell, Horning

Edited by Jim H. on 26 Aug. 1981 7:11 pm PDT (Wednesday).
	' ... ' in rhs
	Restore infix operators, right to left.
	Modify syntax to rule out more nonsense, add semantically meaningful
		nonterminals.
	Introduce special syntax for selections.
	Eliminate side-effects for $subscript (actually, all applications).
	Add application of defined functions.
	Note that Value[ ... ] allows use of temporary (hidden) local definitions,
		Nil[ ... ] allows placement of hidden nodes.
	( ... ) creates list/sequence values (without hiding bindings).

-------------------
Open questions:
	We should rethink our character assignments.
		check our characterset for disjointness with
			Interpress.DoubtfulChars.
		use of various bracket pairs.
		enlarge op with a few more single-character operators?
	Possible node operators (purely in semantic domain, not operators?).
		$properties: node, environment > sequence	-- All #'s
		$marks: node, environment > sequence		-- All !'s
		$references: node, environment > sequence	-- All @'s
		$contents: node, environment > sequence	-- The rest (fringe)
	Consider restricting $subscript just to sequences, not nodes.
	Extend selection to CASE?
	Fix to semantics of := ??

Not done:

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

We envision an Interdoc script being input and viewed in any manner
equivalent to the following:

Parse the script, repeatedly
- reducing each expression to its "dominant structure," containing only literals,
by replacing identifiers by the values to which they are bound in the current
environment, by applying operators, and by removing binding items,
- transforming the environment as indicated by the binding items (recording the components of each node's environment in a form convenient to the editor), and
- recording the links indicated by label references and marks.

				BASIC INTERDOC

SYNTACTIC EXAMPLE:

{Book.example!		      -- Links to this from Book@ and Book.example@
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a property
a:='NOT[EQ[margins.left 120]]' margins.right←100 r=12.5*pt
(a | margins.left←+5 margins.right←5 | margins.left+←10) -- conditional: Algol68
<text for this node>
}

GRAMMAR

item		::= term | node | sequence | binding | property | label
term		::= primary | primary op term | selection	-- Ops apply right to left
primary	::= literal | invocation | application
literal		::= Boolean | integer | hexint | real | string | external | op
external	::= "$" name
name		::= id ( "." id )*
id		::= letter ( letter | digit )*
op		::= "+" | "" | "*" | "/"
invocation	::= id | lookup "." id
lookup	::= invocation | external	  -- Syntactically subsumed by primary
application	::= lookup "[" item* "]"
selection	::= "(" term "|" item* "|" item* ")"	-- Algol 68 style conditional
node		::= "{" item* "}"
sequence	::= "(" item* ")"
binding	::= name bindingMode rhs
bindingMode ::= "=" | ":" | ":=" | "←"
rhs		::= item | op term | "'" item* "'" | "[" item* "]"
property	::= lookup "#"
label		::= id ":!" | name "!" | name "@"

SEMANTICS

R: expression > environment > expression			-- Reduction
T: expression > environment > environment			-- Transformation
R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)

[Unless explicitly given below, T<construct>(E) = E.]

R<literal>(E) = literal

R&T<id>(E) = R&T<valOf(id, E)>(E)

R&T<lookup "." id>(E) = R&T<valOf(id, R<lookup>(E))>(E)

R<lookup "[" item1 ... itemk "]">(E) =
    CASE R<lookup>(E) OF
	"$equal"	=> R<item1>(E) = R<item2>(E)
	"$greater"	=> R<item1>(E) > R<item2>(E)
	. . .
	"$subscript"	=> R<item1>(E)[R<item2>(E)]
						-- item1: sequence | node, item2: int
    ELSE		=> R<lookup>([E | "Value" "=" R<item1 ... itemk>(E)])

R<primary op term>(E) = R<primary>(E) op R<term>(E)

R&T<"(" term "|" item1* "|" item2* ")">(E) =
			if R<term>(E) then R&T<item1*>(E) else R&T<item2*>(E)

R&T<"{" item* "}">(E) = "{" R<"Sub" item*>([Null | "Outer" "=" E]) "}";
	      locVal("Outer", (T<"Sub" item*>([Null | "Outer" "=" E])))

R&T<"(" item* ")">(E) = "(" R<item*>(E) ")" ; T<item*>(E)

R<>(E) = Nil

R&T<item1 item*>(E) = R<item1>(E) R<item*>(T<item1>(E));
					  T<item*>(T<item1>(E))

R&T<n m rhs>(E) = Nil; bind(n, m, R<rhs>(E), E)
	<n m op term> = <n m n op term>		-- Syntactic sugar

R<"'" item* "'">(E) = item*			--Usable only in rhs of binding

R<"[" item* "]">(E) = [T<item*>([Null | "Outer" "=" E]) | "Outer" "=" Null]
	-- Construct a "record" environment value; usable only in rhs of binding

R<lookup "#">(E) = R<lookup>(E) "#"

R<label>(E) = label

	-- Subsidiary definitions for R&T

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

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

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

bind(id, m, val, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, val, E) -- Assign at right level
	True				=> [E | id m val]

bind(id "." n, m, val, E) = [E | id bindingOf(id, E) bind(n, m, val, valOf(id, E))]

assign(id, val, E) =
	locBinding(id, E) = ":"	=> [E | id ":" val]
	bindingOf(id, E) = ":"	=> bind("Outer." id, ":=", val, E)
				[E | "Outer" "=" bind(id, ":=", val, locVal("Outer", E))]
	True				=> E 			-- Can only assign to vars

NOTATION FOR ENVIRONMENTS

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

SEMANTICS OF PROPERTIES, MARKS, REFERENCES (uses)

P: expression > environment > expression		-- Sequence of properties
M: expression > environment > expression		-- Sequence of marks
U: expression > environment > expression		-- Sequence of references
P&M&U<e>(E) denotes the triple  P<e>(E); M<e>(E); U<e>(E)

[These functions all return the empty list, Nil, except as specified below.]

P<primary "#">(E) = R<primary>(E)

M<name "!">(E) = prefixes(name)

U<name "@">(E) = prefixes(name)

P&M&U<invocation>(E) = P&M&U<R<invocation>(E)>(E)

P&M&U<"(" item* ")">(E) = P&M&U<item*>(E)

P&M&U<item1 item*>(E) = P<item1>(E) P<item*>(T<item1>(E));
				M<item1>(E) M<item*>(T<item1>(E));
				U<item1>(E) U<item*>(T<item1>(E))

prefixes(id) = id
prefixes(name "." id) = name "." id prefixes(name)

VALUE SPACE

Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		external names: $name
		the empty environment: Null
		the empty list: NIL
	sequences of values
	unevaluated expressions
	environments

DISCUSSION

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 bind(id, ":=", val, 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 locVal("Outer").  The (implicit) "outermost" environment binds
each id to the external name $id.

Nodes are delimited by brackets.  The contents of each node are implicitly
prefixed by Sub, which will generally be bound in the containing environment
to a quoted expression performing an environment transformation, and perhaps
supplying some properties and marks.

Parentheses are used to denote a sequence value.  to delimit the argument list of
an operator.  Square brackets are used to denote a new environment value, which
behaves much like a record.


Semantics of labels:

A mark name! on a node makes that node a "target" of the label name (and its
prefixes); a reference name@ makes it a "source."  The "main" identifier of a
label must be declared (using name:!) at the root of a subtree containing all its
sources and targets.  The label represents a set of directed arcs, one from each of
its sources to each of its destinations.  Multiple marks make the node a target of
in multiple labels.  A unique label on a node places it in a singleton set, i.e.,
identifies it uniquely.


				OTHER NOTES

It should be clarified that the "view" of the dominant structure is ALWAYS
controlled by the properties of its nodes.  (E.g., text is not always there to be
"shown".)

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its (local) properties, and either
don't remove any of them or also understand ALL properties of its parent.
-It's OK to copy a node if that doesn't move any labels outside their scope, and
you understand ALL properties of its new parent.
-it's OK to delete a (subtree rooted at a) node if you understand ALL properties
of its parent.

The presentation of this material could be clarified by a table that relates
constructions in the notation to their intended uses and meanings.

Put in contents if:				Put in environment if:
	effect is local to node			has scope
	is directly edited				is only indirectly edited
	is to be bound locally			needs delayed or global binding


				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 GENSYM IS AN EDITOR, NOT AN INTERCHANGE, FUNCTION.

 STANDARDIZE CONCEPTS, NOT NAMES.


			CONSCIOUSLY POSTPONED

Lambda expressions.

Sets of properties, etc. (Cf. Mitchell's Font example.)
	SET/LIST operators ($append $union ?)



				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.

Edited by Jim H. on 20 Aug. 1981 5:29 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish syntactically between properties (marks) and labels.
	only the "main" id of a label is declarable.
	eliminate  as an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.
	update semantic equations for new grammar, etc.
	fix treatment of unbound qualified names (now produce Nil).

Edited by Jim H. on 21 Aug. 1981 6:58 pm PDT (Friday).
	restore $val.
	move quoting to rhs, allow quoted primaries without parentheses.
	allow an op to be the rhs of a definition.
	eliminate the functions operate, apply, eval by back substitution.
	change semantics of () to allow "record" construction without $env.

Edited by Jim H. on 24 Aug. 1981 6:08 pm PDT (Monday).
	"It's OK to edit a node if you understand ALL of its (local) properties, and
		either don't remove any of them or also understand ALL properties
		of its parent."
	"Put in contents if:				Put in environment if: ..."
	Add connection syntax to syntactically rule out a+←'b.

Edited by Jim H. on 25 Aug. 1981 11:33 am PDT (Tuesday).
	Syntactically separate label references and name invocation.
	Put in distinct syntax in rhs for environment construction.
	Informal semantics of labels.
	( ... ) > [ ... ] in applications; permitting ( ... ) as a primary.

Edited by Jim H. on 25 Aug. 1981 4:08 pm PDT (Tuesday).
	Add sequence as a nonterminal to the syntax.
	State the formal semantics of labels and properties.
	Reorder presentation (hopefully to improve readability).


*start*
15765 00024 USm
Date: 27 Aug. 1981 7:51 pm PDT (Thursday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 29
To: Mitchell, Horning

Edited by Jim H. on 26 Aug. 1981 7:11 pm PDT (Wednesday).
	' ... ' in rhs
	Restore infix operators, right to left.
	Modify syntax to rule out more nonsense, add semantically meaningful
		nonterminals.
	Introduce special syntax for selections.
	Eliminate side-effects for $subscript (actually, all applications).
	Add application of defined functions.
	Note that Value[ ... ] allows use of temporary (hidden) local definitions,
		Nil[ ... ] allows placement of hidden nodes.
	( ... ) creates list/sequence values (without hiding bindings).
	Tidy up definition of assign, using bind("Outer." ...).
	Introduce value nonterminal into grammar (rule out more nonsense).
	rhs	::= ... | "[" [ lookup ] "|" binding* "]" .
	Remove $ name from literal (to lookup).
	Change nonterminal lookup to invocation.

-------------------
Open questions:
	We should rethink our character assignments.
		check our characterset for disjointness with
			Interpress.DoubtfulChars.
		enlarge op with a few more single-character operators?  %, &, \
	Possible node operators (purely in semantic domain, not operators?).
		$properties: node, environment > sequence	-- All #'s
		$marks: node, environment > sequence		-- All !'s
		$references: node, environment > sequence	-- All @'s
		$contents: node, environment > sequence	-- The rest (fringe)
	Consider restricting $subscript just to sequences, not nodes.
	Extend selection to CASE?

Not done:

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

We envision an Interdoc script being input and viewed in any manner
equivalent to the following:

Parse the script, repeatedly
- reducing each expression to its "dominant structure," containing only literals,
by replacing identifiers by the values to which they are bound in the current
environment, by applying operators, and by removing binding items,
- transforming the environment as indicated by the binding items (recording the
components of each node's environment in a form convenient to the editor), and
- recording the links indicated by label references and marks.

				BASIC INTERDOC

SYNTACTIC EXAMPLE:

{Book.example!		      -- Links to this from Book@ and Book.example@
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a property
Font←[Font | size←10*pt face←bold]
a:='NOT[EQ[margins.left 120]]' margins.right←100 r=12.5*pt
(a | margins.left←+5 margins.right←5 | margins.left+←10) -- conditional: Algol68
<text for this node>
}

GRAMMAR

item		::= value | binding | property | label
value		::= term | node | sequence
term		::= primary | primary op term	-- Ops apply right to left
primary	::= literal | invocation | application | selection
literal		::= Boolean | integer | hexint | real | string | op
op		::= "+" | "" | "*" | "/"
invocation	::= name | external
name		::= id ( "." id )*
id		::= letter ( letter | digit )*
external	::= "$" name
application	::= invocation "[" value* "]"
selection	::= "(" term "|" item* "|" item* ")"	-- Algol 68 style conditional
node		::= "{" item* "}"
sequence	::= "(" item* ")"
binding	::= name bindingMode rhs
bindingMode ::= "=" | ":" | ":=" | "←"
rhs		::= value | op term | "'" item* "'" | "[" [ invocation ] "|" binding* "]"
property	::= invocation "#"
label		::= id ":!" | name "!" | name "@"

SEMANTICS

R: expression > environment > expression			-- Reduction
T: expression > environment > environment			-- Transformation
R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)

[Unless explicitly given below, T<construct>(E) = E.]

R<primary op term>(E) = R<primary>(E) op R<term>(E)

R<literal>(E) = literal

R&T<id>(E) = R&T<valOf(id, E)>(E)

R&T<name "." id>(E) = R&T<valOf(id, R<name>(E))>(E)

R<"$" name>(E) = "$" name

R<invocation "[" value1 ... valuek "]">(E) =
    CASE R<invocation>(E) OF
	"$equal"	=> R<value1>(E) = R<value2>(E)
	"$greater"	=> R<value1>(E) > R<value2>(E)
	. . .
	"$subscript"	=> R<value1>(E)[R<value2>(E)]
						-- value1: sequence | node, value2: int
    ELSE		=> R<invocation>([E | "Value" "=" R<value1 ... valuek>(E)])

R&T<"(" term "|" item1* "|" item2* ")">(E) =
			if R<term>(E) then R&T<item1*>(E) else R&T<item2*>(E)

R&T<"{" item* "}">(E) = "{" R<"Sub" item*>([Null | "Outer" "=" E]) "}";
	      locVal("Outer", (T<"Sub" item*>([Null | "Outer" "=" E])))

R&T<"(" item* ")">(E) = "(" R<item*>(E) ")" ; T<item*>(E)

R<>(E) = Nil

R&T<item1 item*>(E) = R<item1>(E) R<item*>(T<item1>(E));
					  T<item*>(T<item1>(E))

R&T<n m rhs>(E) = Nil; bind(n, m, R<rhs>(E), E)
	<n m op term> = <n m n op term>		-- Syntactic sugar

R<"'" item* "'">(E) = item*			--Usable only in rhs of binding

R<"[" invocation "|" binding* "]">(E) =
	[T<binding*>([R<invocation>(E) | "Outer" "=" E]) | "Outer" "=" Null]
R<"[|" binding* "]">(E) = [T<binding*>([Null | "Outer" "=" E]) | "Outer" "=" Null]

R<invocation "#">(E) = R<invocation>(E) "#"

R<label>(E) = label

	-- Subsidiary definitions for R&T

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

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

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

bind(id, m, val, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, val, E) -- Assign at right level
	True				=> [E | id m val]

bind(id "." n, m, val, E) = [E | id bindingOf(id, E) bind(n, m, val, valOf(id, E))]

assign(id, val, E) =
	locBinding(id, E) = ":"	=> [E | id ":" val]
	bindingOf(id, E) = ":"	=> bind("Outer." id, ":=", val, E)
	True				=> E 			-- Can only assign to vars

NOTATION FOR ENVIRONMENTS

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

SEMANTICS OF PROPERTIES, MARKS, REFERENCES (uses)

P: expression > environment > expression		-- Sequence of properties
M: expression > environment > expression		-- Sequence of marks
U: expression > environment > expression		-- Sequence of references
P&M&U<e>(E) denotes the triple  P<e>(E); M<e>(E); U<e>(E)

[These functions all return the empty list, Nil, except as specified below.]

P<invocation "#">(E) = R<invocation>(E)

M<name "!">(E) = prefixes(name)

U<name "@">(E) = prefixes(name)

P&M&U<invocation>(E) = P&M&U<R<invocation>(E)>(E)

P&M&U<"(" item* ")">(E) = P&M&U<item*>(E)

P&M&U<item1 item*>(E) = P<item1>(E) P<item*>(T<item1>(E));
				M<item1>(E) M<item*>(T<item1>(E));
				U<item1>(E) U<item*>(T<item1>(E))

prefixes(id) = id
prefixes(name "." id) = name "." id prefixes(name)

VALUE SPACE

Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		external names: $name
		the empty environment: Null
		the empty list: NIL
	sequences of values
	unevaluated expressions
	environments

DISCUSSION

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 bind(id, ":=", val, 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 locVal("Outer").  The (implicit) "outermost" environment binds
each id to the external name $id.

Nodes are delimited by brackets.  The contents of each node are implicitly
prefixed by Sub, which will generally be bound in the containing environment
to a quoted expression performing an environment transformation, and perhaps
supplying some properties and marks.

Parentheses are used to denote a sequence value.  to delimit the argument list of
an operator.  Square brackets are used to denote a new environment value, which
behaves much like a record.


Semantics of labels:

A mark name! on a node makes that node a "target" of the label name (and its
prefixes); a reference name@ makes it a "source."  The "main" identifier of a
label must be declared (using name:!) at the root of a subtree containing all its
sources and targets.  The label represents a set of directed arcs, one from each of
its sources to each of its destinations.  Multiple marks make the node a target of
in multiple labels.  A unique label on a node places it in a singleton set, i.e.,
identifies it uniquely.


				OTHER NOTES

It should be clarified that the "view" of the dominant structure is ALWAYS
controlled by the properties of its nodes.  (E.g., text is not always there to be
"shown".)

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its (local) properties, and either
don't remove any of them or also understand ALL properties of its parent.
-It's OK to copy a node if that doesn't move any labels outside their scope, and
you understand ALL properties of its new parent.
-it's OK to delete a (subtree rooted at a) node if you understand ALL properties
of its parent.

The presentation of this material could be clarified by a table that relates
constructions in the notation to their intended uses and meanings.

Put in contents if:				Put in environment if:
	effect is local to node			has scope
	is directly edited				is only indirectly edited
	is to be bound locally			needs delayed or global binding


				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 GENSYM IS AN EDITOR, NOT AN INTERCHANGE, FUNCTION.

 STANDARDIZE CONCEPTS, NOT NAMES.


			CONSCIOUSLY POSTPONED

Lambda expressions.

Sets of properties, etc. (Cf. Mitchell's Font example.)
	SET/LIST operators ($append $union ?)



				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.

Edited by Jim H. on 20 Aug. 1981 5:29 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish syntactically between properties (marks) and labels.
	only the "main" id of a label is declarable.
	eliminate  as an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.
	update semantic equations for new grammar, etc.
	fix treatment of unbound qualified names (now produce Nil).

Edited by Jim H. on 21 Aug. 1981 6:58 pm PDT (Friday).
	restore $val.
	move quoting to rhs, allow quoted primaries without parentheses.
	allow an op to be the rhs of a definition.
	eliminate the functions operate, apply, eval by back substitution.
	change semantics of () to allow "record" construction without $env.

Edited by Jim H. on 24 Aug. 1981 6:08 pm PDT (Monday).
	"It's OK to edit a node if you understand ALL of its (local) properties, and
		either don't remove any of them or also understand ALL properties
		of its parent."
	"Put in contents if:				Put in environment if: ..."
	Add connection syntax to syntactically rule out a+←'b.

Edited by Jim H. on 25 Aug. 1981 11:33 am PDT (Tuesday).
	Syntactically separate label references and name invocation.
	Put in distinct syntax in rhs for environment construction.
	Informal semantics of labels.
	( ... ) > [ ... ] in applications; permitting ( ... ) as a primary.

Edited by Jim H. on 25 Aug. 1981 4:08 pm PDT (Tuesday).
	Add sequence as a nonterminal to the syntax.
	State the formal semantics of labels and properties.
	Reorder presentation (hopefully to improve readability).


*start*
15962 00024 USm
Date: 28 Aug. 1981 2:09 pm PDT (Friday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 30
To: Mitchell, Horning, Guttag

Edited by Jim H. on 28 Aug. 1981 2:08 pm PDT (Friday).
  [Changes since 25 August]
	' ... ' in rhs
	Restore infix operators, right to left.
	Modify syntax to rule out more nonsense, add semantically meaningful
		nonterminals.
	Introduce special syntax for selections.
	Eliminate side-effects for $subscript (actually, all applications).
	Add application of defined functions.
	Note that Value[ ... ] allows use of temporary (hidden) local definitions,
		Nil[ ... ] allows placement of hidden nodes.
	( ... ) creates list/sequence values (without hiding bindings).
	Tidy up definition of assign, using bind("Outer." ...).
	Introduce value nonterminal into grammar (rule out more nonsense).
	rhs	::= ... | "[" [ lookup ] "|" binding* "]" .
	Change nonterminal lookup to invocation.
	Remove $ name from literal (to invocation).
	Add node operators:
		$properties						-- All #'s
		$marks						-- All !'s
		$references						-- All @'s
		$contents						-- The rest (fringe)
	Restrict $subscript just to sequences, not nodes.


-------------------
Open questions:
	We should rethink our character assignments.
		check our characterset for disjointness with
			Interpress.DoubtfulChars.
		enlarge op with a few more single-character operators?  %, &, \
	Possible node operators (purely in semantic domain, not operators?).
	Extend selection to CASE?

Not done:

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

We envision an Interdoc script being input and viewed in any manner
equivalent to the following:

Parse the script, repeatedly
- reducing each expression to its "dominant structure," containing only literals,
by replacing identifiers by the values to which they are bound in the current
environment, by applying operators, and by removing binding items,
- transforming the environment as indicated by the binding items (recording the
components of each node's environment in a form convenient to the editor), and
- recording the links indicated by label references and marks.

				BASIC INTERDOC

SYNTACTIC EXAMPLE:

{Book.example!		      -- Links to this from Book@ and Book.example@
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a property
Font←[Font | size←10*pt face←bold]
factorial←'(LT[Value 2] | 1 | Value* factorial(Value-1))'
a:='NOT[EQ[margins.left factorial[5]]]' margins.right←100 r=12.5*pt
(a | margins.left←+5 margins.right←5 | margins.left+←10) -- conditional: Algol68
<text for this node>
}

GRAMMAR

item		::= value | binding | property | label
value		::= term | node | sequence
term		::= primary | primary op term	-- Ops apply right to left
primary	::= literal | invocation | application | selection
literal		::= Boolean | integer | hexint | real | string | op
op		::= "+" | "" | "*" | "/"
invocation	::= name | external
name		::= id ( "." id )*
id		::= letter ( letter | digit )*
external	::= "$" name
application	::= invocation "[" value* "]"
selection	::= "(" term "|" item* "|" item* ")"	-- Algol 68 style conditional
node		::= "{" item* "}"
sequence	::= "(" item* ")"
binding	::= name bindingMode rhs
bindingMode ::= "=" | ":" | ":=" | "←"
rhs		::= value | op term | "'" item* "'" | "[" [ invocation ] "|" binding* "]"
property	::= invocation "#"
label		::= id ":!" | name "!" | name "@"

SEMANTICS

R: expression > environment > expression			-- Reduction
T: expression > environment > environment			-- Transformation
R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)

[Unless explicitly given below, T<construct>(E) = E.]

R<primary op term>(E) = R<primary>(E) op R<term>(E)

R<literal>(E) = literal

R&T<id>(E) = R&T<valOf(id, E)>(E)

R&T<name "." id>(E) = R&T<valOf(id, R<name>(E))>(E)

R<"$" name>(E) = "$" name

R<invocation "[" value* "]">(E) = apply(invocation, R<value*>(E), E)
apply(invocation, value*, E) =
    CASE R<invocation>(E) OF
	"$equal"	=> value1 = value2
	"$greater"	=> value1 > value2
	. . .
	"$subscript"	=> value1[value2]	-- value1: sequence, value2: int
	"$contents"	=> C<value*>
	"$properties"	=> P<value*>(E)
	"$marks"	=> M<value*>(E)
	"$references" => U<value*>(E)
    ELSE		=> R<invocation>([E | "Value" "=" value*])

R&T<"(" term "|" item1* "|" item2* ")">(E) =
			if R<term>(E) then R&T<item1*>(E) else R&T<item2*>(E)

R&T<"{" item* "}">(E) = "{" R<"Sub" item*>([Null | "Outer" "=" E]) "}";
	      locVal("Outer", (T<"Sub" item*>([Null | "Outer" "=" E])))

R&T<"(" item* ")">(E) = "(" R<item*>(E) ")" ; T<item*>(E)

R<>(E) = Nil

R&T<item1 item*>(E) = R<item1>(E) R<item*>(T<item1>(E));
					  T<item*>(T<item1>(E))

R&T<n m rhs>(E) = Nil; bind(n, m, R<rhs>(E), E)
	<n m op term> = <n m n op term>		-- Syntactic sugar

R<"'" item* "'">(E) = item*			--Usable only in rhs of binding

R<"[" invocation "|" binding* "]">(E) =
	[T<binding*>([R<invocation>(E) | "Outer" "=" E]) | "Outer" "=" Null]
R<"[|" binding* "]">(E) = [T<binding*>([Null | "Outer" "=" E]) | "Outer" "=" Null]

R<invocation "#">(E) = R<invocation>(E) "#"

R<label>(E) = label

	-- Subsidiary definitions for R&T

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

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

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

bind(id, m, val, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, val, E) -- Assign at right level
	True				=> [E | id m val]

bind(id "." n, m, val, E) = [E | id bindingOf(id, E) bind(n, m, val, valOf(id, E))]

assign(id, val, E) =
	locBinding(id, E) = ":"	=> [E | id ":" val]
	bindingOf(id, E) = ":"	=> bind("Outer." id, ":=", val, E)
	True				=> E 			-- Can only assign to vars

NOTATION FOR ENVIRONMENTS

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

SEMANTICS OF PROPERTIES, MARKS, REFERENCES (uses), CONTENTS

P: expression > environment > expression		-- Sequence of properties
M: expression > environment > expression		-- Sequence of marks
U: expression > environment > expression		-- Sequence of references
P&M&U<e>(E) denotes the triple  P<e>(E); M<e>(E); U<e>(E)

[These functions all return the empty list, Nil, except as specified below.]

P<invocation "#">(E) = R<invocation>(E)

M<name "!">(E) = prefixes(name)

U<name "@">(E) = prefixes(name)

P&M&U<invocation>(E) = P&M&U<R<invocation>(E)>(E)

P&M&U<"(" item* ")">(E) = P&M&U<item*>(E)

P&M&U<item1 item*>(E) = P<item1>(E) P<item*>(T<item1>(E));
				M<item1>(E) M<item*>(T<item1>(E));
				U<item1>(E) U<item*>(T<item1>(E))

prefixes(id) = id
prefixes(name "." id) = name "." id prefixes(name)

C: expression > expression

C<value> = value
C<property> = C<label> = Nil


VALUE SPACE

Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		external names: $name
		the empty environment: Null
		the empty list: NIL
	sequences of values
	unevaluated expressions
	environments

DISCUSSION

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 bind(id, ":=", val, 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 locVal("Outer").  The (implicit) "outermost" environment binds
each id to the external name $id.

Nodes are delimited by brackets.  The contents of each node are implicitly
prefixed by Sub, which will generally be bound in the containing environment
to a quoted expression performing an environment transformation, and perhaps
supplying some properties and marks.

Parentheses are used to denote a sequence value.  to delimit the argument list of
an operator.  Square brackets are used to denote a new environment value, which
behaves much like a record.


Semantics of labels:

A mark name! on a node makes that node a "target" of the label name (and its
prefixes); a reference name@ makes it a "source."  The "main" identifier of a
label must be declared (using name:!) at the root of a subtree containing all its
sources and targets.  The label represents a set of directed arcs, one from each of
its sources to each of its destinations.  Multiple marks make the node a target of
in multiple labels.  A unique label on a node places it in a singleton set, i.e.,
identifies it uniquely.


				OTHER NOTES

It should be clarified that the "view" of the dominant structure is ALWAYS
controlled by the properties of its nodes.  (E.g., text is not always there to be
"shown".)

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its (local) properties, and either
don't remove any of them or also understand ALL properties of its parent.
-It's OK to copy a node if that doesn't move any labels outside their scope, and
you understand ALL properties of its new parent.
-it's OK to delete a (subtree rooted at a) node if you understand ALL properties
of its parent.

The presentation of this material could be clarified by a table that relates
constructions in the notation to their intended uses and meanings.

Put in contents if:				Put in environment if:
	effect is local to node			has scope
	is directly edited				is only indirectly edited
	is to be bound locally			needs delayed or global binding


				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 GENSYM IS AN EDITOR, NOT AN INTERCHANGE, FUNCTION.

 STANDARDIZE CONCEPTS, NOT NAMES.


			CONSCIOUSLY POSTPONED

Lambda expressions.

Sets of properties, etc. (Cf. Mitchell's Font example.)
	SET/LIST operators ($append $union ?)



				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.

Edited by Jim H. on 20 Aug. 1981 5:29 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish syntactically between properties (marks) and labels.
	only the "main" id of a label is declarable.
	eliminate  as an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.
	update semantic equations for new grammar, etc.
	fix treatment of unbound qualified names (now produce Nil).

Edited by Jim H. on 21 Aug. 1981 6:58 pm PDT (Friday).
	restore $val.
	move quoting to rhs, allow quoted primaries without parentheses.
	allow an op to be the rhs of a definition.
	eliminate the functions operate, apply, eval by back substitution.
	change semantics of () to allow "record" construction without $env.

Edited by Jim H. on 24 Aug. 1981 6:08 pm PDT (Monday).
	"It's OK to edit a node if you understand ALL of its (local) properties, and
		either don't remove any of them or also understand ALL properties
		of its parent."
	"Put in contents if:				Put in environment if: ..."
	Add connection syntax to syntactically rule out a+←'b.

Edited by Jim H. on 25 Aug. 1981 11:33 am PDT (Tuesday).
	Syntactically separate label references and name invocation.
	Put in distinct syntax in rhs for environment construction.
	Informal semantics of labels.
	( ... ) > [ ... ] in applications; permitting ( ... ) as a primary.

Edited by Jim H. on 25 Aug. 1981 4:08 pm PDT (Tuesday).
	Add sequence as a nonterminal to the syntax.
	State the formal semantics of labels and properties.
	Reorder presentation (hopefully to improve readability).


*start*
16589 00024 US 
Subject: Current Level 0/1 Interdoc status/rev. 31
To: Mitchell, Horning, Guttag

Edited by Jim H. on 1 Sept. 1981 3:09 pm PDT (Tuesday).


-------------------
Open questions:
	We should rethink our character assignments.
		check our characterset for disjointness with
			Interpress.DoubtfulChars.
		enlarge op with a few more single-character operators?  %, &, \
	Extend selection to CASE?
	Better way to present semantics?

Not done:
	Compressed syntactic example.
	Label ::= Mark | Source | Target | Link
	Properties/Attributes
	Format for description of standard properties
	$ hidden #
	R&T&P&M&U > R&B&M&S&T
	Hints to implementors:
		environment restoration points
		coding tricks for common structures
	Editor levels
		Internal definition/invocation
		Nesting of nodes
		Links

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

				STANDARD CARD

 WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

 EVERY SCRIPT IS PARSED BEFORE BEING INTERPRETED.

 STANDARDIZE CONCEPTS, NOT NAMES.

 COMBINING DOCUMENTS IS AN EDITOR, NOT AN INTERCHANGE, TASK.

 GENSYM IS AN EDITOR FUNCTION.


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

We envision an Interdoc script being input and viewed in any manner
equivalent to the following:

Parse the script, repeatedly
- reducing each expression to its "dominant structure," containing only literals,
by replacing identifiers by the values to which they are bound in the current
environment, by applying operators, and by removing binding items,
- transforming the environment as indicated by the binding items (recording the
components of each node's environment in a form convenient to the editor), and
- recording the links indicated by label references and marks.

				BASIC INTERDOC

SYNTACTIC EXAMPLE:

{Book.example!		      -- Links to this from Book@ and Book.example@
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a property
Font←[Font | size←10*pt face←bold]
factorial←'(LT[Value 2] | 1 | Value*factorial(Value-1))'
a:='NOT[EQ[margins.left factorial[5]]]' margins.right←100 r=12.5*pt
(a | margins.left←+5 margins.right←5 | margins.left+←10) -- conditional: Algol68
<text for this node>
}

-- Or, using short identifiers, and omitting comments and unnecessary spaces:
{b.e!ep um#f←[f|s←10*pt fc←bo]fa←'(l[Value 2]|1|Value*fa(Value-1))'
a:='n[e[m.l fa[5]]]'m.r←100 r=12.5*pt(a|m.l←+5 m.r←5|m.l+←10)<text for this node>}

GRAMMAR

item		::= value | binding | property | label
value		::= term | node | sequence
term		::= primary | primary op term	-- Ops apply right to left
primary	::= literal | invocation | application | selection
literal		::= Boolean | integer | hexint | real | string | op
op		::= "+" | "" | "*" | "/"
invocation	::= name | external
name		::= id ( "." id )*
id		::= letter ( letter | digit )*
external	::= "$" name
application	::= invocation "[" item* "]"
selection	::= "(" term "|" item* "|" item* ")"	-- Algol 68 style conditional
node		::= "{" item* "}"
sequence	::= "(" item* ")"
binding	::= name bindingMode rhs
bindingMode ::= "=" | ":" | ":=" | "←"
rhs		::= value | op term | "'" item* "'" | "[" [ invocation ] "|" binding* "]"
property	::= invocation "#"
label		::= id ":!" | name "!" | name "@"

SEMANTICS

R: expression > environment > expression			-- Reduction
T: expression > environment > environment			-- Transformation
R&T<e>(E) denotes the pair  R<e>(E); T<e>(E)

[Unless explicitly given below, T<construct>(E) = E.]

R<primary op term>(E) = R<primary>(E) op R<term>(E)

R<literal>(E) = literal

R&T<id>(E) = R&T<valOf(id, E)>(E)

R&T<name "." id>(E) = R&T<valOf(id, R<name>(E))>(E)

R<"$" name>(E) = "$" name

R<invocation "[" item* "]">(E) = apply(invocation, R<item*>(E), E)

R&T<"(" term "|" item1* "|" item2* ")">(E) =
			if R<term>(E) then R&T<item1*>(E) else R&T<item2*>(E)

R&T<"{" item* "}">(E) = "{" R<"Sub" item*>([Null | "Outer" "=" E]) "}";
	      locVal("Outer", (T<"Sub" item*>([Null | "Outer" "=" E])))

R&T<"(" item* ")">(E) = "(" R<item*>(E) ")" ; T<item*>(E)

R<>(E) = Nil

R&T<item1 item*>(E) = R<item1>(E) R<item*>(T<item1>(E));
					  T<item*>(T<item1>(E))

R&T<n m rhs>(E) = Nil; bind(n, m, R<rhs>(E), E)
	<n m op term> = <n m n op term>		-- Syntactic sugar

R<"'" item* "'">(E) = item*			--Usable only in rhs of binding

R<"[" invocation "|" binding* "]">(E) =
	[T<binding*>([R<invocation>(E) | "Outer" "=" E]) | "Outer" "=" Null]
R<"[|" binding* "]">(E) = [T<binding*>([Null | "Outer" "=" E]) | "Outer" "=" Null]

R<invocation "#">(E) = R<invocation>(E) "#"

R<label>(E) = label

	-- Subsidiary definitions for R&T

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

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

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

apply(invocation, value*, E) =
    CASE R<invocation>(E) OF
	"$equal"	=> value1 = value2
	"$greater"	=> value1 > value2
	. . .
	"$subscript"	=> value1[value2]	-- value1: sequence, value2: int
	"$contents"	=> C<value*>
	"$properties"	=> P<value*>(E)
	"$marks"	=> M<value*>(E)
	"$references" => U<value*>(E)
    ELSE		=> R<invocation>([E | "Value" "=" value*])

bind(id, m, val, E) =
	bindingOf(id, E) = "="	=> E			-- Can't rebind constants
	m = ":=" 			=> assign(id, val, E) -- Assign at right level
	True				=> [E | id m val]

bind(id "." n, m, val, E) = [E | id bindingOf(id, E) bind(n, m, val, valOf(id, E))]

assign(id, val, E) =
	locBinding(id, E) = ":"	=> [E | id ":" val]
	bindingOf(id, E) = ":"	=> bind("Outer." id, ":=", val, E)
	True				=> E 			-- Can only assign to vars

NOTATION FOR ENVIRONMENTS

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

SEMANTICS OF PROPERTIES, MARKS, REFERENCES (uses), CONTENTS

P: expression > environment > expression		-- Sequence of properties
M: expression > environment > expression		-- Sequence of marks
U: expression > environment > expression		-- Sequence of references
P&M&U<e>(E) denotes the triple  P<e>(E); M<e>(E); U<e>(E)

[These functions all return the empty list, Nil, except as specified below.]

P<invocation "#">(E) = R<invocation>(E)

M<name "!">(E) = prefixes(name)

U<name "@">(E) = prefixes(name)

P&M&U<invocation>(E) = P&M&U<R<invocation>(E)>(E)

P&M&U<"(" item* ")">(E) = P&M&U<item*>(E)

P&M&U<item1 item*>(E) = P<item1>(E) P<item*>(T<item1>(E));
				M<item1>(E) M<item*>(T<item1>(E));
				U<item1>(E) U<item*>(T<item1>(E))

prefixes(id) = id
prefixes(name "." id) = name "." id prefixes(name)

C: expression > expression

C<value> = value
C<property> = C<label> = Nil


VALUE SPACE

Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		labels: A123!, anId!, Paragraph.Example!
		external names: $name
		the empty environment: Null
		the empty list: NIL
	sequences of values
	unevaluated expressions
	environments

DISCUSSION

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 bind(id, ":=", val, 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 locVal("Outer").  The (implicit) "outermost" environment binds
each id to the external name $id.

Nodes are delimited by brackets.  The contents of each node are implicitly
prefixed by Sub, which will generally be bound in the containing environment
to a quoted expression performing an environment transformation, and perhaps
supplying some properties and marks.

Parentheses are used to denote a sequence value.  to delimit the argument list of
an operator.  Square brackets are used to denote a new environment value, which
behaves much like a record.


Semantics of labels:

A mark name! on a node makes that node a "target" of the label name (and its
prefixes); a reference name@ makes it a "source."  The "main" identifier of a
label must be declared (using name:!) at the root of a subtree containing all its
sources and targets.  The label represents a set of directed arcs, one from each of
its sources to each of its destinations.  Multiple marks make the node a target of
in multiple labels.  A unique label on a node places it in a singleton set, i.e.,
identifies it uniquely.


				OTHER NOTES

It should be clarified that the "view" of the dominant structure is ALWAYS
controlled by the properties of its nodes.  (E.g., text is not always there to be
"shown".)

Conservative rules for editor treatment of script subtrees created by other editors:
-It's OK to display a node if you understand at least one of its properties.
-It's OK to edit a node if you understand ALL of its (local) properties, and either
don't remove any of them or also understand ALL properties of its parent.
-It's OK to copy a node if that doesn't move any labels outside their scope, and
you understand ALL properties of its new parent.
-it's OK to delete a (subtree rooted at a) node if you understand ALL properties
of its parent.

The presentation of this material could be clarified by a table that relates
constructions in the notation to their intended uses and meanings.

Put in contents if:				Put in environment if:
	effect is local to node			has scope
	is directly edited				is only indirectly edited
	is to be bound locally			needs delayed or global binding


			CONSCIOUSLY POSTPONED

Lambda expressions.

Sets of properties, etc. (Cf. Mitchell's Font example.)
	SET/LIST operators ($append $union ?)



				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.

Edited by Jim H. on 20 Aug. 1981 5:29 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish syntactically between properties (marks) and labels.
	only the "main" id of a label is declarable.
	eliminate  as an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.
	update semantic equations for new grammar, etc.
	fix treatment of unbound qualified names (now produce Nil).

Edited by Jim H. on 21 Aug. 1981 6:58 pm PDT (Friday).
	restore $val.
	move quoting to rhs, allow quoted primaries without parentheses.
	allow an op to be the rhs of a definition.
	eliminate the functions operate, apply, eval by back substitution.
	change semantics of () to allow "record" construction without $env.

Edited by Jim H. on 24 Aug. 1981 6:08 pm PDT (Monday).
	"It's OK to edit a node if you understand ALL of its (local) properties, and
		either don't remove any of them or also understand ALL properties
		of its parent."
	"Put in contents if:				Put in environment if: ..."
	Add connection syntax to syntactically rule out a+←'b.

Edited by Jim H. on 25 Aug. 1981 11:33 am PDT (Tuesday).
	Syntactically separate label references and name invocation.
	Put in distinct syntax in rhs for environment construction.
	Informal semantics of labels.
	( ... ) > [ ... ] in applications; permitting ( ... ) as a primary.

Edited by Jim H. on 25 Aug. 1981 4:08 pm PDT (Tuesday).
	Add sequence as a nonterminal to the syntax.
	State the formal semantics of labels and properties.
	Reorder presentation (hopefully to improve readability).

Edited by Jim H. on 28 Aug. 1981 2:08 pm PDT (Friday).
	' ... ' in rhs
	Restore infix operators, right to left.
	Modify syntax to rule out more nonsense, add semantically meaningful
		nonterminals.
	Introduce special syntax for selections.
	Eliminate side-effects for $subscript (actually, all applications).
	Add application of defined functions.
	Note that Value[ ... ] allows use of temporary (hidden) local definitions,
		Nil[ ... ] allows placement of hidden nodes.
	( ... ) creates list/sequence values (without hiding bindings).
	Tidy up definition of assign, using bind("Outer." ...).
	Introduce value nonterminal into grammar (rule out more nonsense).
	rhs	::= ... | "[" [ lookup ] "|" binding* "]" .
	Change nonterminal lookup to invocation.
	Remove $ name from literal (to invocation).
	Add node operators:
		$properties						-- All #'s
		$marks						-- All !'s
		$references						-- All @'s
		$contents						-- The rest (fringe)
	Restrict $subscript just to sequences, not nodes.


*start*
22301 00024 US 
Date: 4 Sept. 1981 4:39 pm PDT (Friday)
From: Horning.pa
Subject: Current Level 0/1 Interdoc status/rev. 32
To: Mitchell, Horning, Lampson

[Candidate for circulation to Interdoc↑, with history log removed.]

Edited by Jim H. on 4 Sept. 1981 4:03 pm PDT (Friday).
	Compressed syntactic example.
	Re-order sections, in preparation for circulation to Interdoc↑.
	Label ::= Mark | Source | Target | Link
	R&T&P&M&U > R&B&M&S&T
	external names > universal names
	remove op as literal
	$ hidden #
	Properties(present/absent)/Attributes(have values and scopes)
	Format for description of standard properties
	Editor levels
		Internal definition/invocation
		Nesting of nodes
		Links
	Hints to implementors:
		environment restoration points
		coding tricks for common structures

-------------------
Open questions:
	We should rethink our character assignments.
		check our characterset for disjointness with
			Interpress.DoubtfulChars.
		enlarge op with a few more single-character operators?  %, &, \
	Better way to present semantics?

Not done:

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

				STANDARD CARDS

1. WE ARE DESIGNING A STANDARD FOR INTERCHANGE, NOT EDITING.

2. EVERY SCRIPT IS PARSED BEFORE BEING INTERPRETED.

3. STANDARDIZE CONCEPTS, NOT NAMES.

4. COMBINING DOCUMENTS IS AN EDITOR, NOT AN INTERCHANGE, TASK.

5. GENSYM IS AN EDITOR FUNCTION.

6. CHARACTER-SET AND LEXICAL ISSUES CAN BE RESOLVED AT THE END.

7. GET THE TECHNICAL BASIS RIGHT BEFORE WORRYING ABOUT THE
POLITICAL ISSUES.


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

We envision an Interdoc script being input and viewed in any manner
equivalent to the following:

Parse the entire script, repeatedly
- reducing each expression to its "dominant structure," containing only literals
and structural delimiters, by replacing identifiers by the values to which they
are bound in the current environment, by applying operators, and by removing
binding items,
- determining the properties of each node from its marks,
- recording the sources and targets for all links, and
- transforming the environment as indicated by the binding items (recording the
relevant attributes for each node in a form convenient to the particular editor).


				BASIC INTERDOC

SYNTACTIC EXAMPLE

{Book.example!		      -- Links to this from Book@ and Book.example@
ExampleParagraph				-- Invokes a definition
$UniqueMark12356#			-- Adds a mark
Font←[Font | size←10*pt face←bold]
factorial←'(LT[Value 2] | 1 | Value*factorial(Value-1))'
a:='NOT[EQ[margins.left factorial[5]]]' margins.right←100 r=12.5*pt
(a | margins.left←+5 margins.right←5 | margins.left+←10) -- conditional: Algol68
<text for this node>
}

-- Or, using short identifiers, and omitting comments and unnecessary spaces:

{b.e!ep um#f←[f|s←10*pt fc←bo]fa←'(l[Value 2]|1|Value*fa(Value-1))'
a:='n[e[m.l fa[5]]]'m.r←100 r=12.5*pt(a|m.l←+5 m.r←5|m.l+←10)<text for this node>}

GRAMMAR

item		::= value | binding | label
value		::= term | node | sequence
term		::= primary | primary op term
op		::= "+" | "" | "*" | "/"
primary	::= literal | invocation | application | selection
literal		::= Boolean | integer | hexint | real | string
invocation	::= name | universal
name		::= id ( "." id )*
id		::= letter ( letter | digit )*
universal	::= "$" name
application	::= invocation "[" item* "]"
selection	::= "(" term "|" item* "|" item* ")"
node		::= "{" item* "}"
sequence	::= "(" item* ")"
binding	::= name bindingMode rhs
bindingMode ::= "=" | ":" | ":=" | "←"
rhs		::= value | op term | "'" item* "'" | "[" [ invocation ] "|" binding* "]"
label		::= mark | link
mark		::= invocation "#"
link		::= name "@" | name "!" | id "@!"

SEMANTICS: REDUCTION AND BINDING

R: expression, environment > expression			-- Reduction
B: expression, environment > environment			-- Bindings
R&B<construct>(E) denotes the pair  R<construct>(E); B<construct>(E)

[Unless explicitly given below, B<construct>(E) = E.]

R<primary op term>(E) = R<primary>(E) op R<term>(E)

R<literal>(E) = literal

R&B<id>(E) = R&B<valOf(id, E)>(E)

R&B<name "." id>(E) = R&B<valOf(id, R<name>(E))>(E)

R<"$" name>(E) = "$" name

R<invocation "[" item* "]">(E) = apply(invocation, R<item*>(E), E)

R&B<"(" term "|" item1* "|" item2* ")">(E) =
			if R<term>(E) then R&B<item1*>(E) else R&B<item2*>(E)

R&B<"{" item* "}">(E) = "{" R<"Sub" item*>([Null | "Outer" "=" E]) "}";
	      locVal("Outer", (B<"Sub" item*>([Null | "Outer" "=" E])))

R&B<"(" item* ")">(E) = "(" R<item*>(E) ")" ; B<item*>(E)

R<>(E) = Nil

R&B<item1 item*>(E) = R<item1>(E) R<item*>(B<item1>(E));
					  B<item*>(B<item1>(E))

R&B<name mode rhs>(E) = Nil; bind(name, mode, R<rhs>(E), E)
	<name mode op term> = <name mode name op term>	-- Syntactic sugar

R<"'" item* "'">(E) = item*			--Usable only in rhs of binding

R<"[|" binding* "]">(E) = [B<binding*>([Null | "Outer" "=" E]) | "Outer" "=" Null]

R<"[" invocation "|" binding* "]">(E) =
	[B<binding*>([R<invocation>(E) | "Outer" "=" E]) | "Outer" "=" Null]

R<invocation "#">(E) = R<invocation>(E) "#"

R<link>(E) = link

	-- Subsidiary definitions for R&T

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

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

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

apply(invocation, value*, E) =
    CASE R<invocation>(E) OF
	"$equal"	=> value1 = value2
	"$greater"	=> value1 > value2
	. . .
	"$subscript"	=> value1[value2]	-- value1: sequence, value2: int
	"$marks"	=> "(" M<inner(value1)> ")"
	"$links"	=> "(" L<inner(value1)> ")"
	"$sources"	=> "(" S<inner(value1)> ")"
	"$targets"	=> "(" T<inner(value1)> ")"
	"$contents"	=> "(" C<inner(value1)> ")"
    ELSE	=> R<invocation>([[Null | "Outer" "=" E] | "Value" "=" value*])

inner("{" value* "}") = value*

bind(id, mode, value, E) =
	bindingOf(id, E) = "="	=> E			  -- Can't rebind constants
	mode = ":=" 			=> assign(id, value, E) -- Assign at right level
	True				=> [E | id mode value]

bind(id "." name, mode, value, E) =
		[E | id bindingOf(id, E) bind(name, mode, value, valOf(id, E))]

assign(id, value, E) =
	locBinding(id, E) = ":"	=> [E | id ":" value]
	bindingOf(id, E) = ":"	=> bind("Outer." id, ":=", value, E)
	True				=> E 			-- Can only assign to vars

NOTATION FOR ENVIRONMENTS

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

SEMANTICS OF MARKS, LINKS, CONTENTS

M: expression > expression			-- Sequence of marks
L: expression > expression			-- Sequence of links
S: expression > expression			-- Sequence of source links
T: expression > expression			-- Sequence of target links
C: expression > expression			-- Content of node

[These functions all return the non-value, Nil (which does not lengthen a
sequence), except as specified below.]

M<name "#"> = name
M<"(" item* ")"> = M<item*>
M<item1 item*> = M<item1> M<item*>

L<id "@!"> = id
L<"(" item* ")"> = L<item*>
L<item1 item*> = L<item1> L<item*>

S<name "!"> = prefixes(name)
S<"(" item* ")"> = S<item*>
S<item1 item*> = S<item1> S<item*>

T<name "@"> = name
T<"(" item* ")"> = T<item*>
T<item1 item*> = T<item1> T<item*>

C<value> = value
C<label> = Nil

prefixes(id) = id
prefixes(name "." id) = name "." id prefixes(name)



VALUE SPACE

Expressions in an Interdoc script may denote
	literal values:
		Booleans: (F, T)
		integers: ... -3, -2, -1, 0, 1, 2, 3, ...
		reals: 1.2E5, . . .
		strings: <this is a string>
		marks: Xerox.Laurel.Message#
		links: A123@!, Paragraph.Example!, anId@
		universal names: $Authority.Sub.id
	nodes
	sequences of values
	unevaluated expressions
	environments

DISCUSSION

Each environment, E, initially contains only its "inherited" environment (bound
to the id Outer).  Most bindings take place directly in E.  To allow for
"persistent" bindings, the value of a bind(id, ":=", val, 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.

If the rhs of a binding is surrounded by single quotes, it will be evaluated in
the environments where the name is invoked, rather than the environment in
which the binding is made.

When an id is referred to and locBinding(id, E)=None, then the value is sought
recursively in locVal("Outer").  The (implicit) "outermost" environment binds
each id to the "universal" name $id.

Nodes are delimited by brackets.  The contents of each node are implicitly
prefixed by Sub, which will generally be bound in the containing environment
to a quoted expression performing some bindings, and perhaps supplying some
labels (marks and links).

Parentheses are used to delimit sequence values.  Square brackets are used to
delimit the argument list of an operator application and to denote environment
constructors, which behave much like records.

Expressions involving the four infix ops (+, , *, /) are evaluated right-to-left
(a la APL); since we expect expressions to be short, we have not imposed
precedence rules.

The notation for selections (conditionals) is borrowed from Algol 68:
	( <test> | <true part> | <false part> )
This is consistent with our principles of using balanced brackets for compound
constructions and avoiding syntactically reserved words; the true part and false
part may each contain an arbitrary number of items (including none). 


A label N! on a node makes that node a "target" of the link N (and its prefixes);
a label N@ makes it a "source."  The "main" identifier of a link must be declared
(using id@!) at the root of a subtree containing all its sources and targets.  The
link represents a set of directed arcs, one from each of its sources to each of its
targets.  Multiple target labels make a node the target of multiple links.  A target
label that appears only on a single node places it in a singleton set, i.e.,
identifies it uniquely.


				OTHER NOTES

Conservative rules for editor treatment of Interdoc subtrees created by other
editors:
-It's OK to display a node if you understand at least one of its marks.
-It's OK to edit a node if you understand ALL of its (local) marks, and either
don't remove any of them or also understand ALL marks of its parent.
-It's OK to copy a node if that doesn't move any labels outside their scope, and
you understand ALL marks of its new parent.
-it's OK to delete a (subtree rooted at a) node if you understand ALL marks of its
parent.

The "view" of the dominant structure is ALWAYS controlled by the marks on its
nodes.  (E.g., text is not always there to be "shown.")  $hidden# means that a
node is intended not to be viewed at the point where it occurs in the dominant
structure; such nodes will generally be targets of links, placed remotely from
their sources (uses) to extract attributes from an environment (e.g., page or figure
numbers for references).

We will try to use the term "property" to refer to a characteristic associated with
a node by means of a label (mark or link) and "attribute" to refer to a
characteristic whose value is determined by the environment.  Properties are
either present (locally) or absent, whereas attributes commonly have values that
apply throughout a scope.

Level 2 of the standard will be primarily concerned with the definition of
standard properties that are expected to be shared among editors.  For each
standard property, it will describe
	- the associated universal mark that denotes it,
	- the assumptions that this mark implies about the contents of a node
		(values that must/may be present and their intended intepretation),
	- the assumptions that this mark implies about the environment of a node
		(attributes that must be present and their intended intepretation).

Attributes are "relevant" to a node if they are assumed by any of its marks.
In general, a node's environment will also contain bindings for many "latent"
attributes that are either relevant to its ancestors (and inherited by default) or
are potentially relevant to its descendants.

Attributes are inherited only via environments following the dominant
structure.  Thus the choice of a dominant structure to represent scripts from a
particular editor will be strongly influenced by expectations about inheritance. 

Put a value in contents if:			Put a value in environment if:
	effect is local to node			has scope
	is directly edited				is only indirectly edited
	is to be bound locally			needs delayed or global binding

The presentation of this material could be clarified by a table that relates
constructions in the notation to their intended uses and meanings.


				EDITOR LEVELS

Just as with Interpress, the Interdoc standard will apply to editors with varying
capabilities, and it will be important to define some structure to the space of
possibilities.  Dimensions in which we foresee reasonable variation are:

- Invocation/Application: Only built-in definitions - definitions in script.

- Dominant structure: Nodes cannot nest - nesting allowed.

- Other structure: No links - links allowed.


			HINTS TO IMPLEMENTORS

Environment restoration: Some constructs in the language are not allowed to have
a "net effect" on the environment, even though they may contain internal
bindings that will be in effect for some or all of their substructures.  Thus, a
program to process Interdoc scripts must make provision for restoration of saved
environments.  The amount of bookkeeping required to do this can be minimized
by the following observations:
- A rhs always produces a value (which may be an environment), which is
then bound to a name in the environment that obtained when the binding was
encountered.  Thus, occurrence of a bindingMode (=, :, :=, ←) signals a potential
restoration point.
- Any application (but not every invocation), any term containing infix ops,
and any mark will leave the environment unchanged.  Thus the appearance of
an operator, the bracket surrounding an argument list, or # signals a potential
restoration point; the environment to be saved is the one BEFORE the invocation
to its left.  (One-character lookahead before invocation is prudent.)
- Environments are NOT restored at the end of sequences.
- The environment at the end of a node is the final value of the Outer
component of the node's environment; unless the node contains persistent (:=)
bindings, this will be the same as the environment just prior to the node.

Coding tricks for common structures: 
- Attributes that tend to persist across boundaries in the dominant structure (e.g.,
Bravo character looks, which persist from paragraph to paragraph unless
explicitly changed by the user) should generally be represented by VAR (:)
bindings at a high-level node in the script; changes would then be represented
by persistent (:=) bindings at the points where they occur.
- Persistent bindings can also be used to record changes to "running" information
(e.g., section number, figure number).
- Information (e.g., marks) repeated in all subnodes of a node should be bound to
Sub, and hence associated with the subnodes implicitly.
- Very compact encodings can often be obtained by using single-character id's
for common sequences of items; each editor can have its own set, tuned to its
own usages.  When reading a script produced by a different editor, it will be
necessary to know the bindings for these abbreviations.


			CONSCIOUSLY POSTPONED

Lambda expressions.

Sets (Cf. Mitchell's Font example.)
	SET/LIST operators ($append $union ?)

Extend selection to CASE?


				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. 

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.

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.

Edited by Mitchell, 7 Aug. 1981 4:40 pm PDT (Friday)
Fixed error in semantics when exchanging the use of {}s and ()s.

Edited by Horning 13 Aug. 1981 4:47 pm PDT (Thursday).
	E(id) > locVal(id, E) 	--Remove conflict with f(E).
	Outer > "Outer"
	Const > "="
	id lookup rule modified (R & T<id>)
	[E | id←e, m] > [E | id m e]
	"." as infix op
	expressions are evaluated left-to-right (except for binding operator)
	Reverse VAL/ENV default for parens.
	bindq > bind
	binding > bindingMode
	expand definition of apply inline
	default T<construct>(E) = E
	add comments to semantic equations

-------------------
R<>(E) = Nothing						-- The empty expression

							-- 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<literal>(E) = literal

R<id>(E) = if bindingOf(id, E)=None then id else R<valOf(id, E)>(E)
T<id>(E) = if bindingOf(id, E)=None then E else T<valOf(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<"NOT" p>(E) = if R<p>(E) then False else True

R<p1 op p2>(E) = 
	op = "." 	=> R<p2>([R<p1>(E) | "Outer" = E])
	op = "+"	=> R<p1>(E)+R<p2>(E)
	. . .

R<n m op e>(E) = Nothing						-- Empty list
T<n m e>(E) = bind(n, m, R<e>(E), E)
T<n m "'" e>(E) = bind(n, m, e, E)
T<n m op e>(E) = bind(n, m, R<n op e>(E), E)

R<"{" labels e* "}">(E) = "{" labels R<Sub e*>([Null | "Outer" = E]) "}"
T<"{" labels e* "}">(E) = locVal("Outer", (T<"ENV("Sub e*")">(E)))

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

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

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

Edited by Jim Horning 17 Aug. 1981 10:49 am PDT (Monday)
	R&T<>
	Nothing > ""

Edited by Jim H. on 17 Aug. 1981 4:58 pm PDT (Monday)
	Remove side-effects from all expressions.
	Parentheses purely for grouping (don't hide environment transformations).
	#label > label !
	labels within nodes

Edited by Jim H. on 19 Aug. 1981 9:52 am PDT (Wednesday).
	Rewrite <n m op e> as syntactic sugar.
	structured labels
	re-introduce apply function in R&T<p1 op p2>
	correct syntax for "."
	% for opening an environment (also replaces ENV?)

Edited by Jim H. on 19 Aug. 1981 6:55 pm PDT (Wednesday).
	Drop "%"; ENV() is now the only environment-constructing operator.
	Add SUB operator (first operand: sequence only, second: number only).
	Add atoms, as distinct from ids.
	Fix lhs op rhs syntax.

Edited by Jim H. on 20 Aug. 1981 5:29 pm PDT (Thursday).
	resolve pending questions as per message of 20 Aug. 1981 12:29 pm PDT.
	distinguish syntactically between properties (marks) and labels.
	only the "main" id of a label is declarable.
	eliminate  as an id character.
	eliminate op ids from grammar.
	restructure the grammar for "functional" notation for operators.
	update semantic equations for new grammar, etc.
	fix treatment of unbound qualified names (now produce Nil).

Edited by Jim H. on 21 Aug. 1981 6:58 pm PDT (Friday).
	restore $val.
	move quoting to rhs, allow quoted primaries without parentheses.
	allow an op to be the rhs of a definition.
	eliminate the functions operate, apply, eval by back substitution.
	change semantics of () to allow "record" construction without $env.

Edited by Jim H. on 24 Aug. 1981 6:08 pm PDT (Monday).
	"It's OK to edit a node if you understand ALL of its (local) properties, and
		either don't remove any of them or also understand ALL properties
		of its parent."
	"Put in contents if:				Put in environment if: ..."
	Add connection syntax to syntactically rule out a+←'b.

Edited by Jim H. on 25 Aug. 1981 11:33 am PDT (Tuesday).
	Syntactically separate label references and name invocation.
	Put in distinct syntax in rhs for environment construction.
	Informal semantics of labels.
	( ... ) > [ ... ] in applications; permitting ( ... ) as a primary.

Edited by Jim H. on 25 Aug. 1981 4:08 pm PDT (Tuesday).
	Add sequence as a nonterminal to the syntax.
	State the formal semantics of labels and properties.
	Reorder presentation (hopefully to improve readability).

Edited by Jim H. on 28 Aug. 1981 2:08 pm PDT (Friday).
	' ... ' in rhs
	Restore infix operators, right to left.
	Modify syntax to rule out more nonsense, add semantically meaningful
		nonterminals.
	Introduce special syntax for selections.
	Eliminate side-effects for $subscript (actually, all applications).
	Add application of defined functions.
	Note that Value[ ... ] allows use of temporary (hidden) local definitions,
		Nil[ ... ] allows placement of hidden nodes.
	( ... ) creates list/sequence values (without hiding bindings).
	Tidy up definition of assign, using bind("Outer." ...).
	Introduce value nonterminal into grammar (rule out more nonsense).
	rhs	::= ... | "[" [ lookup ] "|" binding* "]" .
	Change nonterminal lookup to invocation.
	Remove $ name from literal (to invocation).
	Add node operators:
		$properties						-- All #'s
		$marks						-- All !'s
		$references						-- All @'s
		$contents						-- The rest (fringe)
	Restrict $subscript just to sequences, not nodes.