
									81






				Appendix A


			 Small-X Command Summary

									82


     ---------------------------------------------------------------------
                           Small-X Command Summary
   Commands                                       STM Commands

   STM            places sx in STM mode           ADD     add an object
   RULES          define sx rules                         to STM
   ENGINE         starts inference engine         REMOVE  erase an 
   EXIT           returns user to DOS                     object in STM
   SAVE file      saves STM to a file             BIND    bind a variable
   READ file      restores STM from a file                to an object
   MEMORIZE file  saves all rules to a file       UNBIND  remove a 
   REMEMBER file  restores rules from a file              binding
   STEP           enables step mode               READ    get an object
   NOSTEP         disables step mode                      from keyboard
   TRACE          enables trace mode              WRITE   write an object
   NOTRACE        disables trace mode             HALT    stop inference
   TERMINAL       sets input stream to console            engine
   LIST STM/RULES lists STM or RULES to console   COMPUTE do calculations
   CLEAR STM/RULES clears all STM or rules        OPEN    open external files
   SHOW rulename  displays a rule                 CLOSE   close external files
   STORAGE        displays available storage      RESET   resets a fired rule
   DELETE rule    deletes a specified rule        FIRE    fires rule actions
   HELP           gets help for commands/actions  RUN     execute external
   DOS		  execute DOS commands                    programs
   CLOAD file     load a CSAVEd file              RESTRICT set value limits
   CSAVE file     compile a rule program                   for variables
   FORWARD        set inference engine forward    MODIFY  change a rule value
   BACKWARD       set inference engine backward
   GOAL           set backward chaining goal
   STATUS         display status data
   LOWER          distinguish between upper and
                  lower case
   UPPER          convert all to upper case
   QUIET          do not echo input
   NOQUIET        echo input
     ---------------------------------------------------------------------

									83










				Appendix B


			 Sample Expert System

		  Simple Automobile Problem Diagnostics

									84


	% Sample Expert System 2 - Car Problems
	% May 20, 1985
	%
	IF NOT IN-MEMORY(dummy) THEN
	{
		WRITE CLEAR
		WRITE NEW-LINE
		WRITE NEW-LINE
		WRITE 'Car Problem Expert System'
		WRITE NEW-LINE
		WRITE NEW-LINE
		WRITE 'Please answer each of the questions yes or no.'
		WRITE NEW-LINE
	}
	IF NOT IN-MEMORY(#cranks) THEN
	READ STRING 'Does engine crank ? ' #cranks
	%
	IF #cranks = yes THEN
	BIND #charged yes
	%
	IF #cranks = no THEN
	BIND #charged no
	%
	IF #charged = no THEN
	{
		WRITE 'You need to charge battery -- $5.'
		WRITE NEW-LINE
	}
	%
	IF #charged = yes AND
	   NOT IN-MEMORY(#empty) THEN
	READ STRING 'Is fuel indicator reading empty ? ' #empty
	%
	IF #empty = yes THEN
	{
		WRITE 'You need to fill fuel tank -- $10.'
		WRITE NEW-LINE
	}
	%
	IF #charged = no AND
	   NOT IN-MEMORY(#lit) THEN
	READ STRING 'Is battery indicator lit ? ' #lit
	%
	IF #charged = no AND
	   #lit = yes THEN
	{
		WRITE 'You must rebuild alternator -- $50.'
		WRITE NEW-LINE
	}

									85










				Appendix C


			   Sample Expert System

			     Mock Tax Advisor

									86
	% Sample Expert System  -  June 1, 1985
	%
	% Mock Tax Advisor
	%
	%
	if not in-memory(dummy) then
	{
		write clear
		write 'Mock Tax Advisor'
		write new-line
		write new-line
	}
	%
	%
	if not in-memory(#age) then
	read int 'What is your age ?  ' #age
	%
	%
	if #married = yes and
	   not in-memory(#ageS) then
	read int 'What is spouses age ?  ' #ageS
	%
	%
	if #married = no and
	   #age < 65 and
	   #totinc > 3299.0 then
	bind #mustfile yes
	%
	%
	if #married = yes and
	   #age > 64 and
	   #totinc > 3299.0 then
	bind #mustfile yes
	%
	%
	if #married = yes and
	   #ageS < 65 and
	   #age < 65 and
	   #cominc > 5400.0 then
	bind #mustfile yes
	%
	%
	if #married = yes and
	   #age >= 65 and
	   #ageS < 65 and
	   #cominc > 6399.0 then
	bind #mustfile yes
	%
	%
	if #married = yes and
	   #age < 65 and
	   #ageS >= 65 and
	   #cominc > 6399.0 then
	bind #mustfile yes

									87

	%
	%
	if #married = yes and
	   #ageS > 64 and
	   #age > 64 and
	   #cominc > 7399.0 then
	bind #mustfile yes
	%
	%
	if #mustfile = yes then
	{
		write 'You must file an Income Tax Return'
		write new-line
	}
	%
	%
	if #mustfile = yes and
	   #married = yes and
	   #filingjointly = yes then
	{
		write 'You should file a joint return with your spouse'
		write new-line
	}
	%
	%
	if #mustfile = yes and
	   #married = yes and
	   #filingjointly = no then
	{
		write 'You and your spouse should file separate returns'
		write new-line
	}
	%
	%
	if #mustfile = yes and
	   #itemize = yes then
	{
		write 'Itemize to minimize tax'
		write new-line
	}
	%
	%
	if #mustfile = yes and
	   #married = yes and
	   #filingjointly = no and
	   #itemize = yes then
	{
		write 'Your spouse should itemize also'
		write new-line
	}

									88

	%
	%
	if #married = yes and
	   #filingjointly = yes and
	   #totded > 3399.0 then
	bind #itemize yes
	%
	%
	if #married = yes and
	   #filingjointly = no and
	   #totded > 1700.0 then
	bind #itemize yes
	%
	%
	if #married = yes and
	   #totded > 2300.0 then
	bind #itemize yes
	%
	%
	if #married = no and
	   #totded > 2300.0 then
	bind #itemize yes
	%
	%
	if in-memory(#totadj) and
	   #totadj > 0.0 or
	   #itemize = yes and
	   #mustfile = yes then
	{
		write 'You must file the long form 1040'
		write new-line
	}
	%
	%
	if not in-memory(#married) then 
	read string 'Are you married ?  ' #married
	%
	%
	if not in-memory(#mustfile) then
	bind #mustfile no
	%
	%
	if #mustfile = yes and
	   #itemize = no then
	{
		write 'You would be better off not itemizing this year'
		write new-line
	}
	%
	%
	if #mustfile = yes and
	   #married = yes and
	   #filingjointly = no and
	   #itemize = no then
	{
		write 'Your spouse should not itemize either'
		write new-line
	}

									89

	%
	%
	if not in-memory(#totinc) then
	read float 'What is your total income ?  ' #totinc
	%
	%
	if #married = yes and
	   not in-memory(#totincS) then
	read float 'What is spouses total income ?  ' #totincS
	%
	%
	if not in-memory(#totex) then
	{
		bind #totex 1
		bind #comex 1
	}
	%
	%
	if #age > 64 then
	{
		compute #totex <- #totex + 1
		compute #comex <- #comex + 1
	}
	%
	%
	if #married = yes then
	{
		bind #exS 1
		compute #comex <- #comex + 1
	}
	%
	%
	if #married = yes and
	   #ageS > 64 then
	{
		compute #exS <- #exS + 1
		compute #comex <- #comex + 1
	}
	%
	%
	if not in-memory(#blind) then
	read string 'Are you blind ?  ' #blind
	%
	%
	if #blind = yes then
	{
		compute #totex <- #totex + 1
		compute #comex <- #comex + 1
	}
	if not in-memory(#blindS) 
	   and #married = yes then
	read string 'Is your spouse blind ?  ' #blindS
	%
	%

									90

	if #married = yes and
	   #blindS = yes then
	{
		compute #exS <- #exS + 1
		compute #comex <- #comex + 1
	}
	%
	%
	if not in-memory(#children) then
	read string 'Do you have any children ?  ' #children
	%
	%
	if #children = yes then
	read int 'How many children do you have ? ' #nochildren
	%
	%
	if #children = yes then
	{
		write 'How many of the '
		write #nochildren
		write 'that you have, '
		write new-line
		write ' do you provide more than 50% of the childs support or'
		write new-line
		write ' is a full time day school student for five months '
		write 'of the year or '
		write new-line
		write ' makes less than $ 1000 per year ?  '
		read int #chiex
	}
	%
	%
	if #chiex > 0 then
	{
		compute #totex <- #totex + #chiex
		compute #comex <- #comex + #chiex
	}
	%
	%
	if in-memory(#totinc) and
	   in-memory(#totadj) then
	compute #aginc <- #totinc - #totadj
	%
	%
	if #married = yes and
	   in-memory(#totincS) and
	   in-memory(#totadjS) then
	compute #agincS <- #totincS - #totadjS
	%
	%
	if #married = yes and
	   in-memory(#totinc) and
	   in-memory(#totincS) then
	compute #cominc <- #totinc + #totincS
	%
	%

									91

	if not in-memory(#totded) then
	read float 'What are your total deductions ?  ' #totded
	%
	%
	if #married = yes and
	   not in-memory(#totdedS) then
	read float 'What are your spouses total deductions ?  ' #totdedS
	%
	%
	if #married = yes and
	   in-memory(#totded) and
	   in-memory(#totdedS) then
	compute #comded <- #totded + #totdedS
	%
	%
	if #married = no and
	   in-memory(#totex) and
	   in-memory(#txin) then
	{
		write 'For an unmarried taxpayer with '
		write #totex
		write new-line
		write 'exemptions look up your tax'
		write new-line
		write 'for your taxable income of '
		write #txin
		write new-line
		write 'in the tax tables'
		write new-line
		read float 'What is your total tax ? ' #tax
	}
	%
	%
	if #married = no and
	   #itemize = yes and
	   in-memory(#aginc) and
	   in-memory(#totded) then
	{
		compute #txin <- #aginc - #totded
		compute #txin <- #txin + 2300.0
	}
	%
	%
	if #married = no and
	   #itemize = no and
	   in-memory(#aginc) then
	compute #txin <- #aginc + 0.0
	%
	%

									92

	if #married = yes and
	   #itemize = yes and
	   in-memory(#totex) and
	   in-memory(#txini) then
	{
		write 'For a married taxpayer with '
		write #totex
		write new-line
		write 'exemptions look up your tax '
		write new-line
		write 'for your taxable income of '
		write #txini
		write new-line
		write 'in the tax tables'
		write new-line
		read float 'What is your total tax ? ' #txi
	}
	%
	%
	if #married = yes and
	   #itemize = no and
	   in-memory(#totex) and
	   in-memory(#aginc) then
	{
		write 'For a married taxpayer who will not itemize with '
		write #totex
		write new-line
		write 'exemptions look up tax for your taxable income of '
		write #aginc
		write new-line
		write 'in the tax tables'
		write new-line
		read float 'What is your total tax ? ' #tx0
	}
	%
	%
	if #married = yes and
	   #itemize = no and
	   in-memory(#exS) and
	   in-memory(#agincS) then
	{
		write 'For a married taxpayer whose spouse'
		write new-line
		write 'will not itemize with '
		write #exS
		write ' exemptions look up spouses  '
		write new-line
		write ' tax for your taxable income of '
		write #agincS
		write new-line
		write 'in the tax tables'
		write new-line
		read float 'What is your total tax ? ' #tx0S
	}
	%
	%

									93

	if #married = yes and
	   #itemize = yes and
	   in-memory(#exS) and
	   in-memory(#txiniS) then
	{
		write 'For a married taxpayer whose spouse will'
		write new-line
		write 'itemize with '
		write #exS
		write 'exemptions look up spouses tax '
		write new-line
		write 'for your taxable income of '
		write #txiniS
		write new-line
		write 'in the tax tables'
		write new-line
		read float 'What is your total tax ? ' #txiS
	}
	%
	%
	if #married = yes and
	   #itemize = yes and
	   in-memory(#txi) and
	   in-memory(#txiS) then
	{
		compute #tax <- #txi + 0.0
		compute #taxS <- #txiS + 0.0
	}
	%
	%
	if #married = yes and
	   #itemize = no and
	   in-memory(#tx0) and
	   in-memory(#tx0S) then
	{
		compute #tax <- #tx0 + 0.0
		compute #taxS <- #tx0S + 0.0
	}
	%
	%
	if #married = yes and
	   in-memory(#comtaxi) and
	   in-memory(#comex) then
	{
		write 'For a married taxpayer filing jointly with '
		write #comex
		write new-line
		write 'exemptions look up your tax'
		write new-line
		write 'for your taxable income of '
		write #comtaxi
		write new-line
		write 'in the tax tables'
		write new-line
		read float 'What is your total tax ? ' #comtax
	}
	%
	%

									94

	if #married = yes and
	   in-memory(#txi) and
	   in-memory(#txiS) and
	   in-memory(#tx0) and
	   in-memory(#tx0S) then
	{
		compute #sumtax <- #txi + #txiS
		compute #tx0sumtax <- #tx0 + #tx0S
	}
	%
	%
	if in-memory(#sumtax) and
	   in-memory(#comtax) or
	   #comtax < #sumtax or
	   #comtax < #tx0sumtax then
	bind #filingjointly yes
	%
	%
	if not in-memory(#totadj) then
	read float 'What are your total adjustments ?  ' #totadj
	%
	if not in-memory(#totadjS) and
	   #married = yes then
	read float 'What are spouses total adjustments ?  ' #totadjS
	%
	%
	if #married = yes and
	   in-memory(#aginc) and
	   in-memory(#totded) then
	{
		compute #txini <- #aginc - #totded
		compute #txini <- 1700.0 + #txini
	}
	%
	%
	if #married = yes and
	   in-memory(#agincS) and
	   in-memory(#totdedS) then
	{
		compute #txiniS <- #agincS - #totdedS
		compute #txiniS <- 1700.0 + #txiniS
	}
	%
	%
	if #married = yes and
	   in-memory(#txini) and
	   in-memory(#txiniS) then
	compute #comtxin <- #txini + #txiniS
	%
	%
	if #married = yes and
	   in-memory(#aginc) and
	   in-memory(#agincS) then
	compute #comtax0 <-- #aginc + #agincS
	%
	%

									95

	if in-memory(#comtax0) and
	   in-memory(#comtxin) and
	   #comtax0 < #comtxin then
	compute #comtax <- #comtax0 + 0.0
	%
	%
	if in-memory(#comtax0) and
	   in-memory(#comtxin) and
	   #comtax0 >= #comtxin then
	compute #comtax <- #comtxin + 0.0
	%
	%
	if #mustfile = yes and
	   #married = no and
	   in-memory(#totex) then
	{
		write 'The total number of exemptions you may claim is '
		write #totex
		write new-line
	}
	%
	%
	if #mustfile = yes and
	   #married = yes and
	   #filingjointly <> yes and
	   in-memory(#totex) and
	   in-memory(#exS) then
	{
		write 'The total number of exemptions you may claim is '
		write #totex
		write new-line
		write 'The total number of exemptions spouse may claim is '
		write #exS
		write new-line
	}
	%
	%
	if #mustfile = yes and
	   #married = yes and
	   #filingjointly = yes and
	   in-memory(#comex) then
	{
		write 'The total number of exemptions you may claim is '
		write #comex
		write new-line
	}
	%
	%
	if #mustfile = yes and
	   #married = yes and
	   #filingjointly = yes and
	   in-memory(#comtax) then
	{
		write 'Your total tax will be $  '
		write #comtax
		write new-line
	}
	%
	%

									96

	if #mustfile = yes and
	   #married = no and
	   in-memory(#tax) then
	{
		write 'Your total tax will be $  '
		write #tax
		write new-line
	}
	%
	%
	if #mustfile = yes and
	   #married = yes and
	   #filingjointly <> yes and
	   in-memory(#taxS) and
	   in-memory(#tax) then
	{
		compute #totaltax <- #taxS + #tax
		write 'Your total tax will be $  '
		write #tax
		write new-line
		write 'Your total spouses tax will be $  '
		write #taxS
		write new-line
		write 'Your grand total tax will be $  '
		write #totaltax
		write new-line
	}
	%
	%
	if #mustfile = no then
	{
		write 'You need not file a tax return this year'
		write new-line
	}
	%
	%
	if not in-memory(#itemize) then
	bind #itemize no
	%
	%
	if not in-memory(#filingjointly) then 
	bind #filingjointly no

									97








				Appendix D

			         Messages

									98

	Error Messages


	Like any other computer program, the small-X interpreter
	will let you know when it cannot process a command or 
	interpret a rule in rule memory that you entered. The way that
	small-X does this is to display an message. Messages in small-X 
	always begin with a ** and also end with a **. The following is 
	a list of messages and a brief explanation of each. 

									99

	** expecting integer **

		a READ action has the INT option specified. Any input
		other than an integer will cause this error to be 
		displayed. small-X requests an input again.

	** expecting real **

		a READ action has the REAL option specified. Any input
		other than a real number will cause this error to be 
		displayed. small-X requests an input again.

	** expecting string **

		a READ action has the STRING option specified. Any input
		other than a string will cause this error to be 
		displayed. small-X requests an input again.

	** expecting list **

		a READ action has the LIST option specified. Any input
		other than a list will cause this error to be 
		displayed. small-X requests an input again.

	** divide by 0 **

		a COMPUTE action with division has a 0 as the divisor.

	** no current object **

		! was used in a BIND or WRITE operation. ! has no
		value usually means that no condition was satisfied
		in a rule to give a value to !.

	** no self bindings **

		In a BIND action you cannot BIND a variable to
		itself. Change the action to remedy.

	** no circular ref **

		In a BIND action a variable cannot be bound to
		itself by being bound to several variables that
		eventually cause the variable to be bound to 
		itself as in:
				BIND #A #B
				BIND #B #C
				BIND #C #A
		Change the action to remedy.

	** bad operand **

		An operand in a COMPUTE or other action
		did not match the requirements of the operator
		used in the action.

									100


	** unbound variable **

		A variable is not bound to a value in a COMPUTE action.

	** operands not same **

		Operands in a COMPUTE action must be the same type,
		e.g. integer/integer, real/real, etc.

	** bad operator **

		An operator in a COMPUTE action is not valid for the
		operands in the action.

	** syntax error in STM command **

		During parsing of an STM action, the interpreter could
		not recognize the action or a part of the action. This
		error is displayed and the interpreter tries to point to
		the place where the error occurred.

	** only operator is in **

		In a condition the only valid operator for lists
		and choices is IN.

	** variable not found **

		A variable specified in an action was not found in STM.

	** halting inference engine **

		An error occurred which made it necessary to stop
		the inference engine.

	** Small-X ending due to serious error **

		An error occurred which made it necessary to stop
		the small-X interpreter. Usually this error will
		be displayed in conjunction with a message indicating
		that there was a memory allocation error.

									101


	** bad file name **

		A file name was specified that small-X could not
		recognize.

	** error opening file **

		A file was specified that small-X cannot open. This
		usually happens during a REMEMBER or READ command or
		OPEN action.

	** getgnode error **

		An attempt was made to get some memory to build a
		small-X internal structure. No memory was available.

	** end of file **

		While reading a small-X command file, an STM command
		file, or a rule file, the end of the file was
		encountered.

	** getrnode error **

		An attempt was made to get some memory to build a
		small-X internal structure. No memory was available.

	** getsnode error **

		An attempt was made to get some memory to build a
		small-X internal structure. No memory was available.

	** bad rule name **

		While translating a rule small-X found it could not
		recognize the rule name.

	** no IF **

		No IF was found at the beginning of a rule.

	** bad condition **

		While translating the condition part of a rule
		an error was found. The interpreter points to the
		place where the error was encountered.

									102

	** bad certainty **

		The rule value was not correctly specified. 

	** no then **

		No THEN was found while translating the rule.

	** bad action(s) **

		While translating an action in a rule, small-X
		found an error.

	** stm empty **

		No objects in STM to list or erase.

	** no rules **

		The CLEAR RULES command was entered and rule memory was
		empty or a DELETE or SHOW command found no rules in rule 
		memory or a MEMORIZE command was entered and no rules are 
		there to save.

	** clear stm or rules **

		The option specified as part of the CLEAR command was
		incorrect.

	** rule not found **

		a rule specified in a command was not found in rule
		memory.

	** list STM or RULES **

		A LIST command was entered and the LIST option was
		not RULES or STM.

	** empty list **

		a . operation was attempted on a list or variable
		containing a list that was empty

	** DOS command failed **

		a command entered while in DOS mode failed. This 
		usually means that there was not enough memory 
		available to carry out the DOS command.

	** bad file read **

		an external file contained a data object that small-X
		could not recognize.


									103
	** run failed **

		If the program specified as the run action operand 
		cannot be found or if it is too large this error 
		error message is displayed. You must have enough memory
		to hold small-X and the program you specified in the
		RUN action.

	** file not found **

		a READ FILE or WRITE FILE action could not find the
		file specified(it was never opened).

	** file not open **

		a READ FILE or WRITE FILE action was attempted on 
		a file that was previously open.

	** file already open **

		an OPEN action was attempted on a file that was
		already open.

	** bad file mode **

		a WRITE FILE action was attempted on a file that was
		opened for INPUT or a READ FILE action was attempted 
		on a file that was opened for OUTPUT. External files
		in small-X can only be INPUT or OUTPUT, not both.

	** too many files **

		an attempt was made to open more than 10 files
		at the same time.

	** input text ignored **

		this message is displayed when more command or
		action input was supplied than was expected or
		needed. Any command or action preceding the
		text is processed normally.

	** no string value **

		an action or command requiring a string value
		did not have one.

	** run failed **

		a run action did not execute properly. This usually
		occurs when there is not enough memory to run a DOS
		program along side of the small-X interpreter.


									104
	** bad command **

		a command entered could not be processed because
		it was not recognized.

	** no value **

		an action requiring a value did not have one.

	** duplicate rule **

		an attempt was made to enter a rule into rule memory
		with the same name as one that is already in rule 
		memory.

	** type mismatch **

		an operation requiring that the operands be the
		same had this requirement violated.

	** no HELP file **

		the help command was entered by small-X could not
		find its help file. Make sure that the file NSX.HLP
		is on the same disk and in the same directory as
		the small-X interpreter(sx.exe).

	** file locked **

		indicates that a rule program was created with the
		lock option.

	** not available **

		indicates a command just entered in disabled.

	** too many rules **

		indicates you have exceeded the allowable number
		of rules you can enter for a rule program.

	** no goal defined **

		a goal must be defined for backward chaining. This
		message is displayed when the inference engine is
		in backward chaining mode and the engine command 
		was entered with no goal defined.

	** getrstrnode error **

		not enough memory for a restrict action.

									105

	** makegoalnode error **

		not enough memory for backward chaining.

	** getrlnode error **

		not enough memory for backward chaining.

	** goal name not symbol **

		the name of a goal must be a valid small-X
		symbol.

									106


				Appendix E

			      small-X Grammar

									107

	small-X Grammar


	This appendix contains a formal definition of the small-X language.
	This definition consists of rules that define the way in which
	sentences in small-X are constructed. For those familiar with
	definitions of this kind, the definition is given in a BNF-like
	notation.


									108

	<atom>		->		<symbol> |
					<value>  |
					<string>

	<value)		-> 		<integer> |
					<real>

	<list>		->		[ <special-atom> <rest-of-list> ]

	<special-atom>	->		? |
					<atom>

	<rest-of-list>	->		<special-atom> <rest-of-list> |
					\0

	<command>	->		RULES	|
					STM	|
					EXIT	|
					SAVE <filename>  |
					READ <filename>  |
					REMEMBER <filename>  |
					MEMORIZE <filename>  |
					TRACE 	|
					NOTRACE	|
					STEP	|
					NOSTEP	|
					CLEAR <option>  |
					LIST <option>   |
					STORAGE |
					SHOW <rule name> |
					TERMINAL |
					DELETE <rule name> |
					DOS |
					HELP |
					FORWARD |
					BACKWARD |
					QUIET |
					NOQUIET |
					CLOAD <filename> |
					CSAVE <filename> <lock option> |
					GOAL <symbol> |
					STATUS |
					LOWER |
					UPPER


									109

	<rule name> 	-> 		<symbol>

	<option>	->		RULES |
					STM

	<rule>		->		IF <condition> <certainty> 
					 THEN <actions>

	<certainty>	->		C[<real>] |
					\0

	<condition>	->		<condition-element> <rest-of-clause>

	<rest-of-clause> ->		<connective> <condition-element>
					 <rest-of-clause> |
					\0

	<connective>	->		AND |
					OR

	<condition-element> ->		<test> |
					NOT <test>

	<variable>	->		#<symbol>


	<test>		->		IN-MEMORY(<test-operand>) |
					<variable> <test-operator>
					 <test-operand>

	<test-operand>	->		<atom>	|
					<list>	|
					<variable>  |
					<choice>

	<test-operator>	->		=  |
					<= |
					<  |
					>= |
					>  |
					<> |
					IN

	<choice>	->		{ <choice-list> }

	<choice-list>	-> 		<choice-operand> <other-choices>

	<choice-operand> ->		<atom>  |
					<list>  |
					<variable>

	<other-choices>	->		<choice-operand> <other-choices> |
					\0


									110
	<actions>	->		<action> |
					{ <action-list> }

	<action-list>	->		<action> <more-actions>

	<more-actions>	->		<action> <more-actions> |
					\0

	<action>	->		<add-action> |
					<remove-action> |
					<read-action> |
					<write-action> |
					<compute-action> |
					<bind-action> |
					<unbind-action> |
					<halt-action> |
					<run-action> |
					<close-action> |
					<fire-action> |
					<open-action> |
					<reset-action> |
					<modify-action> |
					<restrict-action> 

	<add-action>	->		ADD <operand>

	<remove-action>	->		REMOVE <operand>

	<read-action>	->		READ <type> <prompt> <variable> |
					READ FILE <file name> <variable> 

	<file name> 	->		<symbol>

	<type>		->		INT |
					FLOAT |
					STRING |
					LIST |
					\0

	<prompt>	->		<string> |
					\0

	<write-action>	->		WRITE <operand> |
					WRITE NEW-LINE |
					WRITE CLEAR |
					WRITE MOVE <integer> <integer> |
					WRITE BOX <integer> <integer>
					 <integer> <integer> |
					WRITE ! |
					WRITE FILE <file name> <operand> |
					WRITE FILE <file name> NEW-LINE

									111

	<compute-action> ->		COMPUTE <simple-expression>

	<simple-expression> ->		<variable> <- <operand> <operator>
					 <operand> |
					<variable> <- <unary-operator>
					 <operand>

	<operator>	->		+ |
					- |
					* |
					/

	<unary-operator> ->		. |
					...

	<operand> 	->		<atom> |
					<list> |
					<variable>

	<bind-action> 	->		BIND <variable> <operand> |
					BIND <variable> !

	<unbind-action> ->		UNBIND <variable>

	<halt-action> 	->		HALT

	<run-action>	->		RUN <string>

	<open-action>	->		OPEN <string> AS <file name> FOR <mode>

	<mode>		->		INPUT |
					OUTPUT

	<close-action> 	->		CLOSE <file name>

	<reset-action>	->		RESET <rule name>

	<fire-action>	->		FIRE <rule name>

	<modify-action>	->		MODIFY <rule name> <modify-operator>
					 <real>

	<modify-operator> ->		+ | - | \0

	<restrict-action> ->		RESTRICT <variable> TO <list>

	<lock option>	->		LOCK | NOLOCK



	Note: \0 is used to represent the null string.

									112
	Lexical Syntactic Items

	The following items are lexical:

	<integer> <real> <string> <symbol>

	An <integer> is an optional sign followed sequence of digits.

	A <real> is an optional sign followed by a sequence of digits
	followed by a decimal point followed by an optional real part. A
	real part is a sequence of digits followed by an optional exponent 
	part. The exponent part is an e or E followed by an optional sign, 
	followed by one or two digits.

	A <string> is a ' followed by 0 or more characters followed by a '.
	The maximum size of any small-X string is 80 characters.

	A <symbol> is a letter followed by any sequence of alphabetic or
	numeric characters.

									113


				Appendix F

			         Scripts

									114

	Scripts

	A special feature of the small-X interpreter is its ability to 
	run scripts. A script is a file that contains small-X commands
	and rules that small-X will process automatically. The demonstration
	script supplied with the small-X interpreter is an example of such
	a script. By entering the DOS command,

				sx DEMO.SX

	the interpreter will execute the command and rules contained in
	this script.

	You can use this feature to create applications that contain multiple
	rule files or create applications that run automatically. For instance,
	the command

				sx DEMO.SX

	could be placed in the AUTOEXEC.BAT file so that the small-X
	demonstration program is run when the system boots. This requires
	no intervention on the part of the user.

	To create a script and to use the script run feature create a 
	text file that contains the commands you want small-X to execute.
	Any small-X command can be used. Rules can also be used. Rule
	files can be accessed with the REMEMBER command. After you have
	created this file it can be run with the DOS command,

				sx myscript.ext

	where myscript.ext is replaced by the name of the script file
	you created.

	The script capability makes it possible to write rule programs that
	contain an unlimited number of rules. This can be done by "REMEMBERing"
	and "ENGINEing" each rule program in sequence. As long as no
	CLEAR STM command is entered between rule program files, STM is
	maintained so each subsequent rule program can act on STM in the
	state it was left in by the previous rule program.

	Examine the demo.sx file supplied for a simple example of a small-X
	script.

                                                                                                                                                                                                                                                                                                                        