(FILECREATED "27-Aug-84 17:38:53" {INDIGO}<LOOPS>SOURCES>LOOPSRULES.;30 45882  

      changes to:  (CLASSES RuleSet)

      previous date: "26-Jun-84 14:14:23" {INDIGO}<LOOPS>SOURCES>LOOPSRULES.;29)


(* Copyright (c) 1983, 1984 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT LOOPSRULESCOMS)

(RPAQQ LOOPSRULESCOMS [(* Copyright (c)
			  1982 by Xerox Corporation)
	(* * Package for Rule-Oriented Programming in LOOPS. - File LOOPSRULES contains the basic 
	   class definitions. File LOOPSRULESP contains the rule parser. - File LOOPSRULESC contains 
	   the rule compiler. File LOOPSRULESD interprets RuleSet declarations.)
	(* Written in August 1982 by Mark Stefik, Alan Bell, and Danny Bobrow)
	(* Classes for Rule-Oriented Programming in LOOPS.)
	(CLASSES * LOOPSRULESCLASSES)
	(METHODS Rule.Print RuleSet.CompileRules RuleSet.CopyRules RuleSet.ER RuleSet.EditRules 
		 RuleSet.Off RuleSet.On RuleSet.PPR RuleSet.PPRules RuleSetMeta.New 
		 RuleSetSource.CompileRules RuleSetSource.EditRules RuleSetSource.GetSource 
		 RuleSetSource.PPRules)
	(FNS * LOOPSRULESFNS)
	(FNS * RULESETMISCFNS)
	(VARS TEDITRULESFLG (↑rs NIL)
	      (↑ws NIL)
	      (↑caller NIL)
	      (↑task NIL)
	      (reWindow NIL)
	      (reTraceWindow NIL)
	      (reInspectWindow NIL)
	      (rsTraceFont (FONTCREATE (QUOTE GACHA)
				       8)))
	(P (CLDISABLE (QUOTE ↑)))
	[P (INTERRUPTCHAR 6 (LIST (FUNCTION RE]
	(MACROS RunRS)
	(DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS (ADDVARS (NLAMA)
									      (NLAML)
									      (LAMA WRITETTY])



(* Copyright (c) 1982 by Xerox Corporation)

(* * Package for Rule-Oriented Programming in LOOPS. - File LOOPSRULES contains the basic class
 definitions. File LOOPSRULESP contains the rule parser. - File LOOPSRULESC contains the rule 
compiler. File LOOPSRULESD interprets RuleSet declarations.)




(* Written in August 1982 by Mark Stefik, Alan Bell, and Danny Bobrow)




(* Classes for Rule-Oriented Programming in LOOPS.)


(RPAQQ LOOPSRULESCLASSES (Rule RuleSet RuleSetMeta RuleSetNode RuleSetSource StandardAuditRecord Task 
			       TestAuditRecord))
(DEFCLASSES Rule RuleSet RuleSetMeta RuleSetNode RuleSetSource StandardAuditRecord Task 
	    TestAuditRecord)
[DEFCLASS Rule
   (MetaClass Class doc 

          (* * Class for describing rules as objects. Instances of this class (rule objects) are created as a side-effect 
	  when RuleSets are compiled in audit mode.)


	      Edited:                                        (* mjs: "12-FEB-83 12:19"))
   (Supers Object)
   (InstanceVariables (source NIL doc                        (* string that was the source of the rule in the 
							     RuleSet.))
		      (edited NIL doc                        (* person who edited the rule.))
		      (editor NIL doc                        (* time and date of the editing.))
		      (ruleNumber 0 doc                      (* sequence number of the rule in the RuleSet at the 
							     time of editing.))
		      (ruleSet NIL doc                       (* RuleSet to which this rule belongs.)))
]

[DEFCLASS RuleSet
   (MetaClass RuleSetMeta doc 

          (* * A RuleSet is a set of rules, together with methods for interpreting them.)


	      Edited:                                        (* dgb: "27-Aug-84 17:33"))
   (Supers NamedObject Perspective Method)
   (InstanceVariables (compiledRules NIL doc                 (* Name of Lisp Function for Rules.))
		      (workSpace NIL doc                     (* name of class for work space.))
		      (args NIL doc                          (* arguments to the RuleSet other than self.)
			    )
		      (tempVars NIL doc                      (* temporary variables.))
		      (taskVars NIL doc                      (* Task variables.))
		      (debugVars NIL doc                     (* variables to be printed during a trace or break.)
				 )
		      (numRules NIL doc                      (* Number of Rules in RuleSet.))
		      (controlStructure doAll doc            (* control structure for rules.))
		      (whileCondition NIL doc                (* while condition for RuleSet.))
		      (compilerOptions NIL doc               (* Compilation options.))
		      (auditClass #$StandardAuditRecord doc 
                                                             (* name of class for audit records.))
		      (metaAssignments NIL doc               (* RuleSet specific meta-assignment statements.)
				       )
		      (ruleClass #$Rule doc                  (* name of class for rule objects.))
		      (taskClass NIL doc                     (* Name of class used for tasking.))
		      (perspectiveNode #$RuleSetNode myViewName RuleSet))]

[DEFCLASS RuleSetMeta
   (MetaClass MetaClass doc 

          (* * MetaClass for RuleSets.)


	      Edited:                                        (* mjs: "29-SEP-82 09:14"))
   (Supers Template)]

[DEFCLASS RuleSetNode
   (MetaClass Template doc                                   (* Node for RuleSet perspectives.)
	      Edited:                                        (* mjs: "29-SEP-82 10:43"))
   (Supers Node Object)
   (InstanceVariables (perspectives NIL Source #$RuleSetSource RuleSet #$RuleSet))]

[DEFCLASS RuleSetSource
   (MetaClass Template doc 

          (* * Source code for a RuleSet. Contains editing information about the RuleSet, and an indexed list of rule 
	  objects.)


	      Edited:                                        (* dgb: "31-OCT-83 14:20"))
   (Supers DatedObject Perspective VarLength)
   (InstanceVariables (perspectiveNode #$RuleSetNode myViewName Source)
		      (edited NIL doc                        (* Date last edited.))
		      (editor NIL doc                        (* Last User to edit the rules.)))]

[DEFCLASS StandardAuditRecord
   (MetaClass Class doc 

          (* * Standard (default) audit record for makeing audit trails of RuleSet invocations.)


	      Edited:                                        (* mjs: " 9-JUN-83 09:53"))
   (Supers Object)
   (ClassVariables (metaAssns (rule ← ruleObject)
			      doc                            (* default meta-assignment statements associated with 
							     this audit record.)
			      ))
   (InstanceVariables (rule NIL doc                          (* Rule used in setting the value.)))]

[DEFCLASS Task
   (MetaClass Class doc 

          (* * Representation of the invocation of a RuleSet. Used in creating variations of agenda control structures.
	  Similar to the idea of closures.)


	      Edited:                                        (* mjs: " 7-JUN-83 10:24"))
   (Supers Object)
   (InstanceVariables (ruleNumber 1 doc                      (* Number of the next rule to be executed.
							     Used for RuleSet debugging and for doNext and 
							     cycleNext.))
		      (rs NIL doc                            (* RuleSet that was invoked.))
		      (self NIL doc                          (* workSpace given to the RuleSet.))
		      (value NIL doc                         (* value returned by the RuleSet))
		      (status Started doc                    (* Execution status. Examples: Started, Done, Aborted, 
							     Suspended.))
		      (reason NotKnown doc                   (* Reason for the status. Examples: Success, NoSpace, 
							     Blocked))
		      (caller NIL doc                        (* Caller of the RuleSet.)))]

[DEFCLASS TestAuditRecord
   (MetaClass Class doc                                      (* For Test cases.)
	      Edited:                                        (* mjs: "11-NOV-82 09:30"))
   (Supers StandardAuditRecord)
   (InstanceVariables (↑rs NIL)
		      (↑ruleNumber 0)
		      (cf .3)
		      (support NIL))]

[METH Rule  Print (file)
      (* * Print out formatted information about a rule - the source, RuleSet, and editing 
	 information.)]


[METH RuleSet  CompileRules NIL
      (* Compile the RuleSet.)]


[METH RuleSet  CopyRules (newName)
      (* Creates a new RuleSet containing a copy of the rules.)]


[METH RuleSet  ER NIL
      (* Shorthand for EditRules)
      (method RuleSet.EditRules)]


[METH RuleSet  EditRules NIL
      (* Forward the Edit message to the Source perspective of the RuleSet.)]


[METH RuleSet  Off (compilerOption)
      (* Turn off a compiler option.)]


[METH RuleSet  On (compilerOption)
      (* Turn on a compiler option.)]


[METH RuleSet  PPR NIL
      (* Shorthand for PPRules)
      (method RuleSet.PPRules)]


[METH RuleSet  PPRules NIL
      (* PrettyPrint the Rules.)]


[METH RuleSetMeta  New (name)
      (* * Create a new rule set.)]


[METH RuleSetSource  CompileRules (↑userCompilerOptions sourceRules)
      (* * Compile the Rules for a RuleSet from the Rule Language into Interlisp.)]


[METH RuleSetSource  EditRules NIL
      (* Edit the rules associated with a RuleSetSource.)]


[METH RuleSetSource  GetSource (allDeclFlg)
      (* Compute the source string for a RuleSet for printing or editing. If allDeclFlg is T, the 
	 computed string will include extra rule declarations beyond the basic set, even if they have 
	 no current value.)]


[METH RuleSetSource  PPRules (file)
      (* Pretty Print the Rules)]


(DEFINEQ

(Rule.Print
  [LAMBDA (self file)                                        (* mjs: " 9-JUN-83 09:17")

          (* * Print out formatted information about a rule -
	  the source, RuleSet, and editing information.)


    (printout file T .FONT BOLDFONT (@ source)
	      .FONT DEFAULTFONT T)
    (printout file T .FONT COMMENTFONT .SP 5 "... Rule " (@ ruleNumber)
	      " from "
	      (@(@ ruleSet)
		name))
    (printout file T .SP 5 "   edited by " (@ editor)
	      " on "
	      (@ edited)
	      .FONT DEFAULTFONT T T)
    T])

(RuleSet.CompileRules
  [LAMBDA (self compilerOptions)                             (* mjs: "22-JAN-83 10:01")
                                                             (* Forward the Compile message to the Source perspective
							     of the RuleSet.)
    (PROG (sourcePerspective)
          (SETQ sourcePerspective (← self GetPersp (QUOTE Source)))
          (← sourcePerspective CompileRules compilerOptions)
          (RETURN self])

(RuleSet.CopyRules
  [LAMBDA (self newName workSpace)                           (* mjs: "22-JUL-83 14:43")

          (* * Creates a new RuleSet containing a copy of the rules.)


    (PROG (newRS ruleSetSource)

          (* * Create a RuleSet)


          (SETQ newRS (← self Copy newName))
          (COND
	    (workSpace (←@
			 newRS workSpace workSpace)))        (* Copy the rule objects.)
          (SETQ rsRuleClass (@ ruleClass))
          (SETQ ruleSetSource (← self GetPersp (QUOTE Source)))
          (SaveRules ruleSetSource self (← ruleSetSource GetSource))
                                                             (* Compile the Rules.)
          (SETQ rsCompilerOptions NIL)
          (← newRS CompileRules)
          (RETURN newRS])

(RuleSet.EditRules
  [LAMBDA (self coms)                                        (* SDG "27-MAY-83 08:52")
                                                             (* Forward the Edit message to the Source perspective of
							     the RuleSet.)
    (PROG (sourcePerspective)
          (SETQ sourcePerspective (← self GetPersp (QUOTE Source)))
          (← sourcePerspective EditRules coms)
          (RETURN self])

(RuleSet.Off
  [LAMBDA (self compilerOption)                              (* mjs: "13-JUN-83 19:17")
                                                             (* Turn off a compiler option.)
    (COND
      ((FMEMB compilerOption (@ compilerOptions))
	(←@
	  compilerOptions
	  (REMOVE compilerOption (@ compilerOptions)))
	(← self CompileRules))
      (T (printout T .FONT BOLDFONT compilerOption .FONT DEFAULTFONT " not on for " self T])

(RuleSet.On
  [LAMBDA (self compilerOption)                              (* mjs: "13-FEB-83 11:57")
                                                             (* Turn on a compiler option.)
    (COND
      ((NOT (FMEMB compilerOption (@ compilerOptions)))
	(←@
	  compilerOptions
	  (NCONC1 (@ compilerOptions)
		  compilerOption))
	(← self CompileRules])

(RuleSet.PPRules
  [LAMBDA (self file)                                        (* mjs: "28-JAN-83 18:19")

          (* * PrettyPrint the Rules.)


    (← (← self GetPersp (QUOTE Source))
       PPRules file])

(RuleSetMeta.New
  [LAMBDA (self assocList name)                              (* mjs: "12-FEB-83 12:20")

          (* * Create a new rule set. (The argument self is the class RuleSet.))


    (PROG (newRuleSet sourcePersp)

          (* * Insist on getting a name for the RuleSet.)


          [SETQ name (OR name (INTTY "RuleSet name: " NIL 
			     "RuleSets need to have names.  Please enter a name for the RuleSet."
				     (QUOTE noShiftFlg]

          (* * Make the RuleSet and its other perspectives.)


          (SETQ newRuleSet (←Super
	      self New assocList))

          (* * Set the Name in the RuleSet.)


          (← newRuleSet SetName name)

          (* * Return the RuleSet.)


          (RETURN newRuleSet])

(RuleSetSource.CompileRules
  [LAMBDA (self userCompilerOptions sourceStr)               (* dgb: "25-Jun-84 10:17")

          (* * Compile the Rules for a RuleSet from the Rule Language into Interlisp. self is the Source perspective of the 
	  RuleSet.)


    (PROG (codeBody ruleSet rulePos ruleStr ruleSetArgs)
          (SETQ ruleSet (← self GetPersp (QUOTE RuleSet)))
          (COND
	    (userCompilerOptions (←@
				   ruleSet compilerOptions userCompilerOptions)))
          (SETQ rsName (@ ruleSet name))
          (printout NIL .FONT BOLDFONT "Compiling " rsName " to Lisp." .FONT DEFAULTFONT T)
                                                             (* Compute the source rules unless supplied by the rule 
							     editor.)
          [COND
	    ((NULL sourceStr)
	      (SETQ sourceStr (← self GetSource]             (* Process the declarations.)
          (GetRuleSetDeclarations sourceStr userCompilerOptions)
          (COND
	    (parseErrorFlg (RETURN rsName)))                 (* Locate the start of the rules.)
          (SETQ rulePos (PLUS 8 (STRPOS "********" sourceStr)))
          (SETQ ruleStr (SUBSTRING sourceStr rulePos))       (* Parse the tokens.)
          (ParseTokens ruleStr)                              (* Generate the LISP code for the rules.)
          (COND
	    (parseErrorFlg (RETURN rsName)))
          (SETQ rsNumRules (CountRules sourceStr))
          (SETQ rsRuleObjects (GetRules sourceStr ruleSet))
          (SETQ codeBody (CompileRuleList ruleSet self))
          (SETQ ruleSetArgs (CONS (QUOTE self)
				  rsArgs))

          (* * Install the code in a function with the same rsName as the RuleSet unless there was an error during 
	  compilation.)


          [COND
	    ((NULL parseErrorFlg)
	      (DEFINE (LIST (LIST rsName ruleSetArgs (EDITDATE NIL INITIALS)
				  (BQUOTE                    (* RuleSet , rsName Lisp code))
				  codeBody)))                (* Make a pointer to the function in the RuleSet.)
	      (←@
		ruleSet compiledRules rsName)
	      (TERPRI)
	      (COND
		((AND (FMEMB (QUOTE LC)
			     userCompilerOptions)
		      (NULL parseErrorFlg))
		  (printout NIL .FONT BOLDFONT "Compiling " rsName " to ByteCodes." .FONT DEFAULTFONT 
			    T T)
		  (BKSYSBUF "ST
")
		  (BKSYSBUF "N
")
		  (COMPILE rsName]
          (RETURN rsName])

(RuleSetSource.EditRules
  [LAMBDA (self coms)                                        (* dgb: "25-Jun-84 11:00")
                                                             (* Edit the rules associated with a RuleSetSource.
							     Also sets rsOldRuleStrings and rsRuleStrings -- lists of
							     statements that are compared during RuleSet 
							     compilation.)
    (PROG (command compOptions oldSourceRules ruleSet sourceRules doneFlg workSpace rulePos
		   (needToCompileFlg T))                     (* Collect old statements from BEFORE the Edit.)
          (SETQ ruleSet (← self GetPersp (QUOTE RuleSet)))
          (SETQ oldSourceRules (← self GetSource))
          (SETQ sourceRules oldSourceRules)
          (SETQ rsName (@ ruleSet name))
          (MakeEditMenu)
          [COND
	    ((NULL coms)                                     (* Initially place user in rule editor.)
	      (SETQ coms (LIST (QUOTE EditRules]
          (while (NULL doneFlg) do ((SETQ command (OR (pop coms)
						      (MENU reEditMenu)))
				    (SELECTQ command
					     (UE (UE))
					     (EditRules (SETQ needToCompileFlg T)
							(SETQ sourceRules (RuleSourceEdit sourceRules)
							  ))
					     (EditAllDecls (SETQ needToCompileFlg T)
							   (GetRuleSetDeclarations sourceRules)
							   (SETQ rulePos (PLUS 8 (STRPOS "********" 
										      sourceRules)))
							   (SETQ sourceRules (CONCAT (
GetRSAllDeclString)
										     (SUBSTRING
										       sourceRules 
										       rulePos)))
							   (SETQ sourceRules (RuleSourceEdit 
										      sourceRules)))
					     [(OK&LispCompile OK)
					       (COND
						 (needToCompileFlg
						   (SETQ parseErrorFlg NIL)
                                                             (* Compile Lisp if command is OK&LispCompile)
						   (AND (EQ command (QUOTE OK&LispCompile))
							[NOT (FMEMB (QUOTE LC)
								    (SETQ compOptions (@ 
									 ,RuleSet:compilerOptions]
							(SETQ compOptions (CONS (QUOTE LC)
										compOptions)))
                                                             (* Add Lisp compiling to compOptions)
						   (← self CompileRules compOptions sourceRules)))
					       (COND
						 ((NULL parseErrorFlg)
                                                             (* Here if compiled without error.)
						   (SETQ doneFlg T)
						   (SaveRules self ruleSet sourceRules rsRuleObjects)
						   (SHRINKW TTYINEDITWINDOW]
					     (Compile (SETQ parseErrorFlg NIL)
						      (← self CompileRules NIL sourceRules)
						      (SETQ needToCompileFlg NIL))
					     (STOP (SHRINKW TTYINEDITWINDOW)
						   (SETQ doneFlg T))
					     (Save (SaveRules self ruleSet sourceRules))
					     [DF (COND
						   ((FNTYP rsName)
						     (APPLY (QUOTE DF)
							    rsName)
						     (CLEARBUF]
					     (InspectRuleSet (← ruleSet Inspect))
					     [EditWS (SETQ workSpace (GetClassRec (@ ruleSet 
										     workSpace)))
						     (COND
						       (workSpace (← workSpace Edit))
						       (T (WRITE "Class for Workspace not found."]
					     (Undo! (SETQ sourceRules oldSourceRules))
					     (Help (printout T 
"Use OK to Compile the rules, save them, and exit.
Use OK&LispCompile to compile the Lisp function after Rule compiling
Use EditRules to edit the rules.
Use EditAllDecls to edit the rules, showing all declarations.
Use STOP to exit without compiling or saving.
Use Undo! to restore the original RuleSet.
Use UE to go into a Lisp user exec.
Use DF to edit the compiled lisp code for the RuleSet.
Use Compile to compile the rules without exiting.
Use InspectRuleSet to inspect the RuleSet object.
Use Help to get this list."
							     T))
					     NIL])

(RuleSetSource.GetSource
  [LAMBDA (self)                                             (* dlsb: "16-FEB-83 11:58")
                                                             (* Compute the source string for a RuleSet for printing 
							     or editing.)
    (PROG (declStr str ruleSource ruleSet numRules (CRLF (CONSTANT "
")))
          (SETQ ruleSet (← self GetPersp (QUOTE RuleSet)))
          (SETQ declStr (GetRSDeclString ruleSet))
          (SETQ str CRLF)                                    (* Collect the strings for the rules.)
          (SETQ numRules (OR (@ ruleSet numRules)
			     0))
          (for ruleNum from 1 to numRules when (SETQ ruleSource (GetValue (GetNthValue self ruleNum)
									  (QUOTE source)))
	     do (SETQ str (CONCAT str CRLF CRLF ruleSource)))
          (RETURN (CONCAT declStr "********" CRLF str])

(RuleSetSource.PPRules
  [LAMBDA (self file)                                        (* mjs: "12-FEB-83 12:00")
                                                             (* Pretty Print the Rules)
    (COND
      ((NULL file)                                           (* Default PP file.)
	(SETQ file PPDefault)))
    (printout file .FONT BOLDFONT "RuleSet " (@(← self GetPersp (QUOTE RuleSet))
		name)
	      T)
    (printout file .FONT COMMENTFONT "Last Edited: " (@ edited)
	      " by "
	      (@ editor)
	      .FONT DEFAULTFONT T)
    (printout file (← self GetSource)
	      T)
    self])
)

(RPAQQ LOOPSRULESFNS (ListRuleSets MakeEditMenu REObject ReinstallRuleSets RuleSourceEdit SaveRules 
				   SearchStackForWorkSpace))
(DEFINEQ

(ListRuleSets
  [LAMBDA (ruleSetsSpec pressFileName)                       (* dgb: "28-Feb-84 16:22")

          (* * Prints a list of RuleSets to a file. Arg can be either a RuleSetName, or a list of RuleSetNames, or a file 
	  name, or a className. If it is a className, all of the RuleSets that are methods of the class are printed.)


    (PROG (ruleSetNames numNames class ruleSetName ruleSet (listFile (OR pressFileName (QUOTE 
										  {CORE}ListRules)))
			fileHandle)

          (* * Decode the argument to find the RuleSet Names.)


          [SETQ ruleSetNames (COND
	      ((LISTP ruleSetsSpec)
		ruleSetsSpec)
	      ((SETQ class (GetClassRec ruleSetsSpec))
		(for method in (← class List (QUOTE Methods)) when (SETQ ruleSetName
								     (GetMethod class method
										(QUOTE RuleSet)))
		   collect ruleSetName))
	      (T (LIST ruleSetsSpec]                         (* mumble)

          (* * Create a temporary file.)


          (SETQ fileHandle (OPENFILE listFile (QUOTE OUTPUT)))
          (COND
	    (class (← class PP fileHandle)
		   (printout fileHandle .PAGE T)))
          (SETQ numNames (FLENGTH ruleSetNames))
          [for rsn in ruleSetNames as num from 1 to numNames
	     do (SETQ ruleSet (GetObjectRec rsn))
		(COND
		  (ruleSet (PRIN1 rsn)
			   (SPACES 1)
			   (printout fileHandle T T "*********************************************" T 
				     T)
			   (← ruleSet PPRules fileHandle)
			   (COND
			     ((NEQ num numNames)             (* New page except last one)
			       (printout fileHandle .PAGE T T T]
          (CLOSEF fileHandle)
          (COND
	    ((NOT pressFileName)                             (* Print and Delete the file if name not given by user.)
	      (EMPRESS fileHandle)
	      (DELFILE fileHandle])

(MakeEditMenu
  [LAMBDA NIL                                                (* dgb: "25-Jun-84 10:40")
                                                             (* Makes a menu for the Rule Editor.
							     Saves in the global variable reEditMenu to avoid 
							     recreating the menu over again each time.)
    [COND
      ((NULL reEditMenu)
	(SETQ reEditMenu
	  (create MENU
		  ITEMS ←(QUOTE (OK OK&LispCompile EditRules Help EditAllDecls EditWS STOP Undo! UE 
				    DF Compile Save InspectRuleSet))
		  TITLE ← "Rule Edit Options"]
    reEditMenu])

(REObject
  [LAMBDA (↑ws)                                              (* dgb: " 1-FEB-83 12:24")

          (* * Used to call RE after binding ↑ws.)


    (RE])

(ReinstallRuleSets
  [LAMBDA (className)                                        (* mjs: " 8-JUN-83 18:15")
    (PROG (class methods ruleSetName)
          (SETQ class (GetClassRec className))
          (for selector in (← class List (QUOTE Methods)) do (COND
							       ((SETQ ruleSetName
								   (GetMethod class selector
									      (QUOTE RuleSet)))
								 (DefRSM className selector 
									 ruleSetName])

(RuleSourceEdit
  [LAMBDA (source)                                           (* dgb: "17-Feb-84 10:21")
    (WINDOWPROP TTYINEDITWINDOW (QUOTE TITLE)
		(CONCAT "TTYIN Edit of RuleSet " rsName "    (StopGap Version)"))
    (COND
      ((AND (FNTYP (QUOTE TEDIT))
	    TEDITRULESFLG)
	(TEDIT source TTYINEDITWINDOW T))
      (T (RESETLST (SET.TTYINEDIT.WINDOW)
		   (TTYIN " " NIL NIL (QUOTE (STRING NORAISE REPEAT))
			  NIL NIL source])

(SaveRules
  [LAMBDA (ruleSetSource ruleSet sourceRules ruleObjects)    (* dgb: "21-Feb-84 10:20")

          (* * Saves the rules and declarations from the given sourceRules.)


    (PROG (editor edited)
          (SETQ editor (COND
	      ((EQ USERNAME (QUOTE LOOPSCOURSE))
		StudentName)
	      (T USERNAME)))
          (SETQ edited (DATE))

          (* * Save the declarations.)


          (GetRuleSetDeclarations sourceRules)
          [COND
	    (wsClass (←@
		       ruleSet workSpace (ClassName wsClass]
          (←@
	    ruleSet taskVars taskVars)
          (←@
	    ruleSet tempVars tempVars)
          (←@
	    ruleSet debugVars debugVars)
          (←@
	    ruleSet args rsArgs)
          (←@
	    ruleSet controlStructure controlType)
          (←@
	    ruleSet whileCondition (for term in rsWhileCondition collect (UnParseTerm term)))
          (←@
	    ruleSet compilerOptions rsCompilerOptions)
          [←@
	    ruleSet auditClass (COND
	      ((EQ rsAuditClass ($ StandardAuditRecord))
		NIL)
	      (T (ClassName rsAuditClass]
          (←@
	    ruleSet metaAssignments rsAuditSpecification)
          [←@
	    ruleSet ruleClass (COND
	      ((EQ rsRuleClass ($ Rule))
		NIL)
	      (T (ClassName rsRuleClass]
          (←@
	    ruleSetSource editor editor)
          (←@
	    ruleSetSource edited edited)

          (* * Save the rules.)


          (COND
	    ((NULL ruleObjects)
	      (SETQ rsNumRules (CountRules sourceRules))
	      (SETQ ruleObjects (GetRules sourceRules ruleSet)))
	    (T (SETQ numRules rsNumRules)
	       (SETQ ruleObjects rsRuleObjects)))
          (←@
	    ruleSet numRules rsNumRules)                     (* Hack to remove old Rule objects from indexed vars.)
          (←@
	    ruleSetSource indexedVars NIL)
          (for rule in ruleObjects as I from 1 to rsNumRules
	     do (←@
		  rule edited edited)
		(←@
		  rule editor editor)
		(PutNthValue ruleSetSource I rule])

(SearchStackForWorkSpace
  [LAMBDA NIL                                                (* mjs: "10-JUN-83 11:36")

          (* Climbs the Lisp stack to find the first function corresponding to the invocation of a RuleSet.
	  Then returns the object (self) that is the workspace of the RuleSet during that invocation.)


    (PROG (ruleSetName)
          [for I from 1 to 1000 while (SETQ ruleSetName (STKNTHNAME I))
	     thereis (AND ($! ruleSetName)
			  (← ($! ruleSetName)
			     InstOf!(QUOTE RuleSet]
          (RETURN (COND
		    (ruleSetName (EVALV (QUOTE self)
					(STKPOS ruleSetName 0])
)

(RPAQQ RULESETMISCFNS (CloseREWindow CountRules DefRSM GetRules MINUSMINUS PAUSE PLUSPLUS PutAuditRec 
				     PutClassAuditRec RE RE1 REAskWhy REFocusRuleSet RETraceSelectFn 
				     RSGetFn RSPutFn RuleSetStop RuleSetTransfer SetUpRE TraceLHS 
				     TraceRHS WRITETTY WhichRule?))
(DEFINEQ

(CloseREWindow
  [LAMBDA NIL                                                (* mjs: "29-JUL-83 16:10")

          (* * CLOSEFN for the Rule Exec window. Closes related windows.)


    (COND
      (reTraceWindow (CLOSEW reTraceWindow)))
    (COND
      (reInspectWindow (CLOSEW reInspectWindow])

(CountRules
  [LAMBDA (sourceStr)                                        (* mjs: "13-FEB-83 10:57")

          (* * Counts the number of rules in the given string.)


    (PROG (str rulePos (char T))

          (* * First skip the declarations.)


          (SETQ rulePos (IPLUS 8 (STRPOS "********" sourceStr)))
          (SETQ str (SUBSTRING sourceStr rulePos))

          (* * Then count the semicolons.)


          (RETURN (while char count (EQ semicolon (SETQ char (GNC str])

(DefRSM
  [LAMBDA (className selector ruleSetName)                   (* dgb: "25-Jun-84 16:18")

          (* Installs a RuleSet as a method in the class. If ruleSetName is NIL, then DefRSM creates a RuleSet, invokes the 
	  RuleSet editor, compiles the RuleSet, and installs it as a method in the class. Also initializes the workspace 
	  instance variable.)


    (PROG (ruleSet classRec)                                 (* Check that class exists.)
          (COND
	    ((NOT (SETQ classRec (GetClassRec className)))
	      (PROMPT "Class" className " not found.")
	      (RETURN NIL)))
          (OR selector (SETQ selector (PromptRead "Type selector for RuleSet Method: "))
	      (RETURN))
          [COND
	    ((Object? className)
	      (SETQ className (ClassName className]          (* Create RuleSet if not specified.)
          [COND
	    ((NULL ruleSetName)
	      (SETQ ruleSetName (MethName className selector))
                                                             (* Make the RuleSet.)
	      (SETQ ruleSet (← ($ RuleSet)
			       New NIL ruleSetName))         (* Edit and Compile the RuleSet.)
	      (←@
		ruleSet workSpace className)
	      (← ruleSet ER))
	    (T (SETQ ruleSet (GetObjectRec ruleSetName))
	       (←@
		 ruleSet workSpace className)
	       (SETQ ruleSet (GetObjectRec ruleSetName]
          (←@
	    ruleSet className className)
          (←@
	    ruleSet selector selector)                       (* Create the installation fn.)
                                                             (* Install and document the RuleSet as a method.)
          (PutMethod classRec selector (GetObjectName ruleSet))
          (PutMethod classRec selector ruleSet (QUOTE RuleSet))
          (RETURN (GetObjectName ruleSet])

(GetRules
  [LAMBDA (sourceStr ruleSet)                                (* mjs: " 9-JUN-83 09:32")

          (* * Returns a list of rule objects for rules derived from the given string. Assumes that global rsRuleClass has 
	  been set.)


    (PROG (str rulePos rules rule semiPos ruleStr char (ruleCount 0))

          (* * First skip the declarations.)


          (SETQ rulePos (IPLUS 8 (STRPOS "********" sourceStr)))
          (SETQ str (SUBSTRING sourceStr rulePos))

          (* * Then collect the rules as text between semicolons.)


      NextRule
          (SETQ semiPos (STRPOS semicolon str))
          (COND
	    ((NULL semiPos)
	      (GO Done)))
          (SETQ rule (← rsRuleClass New))
          (SETQ ruleStr (SUBSTRING str 1 semiPos))           (* Eliminate leading CRLFs.)
          (while [AND (SETQ char (SUBATOM ruleStr 1 1))
		      (FMEMB char (CONSTANT (LIST carriageReturn lineFeed]
	     do (SETQ ruleStr (SUBSTRING ruleStr 2)))
          (←@
	    rule source ruleStr)
          (←@
	    rule ruleSet ruleSet)
          (SETQ ruleCount (ADD1 ruleCount))
          (←@
	    rule ruleNumber ruleCount)
          (SETQ rules (NCONC1 rules rule))
          (SETQ str (SUBSTRING str (ADD1 semiPos)))
          (GO NextRule)
      Done(RETURN rules])

(MINUSMINUS
  [LAMBDA (a b)                                              (* mjs: " 3-SEP-82 11:47")

          (* * MinusMinus operator for rules. Defined here to be integer subtraction modulo 4)


    (IREMAINDER (IDIFFERENCE a b)
		4])

(PAUSE
  [LAMBDA (msg1 msg2 msg3 msg4)                              (* mjs: "22-JAN-83 10:55")

          (* * Causes computation to pause until a carriage return is typed.)


    (PROG (msg)
          (SETQ msg (COND
	      (msg4 (CONCAT msg1 msg2 msg3 msg4))
	      (msg3 (CONCAT msg1 msg2 msg3))
	      (msg2 (CONCAT msg1 msg2))
	      (msg1 msg1)
	      (T "PAUSE: Type RETURN to continue.")))
          (INTTYL msg NIL "Type Return when ready to Continue")
          (RETURN T])

(PLUSPLUS
  [LAMBDA (a b)                                              (* mjs: " 3-SEP-82 11:47")

          (* * PlusPlus operator for rules. Defined here to be integer addition modulo 4)


    (IREMAINDER (IPLUS a b)
		4])

(PutAuditRec
  [LAMBDA (auditObject auditVarName newValue auditRecord)    (* mjs: "22-NOV-82 15:24")

          (* * Procedure to set an instance variable to newValue, and then to set its reason property to the given audit 
	  record.)


    (PutValue auditObject auditVarName auditRecord (QUOTE reason))
    (PutValue auditObject auditVarName newValue])

(PutClassAuditRec
  [LAMBDA (self varName newValue auditRecord)                (* mjs: " 5-NOV-82 09:30")

          (* * Procedure to set a class variable to newValue, and then to set its reason property to the given audit 
	  record.)


    (PutClassValue self varName auditRecord (QUOTE reason))
    (PutClassValue self varName newValue])

(RE
  [LAMBDA (wsName)                                           (* mjs: "29-JUL-83 14:04")

          (* * The Rule Exec. Part of the RuleSet debugging facilities. Interprets commands in the syntax of the rule 
	  language and executes them immediately.)


    (COND
      ((NULL reWindow)                                       (* Allocate an RE Exec Window if needed.)
	(SETQ reWindow
	  (CREATEW (create REGION
			   LEFT ← 277
			   BOTTOM ← 12
			   WIDTH ← 600
			   HEIGHT ← 250)
		   "Rule Exec (Stopgap Version)"))
	(WINDOWPROP reWindow (QUOTE CLOSEFN)
		    (FUNCTION CloseREWindow))
	(DSPSCROLL (QUOTE ON)
		   reWindow)
	(WINDOWPROP reWindow (QUOTE RIGHTBUTTONFN)
		    NIL)))

          (* * Clear the reWindow and direct TTY there.)


    (CLEARW reWindow)
    (RESETLST (RESETSAVE (TTY.PROCESS (THIS.PROCESS)))
	      [RESETSAVE (TTYDISPLAYSTREAM (WINDOWPROP reWindow (QUOTE DSP]
	      (RESETSAVE NIL (LIST (QUOTE CLOSEW)
				   reWindow))
	      (PROG [(↑ws (OR wsName (SearchStackForWorkSpace]
		LP  [COND
		      ((NULL ↑ws)
			(SETQ ↑ws (INTTY "Work space: " NIL 
					 "Type name of workSpace.
Type ok to quit."
					 T]                  (* Here if RuleSet found.)
		    (COND
		      ((FMEMB ↑ws (QUOTE (ok Ok OK)))
			(RETURN T)))
		    (SETQ ↑ws ($! ↑ws))
		    (COND
		      ((NULL ↑ws)
			(WRITE "Work space not found.")
			(GO LP)))
		    (RE1)
		    (RETURN T])

(RE1
  [LAMBDA NIL                                                (* edited: "29-FEB-84 17:12")

          (* * Subroutine of RE. Contains the Read-Compile-Eval-Print Loop.)


    (PROG [self ↑ruleSetNames ↑comStr ↑comExpr prevTokens [whyTokens (CONSTANT (QUOTE (WHY Why why]
		(↑doneExprs (CONSTANT (QUOTE (OK Ok ok DONE Done done BYE Bye bye]

          (* * Set up RE menus.)


          (SETQ ↑ruleSetNames (SetUpRE))

          (* * Read Compile Evaluate Print Loop.)


          (SETQ self ↑ws)
      RELoop
          (TOTOPW reTraceWindow)
          [SETQ ↑comStr (TTYIN "re: " NIL NIL (QUOTE (STRING NORAISE]
          (COND
	    ((NULL ↑comStr)
	      (GO RELoop))
	    ((OR (STREQUAL ↑comStr "UE")
		 (STREQUAL ↑comStr "ue"))
	      (CLOSEW reWindow)
	      (UE)
	      (GO RELoop))
	    ((STREQUAL ↑comStr "?")
	      (WRITE 
"To inspect a work space, use LEFT mouse button in trace menu.
To print a RuleSet, use MIDDLE mouse button in trace menu.
To evaluate a Rule expression, type it in this window.
To get the LISP User Exec, type UE.
To quit, type OK.")
	      (GO RELoop)))                                  (* Parse the tokens.)
          (ParseTokens ↑comStr)
          (COND
	    ((FMEMB (CAR ruleSetTokens)
		    whyTokens)
	      (REAskWhy)
	      (GO RELoop))
	    ((FMEMB (CAR ruleSetTokens)
		    ↑doneExprs)
	      (RETURN T)))                                   (* Save tokens in case next query is a bare why.)
          (SETQ prevTokens ruleSetTokens)

          (* * Add extra semicolon and Parse the rule.)


          (SETQ ruleSetTokens (NCONC1 ruleSetTokens semicolon))
          [SETQ ↑comExpr (CAR (CompileRule1 (QUOTE specialFlg]
          (COND
	    (rsCompilerDebugFlg (WRITE "↑comExpr=" ↑comExpr)))
          [COND
	    ((NULL parseErrorFlg)
	      (NLSETQ (WRITE (EVAL ↑comExpr]
          (REFocusRuleSet)
          (GO RELoop])

(REAskWhy
  [LAMBDA NIL                                                (* edited: "29-FEB-84 17:20")
                                                             (* Subroutine of RE to handle a WHY command to see why a
							     variable has a particular value.)
    (PROG (compiledExpr rule)                                (* First Remove the WHY token.)
          (pop ruleSetTokens)
          (COND
	    ((EQ semicolon (CAR ruleSetTokens))
	      (SETQ ruleSetTokens prevTokens)
	      (printout T "   -- That is, why " (CAR ruleSetTokens)
			T T)))                               (* Compile the expression as if a regular fetch.)
          (SETQ ruleSetTokens (NCONC1 ruleSetTokens semicolon))
          (SETQ compiledExpr (CAR (CompileRule1)))           (* Remove the ↑value code.)
          (SETQ compiledExpr (CADDR compiledExpr))
          (SELECTQ (CAR compiledExpr)
		   (GetValue (RPLACA compiledExpr (QUOTE WhichRule?)))
		   (GetClassValue (RPLACA compiledExpr (QUOTE WhichRule?))
				  (NCONC1 compiledExpr T))
		   (PROGN (WRITE "eh?")
			  (GO Done)))
          (SETQ rule (EVAL compiledExpr))
          (COND
	    (rule (← rule Print))
	    (T (WRITE "Rule not known.")))
      Done(TERPRI])

(REFocusRuleSet
  [LAMBDA NIL                                                (* mjs: " 8-JUN-83 10:47")

          (* * Initialize global variables for a RuleSet so that RE will operate correctly with the compiler.
	  The variable self is the RuleSet.)


    (SETQ wsClass (Class ↑ws))
    (SETQ wsVars (← wsClass List!(QUOTE IVS)))
    (SETQ taskVars NIL)
    (SETQ tempVars NIL)
    (SETQ controlType (QUOTE DOALL))
    (SETQ ruleNumber -10000)
    (SETQ rsTraceFlg NIL)
    (SETQ rsBreakFlg NIL)
    (SETQ rsAuditFlg NIL)
    (SETQ ruleObject NIL)
    (SETQ rsTaskFlg NIL])

(RETraceSelectFn
  [LAMBDA (item menu key)                                    (* mjs: " 9-JUN-83 10:40")
                                                             (* Menu Select Fn for the RuleExec Trace Window.
							     Allows printing of RuleSet or Inspecting of its work 
							     space.)
    (PROG (ws)
          (SELECTQ key
		   (LEFT (SETQ ws (CADR item))
			 (SETQ ↑reInspectWindow (← ws Inspect)))
		   [MIDDLE (EVAL.IN.TTY.PROCESS (BQUOTE (← , (GetObjectRec (CAR item))
							   ER]
		   NIL])

(RSGetFn
  [LAMBDA (self varName localSt propName activeVal type)     (* mjs: " 7-JUN-83 10:48")

          (* * This is the getFn for invoking a RuleSet on Get operations in an active value. It assumes that the RuleSet 
	  can be found on the RSGet property of the varName variable in self. The local state is given to the RuleSet as its
	  work space. The value returned by RSGetFn is the value computed by the RuleSet.)


    (PROG (ruleSet ruleValue)
          [SETQ ruleSet (GetObjectRec (GetValue self varName (QUOTE RSGet]
          (COND
	    ((OR (NULL ruleSet)
		 (NOT (Class? (QUOTE RuleSet)
			      ruleSet)))
	      (ERROR "RuleSet not found for active value.")))
          (SETQ ruleValue (RunRS ruleSet localSt))
          (RETURN ruleValue])

(RSPutFn
  [LAMBDA (self varName newValue propName activeVal type)    (* mjs: " 7-JUN-83 10:49")

          (* * This is a putFn for invoking a RuleSet on Put operations in active values. It assumes that the RuleSet can be
	  found on the property RSPut of varName in self. The argument newValue is given to the RuleSet as its the work 
	  space. The value returned by the RuleSet is put into the local state of the active value.)


    (PROG (ruleSet ruleValue)
          [SETQ ruleSet (GetObjectRec (GetValue self varName (QUOTE RSPut]
          (COND
	    ((OR (NULL ruleSet)
		 (NOT (Class? (QUOTE RuleSet)
			      ruleSet)))
	      (ERROR "RuleSet not found for active value.")))
          (SETQ ruleValue (RunRS ruleSet newValue))
          (RETURN (PutLocalState activeVal ruleValue self varName propName type])

(RuleSetStop
  [LAMBDA (stopValue ↑status ↑reason)                        (* mjs: " 7-JUN-83 10:18")

          (* * Used to carry out STOP statements in RuleSets. Sets instance variables in the Task. Arg ↑value is implicitly 
	  passed from the RuleSet.)


    (SETQ ↑value stopValue)                                  (* Add code here to save status and reason when tasks 
							     get implemented.)
    ↑value])

(RuleSetTransfer
  [LAMBDA (ruleSetArgs)                                      (* mjs: "29-OCT-82 17:00")

          (* Does a control transfer eliminating tail recursion for rule sets. Special version of RETAPPLY which cuts back 
	  past internal frames put on the stack if RETAPPLY was used before.)


    (PROG [(ruleSetPos (STKPOS (QUOTE RuleSet.Run]
          (COND
	    ((NULL ruleSetPos)
	      (ERROR "Must be inside a RuleSetR.Run to transfer"))
	    ((AND (EQ (QUOTE APPLY)
		      (STKNTHNAME -1 ruleSetPos))
		  (EQ (QUOTE *ENV*)
		      (STKNTHNAME -2 ruleSetPos)))           (* RETAPPLY has been used before.
							     Fix up stack pointer to be 2 back)
	      (STKNTH -3 ruleSetPos ruleSetPos)))
          (ENVAPPLY (QUOTE RuleSet.Run)
		    ruleSetArgs ruleSetPos ruleSetPos T T])

(SetUpRE
  [LAMBDA NIL                                                (* dgb: " 9-Mar-84 00:10")

          (* * Fn to initialize the break windows and menus for the RuleExec.)


    (PROG (ruleSetNames stkName traceMenu mPosition wRegion)
          (SETQ controltype (QUOTE DOALL))
          (REFocusRuleSet)

          (* * Set up Trace Menu.)


          [SETQ ruleSetNames (for I from 1 to 1000 while (SETQ stkName (STKNTHNAME I))
				when (AND (GetObjectRec stkName)
					  (← (GetObjectRec stkName)
					     InstOf!(QUOTE RuleSet)))
				collect (PROG [(WS (EVALV (QUOTE self)
							  (STKPOS stkName 0]
					      (RETURN (LIST stkName WS (CONCAT "Left to INSPECT "
									       (GetObjectName WS)
									       "
" "Middle to EDIT " stkName " rules"]
          (SETQ traceMenu
	    (create MENU
		    ITEMS ← ruleSetNames
		    ITEMWIDTH ← 150
		    MENUCOLUMNS ← 1
		    MENUFONT ← rsTraceFont
		    WHENSELECTEDFN ←(FUNCTION RETraceSelectFn)))
          (SETQ wRegion (WINDOWPROP reWindow (QUOTE REGION)))
          (SETQ mPosition (create POSITION
				  XCOORD ←(IDIFFERENCE (fetch LEFT of wRegion)
						       151)
				  YCOORD ←(IPLUS (fetch BOTTOM of wRegion)
						 (fetch HEIGHT of wRegion)
						 -50)))
          (SETQ reTraceWindow (ADDMENU traceMenu NIL mPosition])

(TraceLHS
  [LAMBDA (ruleSetName ruleLab ruleNum)                      (* mjs: " 8-JUN-83 11:28")

          (* * Invoked to print a trace msg for the LHS of a rule.)


    (PROGN (printout T "Testing rule " .FONT BOLDFONT (OR ruleLab ruleNum)
		     .FONT DEFAULTFONT " in  RuleSet " .FONT BOLDFONT ruleSetName .FONT DEFAULTFONT T)
	   T])

(TraceRHS
  [LAMBDA (ruleSetName ruleLab ruleNum ↑value)               (* mjs: " 8-JUN-83 11:28")

          (* * Invoked to print a trace msg for the RHS of a rule.)


    (PROGN (printout T "Executing rule " .FONT BOLDFONT (OR ruleLab ruleNum)
		     .FONT DEFAULTFONT " in RuleSet " .FONT BOLDFONT ruleSetName .FONT DEFAULTFONT T)
	   ↑value])

(WRITETTY
  [LAMBDA nargs                                              (* mjs: "15-NOV-82 09:51")
                                                             (* Write each argument out to the TTY.
							     Value is T. Called by various rule tracing fns.)
    (PROG ((I 0))
          [while (ILESSP I nargs) do (PRIN1 (ARG nargs (SETQ I (ADD1 I]
          (TERPRI)
          (RETURN T])

(WhichRule?
  [LAMBDA (obj varName classFlg)                             (* mjs: " 9-JUN-83 09:42")

          (* * Returns the source code for the rule that set the variable named varName on object if an appropriate audit 
	  record has been saved on the reason property of the variable.)


    (PROG (auditRecord)
          [SETQ auditRecord (COND
	      (classFlg (GetClassValue obj varName (QUOTE reason)))
	      (T (GetValue obj varName (QUOTE reason]
          (RETURN (COND
		    ((AND auditRecord (NEQ auditRecord NotSetValue))
		      (@ auditRecord rule])
)

(RPAQQ TEDITRULESFLG T)

(RPAQQ ↑rs NIL)

(RPAQQ ↑ws NIL)

(RPAQQ ↑caller NIL)

(RPAQQ ↑task NIL)

(RPAQQ reWindow NIL)

(RPAQQ reTraceWindow NIL)

(RPAQQ reInspectWindow NIL)

(RPAQ rsTraceFont (FONTCREATE (QUOTE GACHA)
			      8))
(CLDISABLE (QUOTE ↑))
(INTERRUPTCHAR 6 (LIST (FUNCTION RE)))
(DECLARE: EVAL@COMPILE 

(PUTPROPS RunRS MACRO ((rs ws . args)
		       (APPLY* (COND
				 ((LITATOM rs)
				   rs)
				 (T (GetObjectName rs)))
			       ws . args)))
)
(DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS 

(ADDTOVAR NLAMA )

(ADDTOVAR NLAML )

(ADDTOVAR LAMA WRITETTY)
)
(PUTPROPS LOOPSRULES COPYRIGHT ("Xerox Corporation" 1983 1984))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (9442 21192 (Rule.Print 9452 . 10011) (RuleSet.CompileRules 10013 . 10469) (
RuleSet.CopyRules 10471 . 11252) (RuleSet.EditRules 11254 . 11689) (RuleSet.Off 11691 . 12149) (
RuleSet.On 12151 . 12520) (RuleSet.PPRules 12522 . 12742) (RuleSetMeta.New 12744 . 13503) (
RuleSetSource.CompileRules 13505 . 15893) (RuleSetSource.EditRules 15895 . 19679) (
RuleSetSource.GetSource 19681 . 20563) (RuleSetSource.PPRules 20565 . 21190)) (21332 27500 (
ListRuleSets 21342 . 23200) (MakeEditMenu 23202 . 23789) (REObject 23791 . 23968) (ReinstallRuleSets 
23970 . 24416) (RuleSourceEdit 24418 . 24862) (SaveRules 24864 . 26861) (SearchStackForWorkSpace 26863
 . 27498)) (27794 45150 (CloseREWindow 27804 . 28110) (CountRules 28112 . 28621) (DefRSM 28623 . 30423
) (GetRules 30425 . 31734) (MINUSMINUS 31736 . 31985) (PAUSE 31987 . 32482) (PLUSPLUS 32484 . 32720) (
PutAuditRec 32722 . 33092) (PutClassAuditRec 33094 . 33451) (RE 33453 . 34882) (RE1 34884 . 36795) (
REAskWhy 36797 . 38042) (REFocusRuleSet 38044 . 38636) (RETraceSelectFn 38638 . 39171) (RSGetFn 39173
 . 39951) (RSPutFn 39953 . 40792) (RuleSetStop 40794 . 41234) (RuleSetTransfer 41236 . 42057) (SetUpRE
 42059 . 43427) (TraceLHS 43429 . 43785) (TraceRHS 43787 . 44149) (WRITETTY 44151 . 44564) (WhichRule?
 44566 . 45148)))))
STOP