%
% tesla.sty
%
%	Henry Baragar				Gail E. Harris
%	Instantiated Software Inc.	and	RES Policy Research Inc.
%	henry@instantiated.on.ca		ak753@freenet.carleton.ca
%
% This is the TeSLa style package that is the subject of the paper
% entitled "An Example Special Purpose Input Language to LaTeX" that
% was (will be) presented to the TUG94 conference in Santa Barabara.  
% The paper contains a complete description of this package and should
% be consulted when documentation in this file is unclear or incomplete.
%
%
% Introduction.
% =============
%
% This style file is used for documenting the rules of a knowledge base.
% There are two reasons for using a style like the one defined here:
%	    1.	To generate, from the same source file, documentation for
%		use by two audiences with vastly different expectations,
%		namely:
%		      - the Expert System Programmer, who expects
%			the documentation in a tabular form where rules
%			are grouped into tables of related rules that
%			incorporate the names of the Knowledge Base
%			variables
%		      -	the Domain Expert (or system user), who expects the
%			documentation in an English form where rules are
%			grouped into subsections of related rules, each of
%			which is a sentence (and paragraph) that
%			incorporates the meanings of the Knowledge Base
%			variables
%	    2.	To input (or mark up) the rules in a manner such that the
%		structure of the rules is visually apparent to the Expert
%		System Analyst (the author of the documentation) and such
%		that the likelyhood of errors is reduced (since the Expert
%		System Analyst might not be comfortable with LaTeX or TeX).
%
%
% Background Terminology.
% =======================
%
% A Knowledge Base in an Expert System is a set of rules that defines the 
% logic used to make decisions in a particular Domain (area of expertise). 
% Each rule is composed of a number of conditions and a conclusion.  Each
% condition is a relation that evaluates to true or false.  If all 
% conditions evaluate to true, then the conclusion is deemed true.  For
% example:
%     if the temperature of the porridge is greater than 40 degrees celsius
%	 and the temperature of the porridge is less than 50 degrees celsius
%     then the porridge is just right.
% which says that the conclusion---"the porridge is just right"---is deemed
% to be true if the temperature of the porridge falls within the range
% indicated by the two conditions.
% 
%
%
% Usage:
% ======
%
% The TeSLa package defines five primary commands for use in a rule file:
%	[tvar 
%		to define a mapping between a Knowledge Base variable
%		and the English phrase that describes it
%	[tgroup
%		to group rules
%	[trule
%		to display rules
%	[ttext
%		to input explanatory text
%	[trem
%		to input additional remarks into the tabular form.
% The syntax for these commands is defined in the paper. In addition,
% the TeSLa package also predefines many of the relational operators that
% would be used in rules.  See below for the list of such operators.
%
% See the file goldilocks.tex for an example of how TeSLa is used.
%
%
% Structure of the TeSLa Package:
% ===============================
% 
% The TeSLa package is structured as three files:
%	tesla.sty
%		(this file) which contains the TeX code to parse the
%		input file as well as code common to both the tabular
%		and English forms
%	tab-form.sty
%		which contains the code to customize the documentation
%		for the Expert System Programmer
%	eng-form.sty
%		which contains the code to customize the documentation
%		for the Domain Expert.
% Please see the tab-form.sty and eng-form.sty files for the details on how
% the customization was implemented for the tabular and English forms.
% 
%

%
% The structure of TeSLa documents.
% =================================
%
% A document which uses the TeSLa package is usually implemented as three
% main files and one or more rule files.  The main files are:
%	main.tex
%		which contains non-rule text and lines of the form:
%			\inputrulefile{rule-file}
%		to input a file of rules name "rule-file"
%	main-tab.tex
%		which simply contains:
%			\documentstyle[tesla,tab-form]{article}
%			\input{main}
%		and is the file LaTeX'ed when the tabular form is desired.
%	main-eng.tex
%		which simply contains:
%			\documentstyle[tesla,eng-form]{article}
%			\input{main}
%		and is the file LaTeX'ed when the English form is desired.
%
% The \inputrulefile command takes one argument:
%	   #1 -	The name of the input file, with or without a .tex extension
% This command removes the special meaning (to TeX) of many characters that
% are heavily used in TeSLa documents and inputs the rule file.
%
% Note that two characters are given special meaning in TeSLa:
%	    [ -	is set to be the TeX escape character  (like \ in LaTeX)
%	    ; -	is set to be the TeX comment character (like % in LaTeX)
% 
\newcommand{\inputrulefile}[1]{%
    \changecatcodes
    \input{#1}
    }
\newcommand{\changecatcodes}{	%Change mostly to alphabetic
    \catcode`\+=11          \catcode`\0=11
    \catcode`\-=11          \catcode`\1=11
    \catcode`\*=11          \catcode`\2=11
    \catcode`\(=11          \catcode`\3=11
    \catcode`\)=11          \catcode`\4=11
    \catcode`\<=11          \catcode`\5=11
    \catcode`\!=11          \catcode`\6=11
    \catcode`\>=11          \catcode`\7=11
    \catcode`\:=11          \catcode`\8=11
    \catcode`\==11          \catcode`\9=11
    \catcode`\_=11	    \catcode`\%=11
    \catcode`\[=0	    % Give [ the same meaning as \ in TeX
    \catcode`\;=14	    % Give ; the same meaning as % in TeX
    }

%
% [tvar.
% ======
%
% The [tvar command maps a Knowledge Base variable to its English language
% description.  Its arguments are:
%	   #1 -	the Knowledge Base variable name
%	   #2 -	the English phrase that descibes the Knowledge Base
%		variable
% It is implemented by defining a new TeX command for the Knowledge Base
% variable whose definition is selected by the \xform command, which is 
% as "#1" in tab-form.sty and as "#2" in eng-form.sty.
% 
% The \xvar command is used to expand a Knowledge Base variable defined by 
% [tvar.  It takes one argument:
%	   #1 - the Knowledge Base variable name to be expanded
% If the argument has not been [tvar'ed, then \xvar prints out its argument
% in italics, to indicate that the argument has not yet been defined.
%
% See the "Definitions" subsection of the "The New Input Language" section
% and "The [tvar command" subsection of "The Implementation" section in the
% paper for more details.
%
\gdef\tvar | #1 | #2 ]{%
    \expandafter\gdef\csname #1\endcsname{\xform{#1}{#2}}%
    }
\gdef\xvar#1{%
    \expandafter
        \ifx\csname #1\endcsname\relax{\it #1}%
        \else \csname #1\endcsname%
        \fi
    }

%
% [tgroup.
% ========
%
% The [tgroup command delineates groups of rules.  Its arguments are:
%	   #1 -	the group name
%	   #2 - the action, which can be one of:
%		    n -	to begin a group of rules with n conditions,
%			where n is an integer in the range 1 to 6
%		    - -	to delineate subgroups within a group of rules
%		    e -	to end a group of rules
%
% It is implemented as a switch statement based on the action, \xbegin,
% \xsep and \xend specify what formatting is to be done, and are defined
% differently in tab-form.sty and eng-form.sty.
%
% See the "Groups of Rules" subsection of the "The New Input Language"
% section and "The [tgroup command" subsection of "The Implementation"
% section in the paper for more details.
%
\gdef\tgroup | #1 | #2 ]{%
    \if 1#2 \xbegin{xone}{1}{2}{.466}{#1}\fi
    \if 2#2 \xbegin{xtwo}{2}{3}{.300}{#1}\fi
    \if 3#2 \xbegin{xthree}{3}{4}{.216}{#1}\fi
    \if 4#2 \xbegin{xfour}{4}{5}{.166}{#1}\fi
    \if 5#2 \xbegin{xfive}{5}{6}{.133}{#1}\fi
    \if 6#2 \xbegin{xsix}{6}{7}{.1095}{#1}\fi
    \if -#2 \xsep\fi
    \if e#2 \xend\fi
    }

% 
% [trule.
% =======
%
% The [trule command documents a Knowledge Base rule.  Since the number of 
% conditions expected by [trule command is governed by which group the rule
% is in, [trule must be defined in the \xbegin command called by [tgroup. 
% That is, the definition of \xbegin in tab-form.sty and eng-form.sty must
% include a definition of [trule.  However, [trule must be defined as one 
% of \xone through \xsix defined here.
%
% \xone through \xsix all have the same structure.  If the first condition
% of the rule is empty (denoted by a "_"), then do something defined by 
% \xpre (which is defined in tab-form.sty and eng-form.sty) and then pretend
% this is a rule with one less condition.  If the first condition is not 
% empty, then do something defined by \xif on the first condition, by
% \xand on each of the following conditions, and by \xthen on the conclusion.
% \xif, \xand and \xthen are defined differently by tab-form.sty and
% eng-form.sty.
%
% The \if, \xand and \xthen commands in tab-form.sty and eng-form.sty have
% the responsibility of expanding each relation that makes up a condition or
% conclusion. This is accomplished with the \xrel command.  Since a
% condition has one of the following three forms:
%	    1.	lhs rel rhs
%	    2.	rel rhs _ 
%	    3.	rhs _ _ 
% \rel must check each part for a "_" to determine if the part should be 
% expanded by \xvar.  Note that the "rel" operators must be [tvar'ed (or
% the equivalent) so that they can be expanded by \xvar.  See below for
% the list of predefined relational operators.
% 
% See the "Groups of Rules" subsection of the "The New Input Language"
% section and "The [trule command" subsection of "The Implementation"
% section in the paper for more details.
%
\gdef\xone | #1| #2]{%
    \xif{#1} \xthen{#2}
    }
\gdef\xtwo | #1| #2| #3]{%
    \if_#1 \xpre \xone | #2| #3]%
    \else\xif{#1} \xand{#2}\xthen{#3}
    \fi
    }
\gdef\xthree | #1| #2| #3| #4]{%
    \if_#1 \xpre \xtwo | #2| #3| #4]%
    \else\xif{#1} \xand{#2}\xand{#3}\xthen{#4}
    \fi
    }
\gdef\xfour | #1| #2| #3| #4| #5]{%
    \if_#1 \xpre \xthree | #2| #3| #4| #5]%
    \else\xif{#1} \xand{#2}\xand{#3}\xand{#4}\xthen{#5}
    \fi
    }
\gdef\xfive | #1| #2| #3| #4| #5| #6]{%
    \if_#1 \xpre \xfour | #2| #3| #4| #5| #6]%
    \else\xif{#1} \xand{#2}\xand{#3}\xand{#4}\xand{#5}\xthen{#6}
    \fi
    }
\gdef\xsix | #1| #2| #3| #4| #5| #6| #7]{%
    \if_#1 \xpre \xfive | #2| #3| #4| #5| #6| #7]%
    \else\xif{#1} \xand{#2}\xand{#3}\xand{#4}\xand{#5}%
        \xand{#6}\xthen{#7}
    \fi
    }
\gdef\xrel #1 #2 #3 {%
   \if_#3\if_#2\xvar{#1}\else\xvar{#1} \xvar{#2}\fi
   \else\xvar{#1} \xvar{#2} \xvar{#3}%
   \fi
    }

%
% The [ttext and [trem commands.
% ==============================
%
% The [ttext and [trem commands insert arbitrary text into the
% documentation.  [ttext is intended for text that is to be inserted in 
% both forms, while [trem is for text to be inserted into the tabular
% form, but not the English form.  There has yet to be a need to insert
% text into the English form, but not the tabular form.
%
% Both [ttext and [trem take one argument:
%	   #1 -	The text to be inserted
% [ttext and [trem are implemented by \xtext and \xrem, respectively, in 
% tab-form.sty and eng-form.sty.
%
% See the "Other Commands" subsection of the "The New Input Language" section
% and "The [ttext command" and "The [trem command" subsections of "The
% Implementation" section in the paper for more details.
%
\gdef\ttext | #1 ]{\xtext{#1}}
\gdef\trem | #1 ]{\xrem{#1}}

% 
% Predefined relational operators.
% ================================
% 
% The relational operators that follow are predefined for use in TeSLa.
%
% Note that we are essentially [tvar'ing these operators so that they can
% be treated like TeSLa definitions.  Also note that the first thing we 
% do is \changecatcodes so that the special meaning (to TeX) of any 
% character that might be used in the relational operator is removed.
%
{
\changecatcodes
\gdef\<{\xform{$<$}{is less than}}
\gdef\>{\xform{$>$}{is greater than}}
\gdef\!={\xform{$\neq$}{is not equal to}}
\gdef\=={\xform{$=$}{is equal to}}
\gdef\<={\xform{$\leq$}{is less than or equal to}}
\gdef\>={\xform{$\geq$}{is greater than or equal to}}
\gdef\:={\xform{$\leftarrow$}{is assigned}}
\gdef\+{\xform{$+$}{added to}}
\gdef\+={\xform{$+$$=$}{is incremented by}}
\gdef\decrement{\xform{$-$$=$}{is decremented by}}
\gdef\minus{\xform{$-$}{less}}
\gdef\*{\xform{$*$}{multiplied by}}
\gdef\memberOf{\xform{$\in$}{is one of}}
\gdef\notMemberOf{\xform{$\not\in$}{is not one of}}
\gdef\isnot{\xform{$\neg$}{not}}
}

%
% Default formatting.
% ===================
% 
% Use block formatting as the default for paragraphs.
%
\setlength{\parskip}{\baselineskip}
\setlength{\parindent}{0pt}

% 
% Etc.
% ===
%
% We need an "empty" command to do certain comparisons.
%
\gdef\empty{}

%
% Post Script.
% ============
%
% The TeSLa logo is defined here, just in case you need it;-)
%
\def\TeSLa{T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emS\kern-.10em\La}
\def\La{{\reset@font\rm L\kern-.36em\raise.3ex\hbox{\sc a}\kern-.15em}}
