Artifact 475c5d270ba2bc81e887889d1ed7281212f525ebcaccaf5e7a90c78697963aaf:
- File
psl-1983/3-1/lpt/17-utilities.lpt
— part of check-in
[eb17ceb7f6]
at
2020-04-21 19:40:01
on branch master
— Add Reduce 3.0 to the historical section of the archive, and some more
files relating to version sof PSL from the early 1980s. Thanks are due to
Paul McJones and Nelson Beebe for these, as well as to all the original
authors.git-svn-id: https://svn.code.sf.net/p/reduce-algebra/code/historical@5328 2bfe0521-f11c-4a00-b80e-6202646ff360 (user: arthurcnorman@users.sourceforge.net, size: 62623) [annotate] [blame] [check-ins using] [more...]
- File
psl-1983/lpt/17-utilities.lpt
— part of check-in
[eb17ceb7f6]
at
2020-04-21 19:40:01
on branch master
— Add Reduce 3.0 to the historical section of the archive, and some more
files relating to version sof PSL from the early 1980s. Thanks are due to
Paul McJones and Nelson Beebe for these, as well as to all the original
authors.git-svn-id: https://svn.code.sf.net/p/reduce-algebra/code/historical@5328 2bfe0521-f11c-4a00-b80e-6202646ff360 (user: arthurcnorman@users.sourceforge.net, size: 62623) [annotate] [blame] [check-ins using]
PSL Manual 7 February 1983 Utilities section 17.0 page 17.1 CHAPTER 17 CHAPTER 17 CHAPTER 17 MISCELLANEOUS UTILITIES MISCELLANEOUS UTILITIES MISCELLANEOUS UTILITIES 17.1. Introduction . . . . . . . . . . . . . . . 17.1 17.2. RCREF - Cross Reference Generator for PSL Files . . . 17.1 17.2.1. Restrictions. . . . . . . . . . . . . 17.2 17.2.2. Usage . . . . . . . . . . . . . . . 17.3 17.2.3. Options . . . . . . . . . . . . . . 17.3 17.3. Picture RLISP. . . . . . . . . . . . . . . 17.4 17.3.1. Running PictureRLISP on HP2648A and on TEKTRONIX 17.10 4006-1 Terminals . . . . . . . . . . . 17.4. Tools for Defining Macros. . . . . . . . . . . 17.11 17.4.1. DefMacro . . . . . . . . . . . . . . 17.11 17.4.2. BackQuote. . . . . . . . . . . . . . 17.12 17.4.3. Sharp-Sign Macros . . . . . . . . . . . 17.12 17.4.4. MacroExpand . . . . . . . . . . . . . 17.13 17.4.5. DefLambda. . . . . . . . . . . . . . 17.13 17.5. Simulating a Stack . . . . . . . . . . . . . 17.14 17.6. DefStruct . . . . . . . . . . . . . . . . 17.14 17.6.1. Options . . . . . . . . . . . . . . 17.17 17.6.2. Slot Options. . . . . . . . . . . . . 17.18 17.6.3. A Simple Example . . . . . . . . . . . 17.18 17.7. DefConst . . . . . . . . . . . . . . . . 17.21 17.8. Functions for Sorting . . . . . . . . . . . . 17.22 17.9. Hashing Cons . . . . . . . . . . . . . . . 17.23 17.10. Graph-to-Tree . . . . . . . . . . . . . . 17.25 17.11. Inspect Utility. . . . . . . . . . . . . . 17.25 17.1. Introduction 17.1. Introduction 17.1. Introduction This chapter describes an assortment of utility packages. Its purpose is to record the existence and capabilities of a number of tools. More information on existing packages can be found by looking at the current set of HELP files (DIR PH:*.* on the DEC-20). 17.2. RCREF - Cross Reference Generator for PSL Files 17.2. RCREF - Cross Reference Generator for PSL Files 17.2. RCREF - Cross Reference Generator for PSL Files RCREF is a Standard LISP program for processing a set of Standard LISP function definitions to produce: a. A "Summary" showing: Utilities 7 February 1983 PSL Manual page 17.2 section 17.2 i. A list of files processed. ii. A list of "entry points" (functions which are not called or are called only by themselves). iii. A list of undefined functions (functions called but not defined in this set of functions). iv. A list of variables that were used non-locally but not declared GLOBAL or FLUID before their use. v. A list of variables that were declared GLOBAL but used as FLUIDs (i.e. bound in a function). vi. A list of FLUID variables that were not bound in a function so that one might consider declaring them GLOBALs. vii. A list of all GLOBAL variables present. viii. A list of all FLUID variables present. ix. A list of all functions present. b. A "global variable usage" table, showing for each non-local variable: i. Functions in which it is used as a declared FLUID or GLOBAL. ii. Functions in which it is used but not declared before. iii. Functions in which it is bound. SetQ SetQ iv. Functions in which it is changed by SetQ. c. A "function usage" table showing for each function: i. Where it is defined. ii. Functions which call this function. iii. Functions called by it. iv. Non-local variables used. The output is alphabetized on the first seven characters of each function name. RCREF also checks that functions are called with the correct number of arguments. 17.2.1. Restrictions 17.2.1. Restrictions 17.2.1. Restrictions Algebraic procedures in REDUCE are treated as if they were symbolic, so that algebraic constructs actually appear as calls to symbolic functions, AEval AEval such as AEval. SYSLISP procedures are not correctly analyzed. PSL Manual 7 February 1983 Utilities section 17.2 page 17.3 17.2.2. Usage 17.2.2. Usage 17.2.2. Usage RCREF should be used in PSL:RLISP. To make a file FILE.CRF which is a cross reference listing for files FILE1.EX1 and FILE2.EX2 do the following in RLISP: @PSL:RLISP LOAD RCREF; % RCREF is now autoloading, so this may be omitted OUT "file.crf"; % later, CREFOUT ... ON CREF; IN "file1.ex1","file2.ex2"; OFF CREF; SHUT "file.crf"; % later CREFEND To process more files, more IN statements may be added, or the IN statement may be changed to include more files. 17.2.3. Options 17.2.3. Options 17.2.3. Options __________ ______ !*CREFSUMMARY [Initially: NIL] switch If the switch CREFSUMMARY is ON then only the summary (see 1 above) is produced. Functions with the flag NOLIST are not examined or output. Initially, all Standard LISP functions are so flagged. (In fact, they are kept on a list NOLIST!*, so if you wish to see references to ALL functions, then CREF should be first loaded with the command LOAD RCREF, and this variable then set to NIL). (RCREF is now autoloading.) __________ ______ NOLIST!* [Initially: the following list] global (AND COND LIST MAX MIN OR PLUS PROG PROG2 PROGN TIMES LAMB ADD1 APPEND APPLY ASSOC ATOM CAR CDR CAAR CADR CDAR CDDR CAADR CADAR CADDR CDAAR CDADR CDDAR CDDDR CAAAAR CAAADR CAADDR CADAAR CADADR CADDAR CADDDR CDAAAR CDAADR CDADAR CDDAAR CDDADR CDDDAR CDDDDR CLOSE CODEP COMPRESS CONS CO DE DEFLIST DELETE DF DIFFERENCE DIGIT DIVIDE DM EJECT EQUAL ERROR ERRORSET EVAL EVLIS EXPAND EXPLODE EXPT FIX FI FLAGP FLOAT FLOATP FLUID FLUIDP FUNCTION GENSYM GET GET GLOBAL GLOBALP GO GREATERP IDP INTERN LENGTH LESSP LIN LITER LPOSN MAP MAPC MAPCAN MAPCAR MAPCON MAPLIST MAX2 MEMQ MINUS MINUSP MIN2 MKVECT NCONC NOT NULL NUMBERP ONE PAGELENGTH PAIR PAIRP PLUS2 POSN PRINC PRINT PRIN1 PRIN2 PUT PUTD PUTV QUOTE QUOTIENT RDS READ READCH REMAINDE REMFLAG REMOB REMPROP RETURN REVERSE RPLACA RPLACD SASS SETQ STRINGP SUBLIS SUBST SUB1 TERPRI TIMES2 UNFLUID UPBV WRS ZEROP) Utilities 7 February 1983 PSL Manual page 17.4 section 17.2 It should also be remembered that in RLISP any macros with the flag EXPAND or, if FORCE is on, without the flag NOEXPAND are expanded before the definition is seen by the cross-reference program, so this flag can also be used to select those macros you require expanded and those you do not. The use of ON FORCE; is highly recommended for CREF. 17.3. Picture RLISP 17.3. Picture RLISP 17.3. Picture RLISP [??? ReWrite ???] [??? ReWrite ???] [??? ReWrite ???] Picture RLISP is an ALGOL-like graphics language for Teleray, HP2648a and Tektronix, in which graphics Model primitives are combined into complete Models for display. PRLISP is a 3D version; PRLISP2D is a faster, smaller 2D version which also drives more terminals. Two demonstration files, PR-DEMO.RED and PR-DEMO.Sl, are available on PU. See the help files PH:PRLISP.HLP and PRLISP2D.HLP. Model primitives include: P:={x,y,z}; A point (y, and z may be omitted, default to 0). PS:=P1_ P2_ ... Pn; A Point Set is an ordered set of Points (Polygon). G := PS1 & PS2 & ... PSn; A Group of Polygons. Point Set Modifiers alter the interpretation of Point Sets within their scope. BEZIER() causes the point-set to be interpreted as the specification points for a BEZIER curve, open pointset. BSPLINE() does the same for a Bspline curve, closed pointset. TRANSFORMS: Mostly return a transformation matrix. Translation: Move the specified amount along the specified axis. XMOVE(deltaX); YMOVE(deltaY); ZMOVE(deltaZ); MOVE(deltaX, deltaY, deltaZ); Scale: Scale the Model SCALE (factor) XSCALE(factor); YSCALE(factor); ZSCALE(factor); SCALE1(x.scale.factor, y.scale.factor, z.scale.factor); SCALE<Scale factor>;. Scale along all axes. PSL Manual 7 February 1983 Utilities section 17.3 page 17.5 Rotation: ROT(degrees); ROT(degrees, point.specifying.axis); XROT(degrees); YROT(degrees); ZROT(degrees); Window (z.eye,z.screen): The WINDOW primitives assume that the viewer is located along the z axis looking in the positive z direction, and that the viewing window is to be centered on both the x and y axis. Vwport(leftclip,rightclip,topclip,bottomclip): The VWPORT, which specifies the region of the screen which is used for display. REPEATED (number.of.times, my.transform): The Section of the Model which is contained within the scope of the Repeat Specification is replicated. Note that REPEATED is intended to duplicate a sub-image in several different places on the screen; it was not designed for animation. Identifiers of other Models the Model referred to is displayed as if it were part of the current Model for dynamic display. Calls to PictureRLISP Procedures This Model primitive allows procedure calls to be imbedded within Models. When the Model interpreter reaches the procedure identifier it calls it, passing it the portion of the Model below the procedure as an argument. The current transformation matrix and the current pen position are available to such procedures as the values of the global identifiers GLOBAL!.TRANSFORM and HEREPOINT. If normal procedure call syntax, i.e. proc.name (parameters), is used then the procedure is called at Model-building time, but if only the procedure's identifier is used then the procedure is imbedded in the Model. ERASE() Clears the screen and leaves the cursor at the origin. SHOW(pict) Takes a picture and displays it on the screen. ESHOW (pict) Erases the whole screen and display "pict". HP!.INIT(), TEK!.INIT(), TEL!.INIT() Initializes the operating system's view of the characteristics of HP2648A terminal, TEKTRONIX 4006-1 (also ADM-3A with Retrographics board, and Teleray-1061). For example, the Model Utilities 7 February 1983 PSL Manual page 17.6 section 17.3 (A _ B _ C & {1,2} _ B) | XROT (30) | 'TRAN ; % % PictureRLISP Commands to SHOW lots of Cubes % % Outline is a Point Set defining the 20 by 20 % square which is part of the Cubeface % Outline := { 10, 10} _ {-10, 10} _ {-10,-10} _ { 10,-10} _ {10, 10}; % Cubeface also has an Arrow on it % Arrow := {0,-1} _ {0,2} & {-1,1} _ {0,2} _ {1,1}; % We are ready for the Cubeface Cubeface := (Outline & Arrow) | 'Tranz; % Note the use of static clustering to keep objects % meaningful as well as the quoted Cluster % to the as yet undefined transformation Tranz, % which results in its evaluation being % deferred until SHOW time % and now define the Cube Cube := Cubeface & Cubeface | XROT (180) % 180 degrees & Cubeface | YROT ( 90) & Cubeface | YROT (-90) & Cubeface | XROT ( 90) & Cubeface | XROT (-90); % In order to have a more pleasant look at % the picture shown on the screen we magnify % cube by 5 times. BigCube := Cube | SCALE 5; % Set up initial Z Transform for each cube face % Tranz := ZMOVE (10); % 10 units out % % GLOBAL!.TRANSFORM has been treated as a global variable. % GLOBAL!.TRANSFORM should be initialized as a perspective % transformation matrix so that a viewer can have a correct % look at the picture as the viewing location changed. % For instance, it may be set as the desired perspective % with a perspective window centered at the origin and % of screen size 60, and the observer at -300 on the z axis. % Currently this has been set as default perspective transformation. PSL Manual 7 February 1983 Utilities section 17.3 page 17.7 % Now draw cube % SHOW BigCube; % Utilities 7 February 1983 PSL Manual page 17.8 section 17.3 % Draw it again rotated and moved left % SHOW (BigCube | XROT 20 | YROT 30 | ZROT 10); % Dynamically expand the faces out % Tranz := ZMOVE 12; % SHOW (BigCube | YROT 30 | ZROT 10); % Now show 5 cubes, each moved further right by 80 % Tranz := ZMOVE 10; % SHOW (Cube | SCALE 2.5 | XMOVE (-240) | REPEATED(5, XMOVE 80)); % % Now try pointset modifier. % Given a pointset (polygon) as control points either a BEZIER or a % BSPLINE curve can be drawn. % Cpts := {0,0} _ {70,-60} _ {189,-69} _ {206,33} _ {145,130} _ {48,13 _ {0,84} $ % % Now draw Bezier curve % Show the polygon and the Bezier curve % SHOW (Cpts & Cpts | BEZIER()); % Now draw Bspline curve % Show the polygon and the Bspline curve % SHOW (Cpts & Cpts | BSPLINE()); % Now work on the Circle % Given a center position and a radius a circle is drawn % SHOW ( {10,10} | CIRCLE(50)); % % Define a procedure which returns a model of % a Cube when passed the face to be used % Symbolic Procedure Buildcube; List 'Buildcube; % put the name onto the property list Put('buildcube, 'pbintrp, 'Dobuildcube); Symbolic Procedure Dobuildcube Face$ Face & Face | XROT(180) & Face | YROT(90) & Face | YROT(-90) PSL Manual 7 February 1983 Utilities section 17.3 page 17.9 & Face | XROT(90) & Face | XROT(-90) ; % just return the value of the one statement % Use this procedure to display 2 cubes, with and % without the Arrow - first do it by calling % Buildcube at time the Model is built % P := Cubeface | Buildcube() | XMOVE(-15) & (Outline | 'Tranz) | Buildcube() | XMOVE 15; % SHOW (P | SCALE 5); % Now define a procedure which returns a Model of % a cube when passed the half size parameter Symbolic Procedure Cubemodel; List 'Cubemodel; %put the name onto the property list Put('Cubemodel,'Pbintrp, 'Docubemodel); Symbolic Procedure Docubemodel HSize; << if idp HSize then HSize := eval HSize$ { HSize, HSize, HSize} _ {-HSize, HSize, HSize} _ {-HSize, -HSize, HSize} _ { HSize, -HSize, HSize} _ { HSize, HSize, HSize} _ { HSize, HSize, -HSize} _ {-HSize, HSize, -HSize} _ {-HSize, -HSize, -HSize} _ { HSize, -HSize, -HSize} _ { HSize, HSize, -HSize} & {-HSize, HSize, -HSize} _ {-HSize, HSize, HSize} & {-HSize, -HSize, -HSize} _ {-HSize, -HSize, HSize} & { HSize, -HSize, -HSize} _ { HSize, -HSize, HSize} >>; % Imbed the parameterized cube in some Models % His!.cube := 'His!.size | Cubemodel(); Her!.cube := 'Her!.size | Cubemodel(); R := His!.cube | XMOVE (60) & Her!.cube | XMOVE (-60) ; % Set up some sizes and SHOW them His!.size := 50; Her!.size := 30; % SHOW R ; Utilities 7 February 1983 PSL Manual page 17.10 section 17.3 % % Set up some different sizes and SHOW them again % His!.size := 35; Her!.size := 60; % SHOW R; % % Now show a triangle rotated 45 degree about the z axis. Rotatedtriangle := {0,0} _ {50,50} _ {100,0} _ {0,0} | Zrot (45); % SHOW Rotatedtriangle; % % Define a procedure which returns a model of a Pyramid % when passed 4 vertices of a pyramid. % Procedure Second,Third, Fourth and Fifth are primitive procedures % written in the source program which return the second, the third, % the fourth and the fifth element of a list respectively. % This procedure simply takes 4 points and connects the vertices to % show a pyramid. Symbolic Procedure Pyramid (Point4); %.point4 is a pointset Point4 & Third Point4 _ Fifth Point4 _ Second Point4 _ Fourth Point4 ; % Now give a pointset indicating 4 vertices build a pyramid % and show it % My!.vertices := {-40,0} _ {20,-40} _ {90,20} _ {70,100}; My!.pyramid := Pyramid Vertices; % SHOW ( My!.pyramid | XROT 30); % % A procedure that makes a wheel with "count" % spokes rotated around the z axis. % in which "count" is the number specified. Symbolic Procedure Dowheel(spoke,count)$ begin scalar rotatedangle$ count := first count$ rotatedangle := 360.0 / count$ return (spoke | REPEATED(count, ZROT rotatedangle)) end$ % % Now draw a wheel consisting of 8 cubes % PSL Manual 7 February 1983 Utilities section 17.3 page 17.11 Cubeonspoke := (Outline | ZMOVE 10 | SCALE 2) | buildcube(); Eight!.cubes := Cubeonspoke | XMOVE 50 | WHEEL(8); % SHOW Eight!.cubes; % %Draw a cube in which each face consists of just % a wheel of 8 Outlines % Flat!.Spoke := outline | XMOVE 25$ A!.Fancy!.Cube := Flat!.Spoke | WHEEL(8) | ZMOVE 50 | Buildcube()$ % SHOW A!.Fancy!.Cube; % % Redraw the fancy cube, after changing perspective by % moving the observer farther out along Z axis % GLOBAL!.TRANSFORM := WINDOW(-500,60); % SHOW A!.Fancy!.Cube; % % Note the flexibility resulting from the fact that % both Buildcube and Wheel simply take or return any % Model as their argument or value The current version of PictureRLISP runs on HP2648A graphics terminal and TEKTRONIX 4006-1 computer display terminal. The screen of the HP terminal is 720 units long in the X direction, and 360 units high in the Y direction. The coordinate system used in HP terminal places the origin in approximately the center of the screen, and uses a domain of -360 to 360 and a range of -180 to 180. Similarly, the screen of the TEKTRONIX terminal is 1024 units long in the X direction, and 780 units high in the Y direction. The same origin is used but the domain is -512 to 512 in the X direction and the range is -390 to 390 in the Y direction. Procedures HP!.INIT and TEK!.INIT are used to set the terminals to graphics mode and initiate the lower level procedures on HP and TEKTRONIX terminals respectively. Basically, INIT procedures are written for different terminals depending on their specific characteristics. Using INIT procedures keeps terminal device dependence at the user's level to a minimum. 17.4. Tools for Defining Macros 17.4. Tools for Defining Macros 17.4. Tools for Defining Macros The following (and other) macro utilities are in the file PU:USEFUL.SL; Utilities 7 February 1983 PSL Manual page 17.12 section 17.4 1 use (LOAD USEFUL) to access. See PH:USEFUL.HLP for more information. 17.4.1. DefMacro 17.4.1. DefMacro 17.4.1. DefMacro DefMacro DefMacro _ __ _ ____ _ ____ __ _____ (DefMacro A:id B:form [C:form]): id macro _____ _____ _____ DefMacro macro DefMacro DefMacro macro DefMacro DefMacro is a useful tool for defining macros. A DefMacro form looks like (DEFMACRO <NAME> <PATTERN> <S1> <S2> ... <Sn>) ____ __ The <PATTERN> is an S-expression made of pairs and ids. It is _____ _____ _____ macro macro matched against the arguments of the macro much like the first DeSetQ DeSetQ __ argument to DeSetQ. All of the non-NIL ids in <pattern> are local variables which may be used freely in the body (the <Si>). _____ _____ _____ macro ProgN macro ProgN If the macro is called the <Si> are evaluated as in a ProgN with the local variables in <pattern> appropriately bound, and the DefMacro DefMacro value of <Sn> is returned. DefMacro is often used with BackQuote. 17.4.2. BackQuote 17.4.2. BackQuote 17.4.2. BackQuote Note that the special symbols described below only work in LISP syntax, BackQuote UnQuote BackQuote UnQuote not RLISP. In RLISP you may simply use the functions BackQuote, UnQuote, UnQuoteL BackQuote UnQuoteL BackQuote and UnQuoteL. Load USEFUL to get the BackQuote function. _____ _____ _____ Read macro Read macro The backquote symbol "`" is a Read macro which introduces a quoted expression which may contain the unquote symbols comma "," and comma-atsign ",@". An appropriate form consisting of the unquoted expression calls to Cons Cons the function Cons and quoted expressions are produced so that the resulting expression looks like the quoted one except that the values of the unquoted expressions are substituted in the appropriate place. ",@" splices in the value of the subsequent expression (i.e. strips off the outer layer of parentheses). Thus `(a (b ,x) c d ,@x e f) is equivalent to (cons 'a (cons (list 'b x) (append '(c d) (append x '(e f))))) In particular, if x is bound to (1 2 3) this evaluates to _______________ 1 Useful was written by D. Morrison. PSL Manual 7 February 1983 Utilities section 17.4 page 17.13 (a (b (1 2 3)) c d 1 2 3 e f) BackQuote BackQuote _ ____ ____ _____ (BackQuote A:form): form macro Function name for back quote `. UnQuote UnQuote _ ___ _________ _____ (UnQuote A:any): Undefined fexpr Eval Eval Function name for comma ,. It is an error to Eval this function; BackQuote BackQuote it should occur only inside a BackQuote. UnQuoteL UnQuoteL _ ___ _________ _____ (UnQuoteL A:any): Undefined fexpr Eval Eval Function name for comma-atsign ,@. It is an error to Eval this BackQuote BackQuote function; it should only occur inside a BackQuote. 17.4.3. Sharp-Sign Macros 17.4.3. Sharp-Sign Macros 17.4.3. Sharp-Sign Macros USEFUL defines several MACLISP style sharp sign read macros. Note that these only work with the LISP reader, not RLISP. Those currently included are #' : this is like the quote mark ' but is for FUNCTION instead of QUOTE. #/ : this returns the numeric form of the following character read without raising it. For example #/a is 97 while #/A is 65. #\ : This is a read macro for the CHAR macro, described in the PSL manual. Not that the argument is raised, if *RAISE is non-nil. For Char Char example, #\a = #\A = 65, while #\!a = #\(lower a) = 97. Char has been redefined in USEFUL to be slightly more table driven -- users can now add new "prefixes" such as META or CONTROL: just hang the appropriate function (from integers to integers) off the char-prefix-function property of the "prefix". A LARGE number of additional alias for various characters have been added, including all the "standard" ASCII names like NAK and DC1. #. : this causes the following expression to be evaluated at read time. For example, `(1 2 #.(plus 1 2) 4) reads as (1 2 3 4) #+ : this reads two expressions, and passes them to the if_system macro. That is, the first should be a system name, and if that is the current system the second argument is returned by the reader. If not, the next expression is returned. #-: #- is similar, but causes the second arg to be returned only if it is NOT the current system. Utilities 7 February 1983 PSL Manual page 17.14 section 17.4 17.4.4. MacroExpand 17.4.4. MacroExpand 17.4.4. MacroExpand MacroExpand MacroExpand _ ____ _ __ ____ _____ (MacroExpand A:form [B:id]): form macro _____ _____ _____ MacroExpand macro MacroExpand macro MacroExpand is a useful tool for debugging macro definitions. If MacroExpand macro MacroExpand macro given one argument, MacroExpand expands all the macros in that form. Often one wishes for more control over this process. For _____ _____ _____ macro Let macro Let example, if a macro expands into a Let, we may not wish to see Let Let the Let itself expanded to a lambda expression. Therefore MacroExpand MacroExpand additional arguments may be given to MacroExpand. If these are _____ _____ _____ macro macro supplied, they should be macros, and only those specified are expanded. 17.4.5. DefLambda 17.4.5. DefLambda 17.4.5. DefLambda DefLambda DefLambda _____ (DefLambda ): macro Yet another little (two line) macro has been added to USEFUL: DefLambda DefLambda DefLambda. This defines a macro much like a substitution macro ______ ______ ______ smacro smacro (smacro) except that it is a lambda expression. Thus, modulo ____ ____ ____ expr expr redefinability, it has the same semantics as the equivalent expr. It is mostly intended as an easy way to open compile things. For example, we would not normally want to define a substitution macro for a constructor (NEW-FOO X) which maps into (CONS X X), in case X is expensive to compute or, far worse, has side effects. (DEFLAMBDA NEW-FOO (X) (CONS X X)) defines it as a macro which maps (NEW-FOO (SETQ BAR (BAZ))) to ((LAMBDA (X) (CONS X X)) (SETQ BAR (BAZ))). 17.5. Simulating a Stack 17.5. Simulating a Stack 17.5. Simulating a Stack The following macros are in the USEFUL package. They are convenient for ____ adding and deleting things from the head of a list. Push Push ___ ___ ___ ____ ___ _____ (Push ITM:any STK:list): any macro (PUSH ITEM STACK) is equivalent to (SETF STACK (CONS ITEM STACK)) PSL Manual 7 February 1983 Utilities section 17.5 page 17.15 Pop Pop ___ ____ ___ _____ (Pop STK:list): any macro (POP STACK) does (SETF STACK (CDR STACK)) _____ and returns the item popped off STACK. An additional argument Pop Pop may be supplied to Pop, in which case it is a variable which is SetQ SetQ SetQ'd to the popped value. 17.6. DefStruct 17.6. DefStruct 17.6. DefStruct (LOAD DEFSTRUCT) to use the functions described below, or FAST!-DEFSTRUCT to use those functions but with fast vector operations used. DefStruct is similar to the Spice (Common) LISP/LISP machine/MacLISP flavor of struct definitions, and is expected to be subsumed by the Mode package. It is 2 implemented in PSL as a function which builds access macros and fns for "typed" vectors, including constructor and alterant macros, a type predicate for the structure type, and individual selector/assignment fns for the elements. DefStruct understands a keyword-option oriented structure specification. DefStruct is now autoloading. First a few miscellaneous functions on types, before getting into the depths of defining DefStructs: DefstructP DefstructP ____ __ _____ _______ ____ (DefstructP NAME:id): extra-boolean expr This is a predicate that returns non-NIL (the Defstruct ____ definition) if NAME is a structured type which has been defined using Defstruct, or NIL if it is not. DefstructType DefstructType _ ______ __ ____ (DefstructType S:struct): id expr This returns the type name field of an instance of a structured _ type, or NIL if S cannot be a Defstruct type. _______________ 2 Defstruct was implemented by Russ Fish. Utilities 7 February 1983 PSL Manual page 17.16 section 17.6 SubTypeP SubTypeP _____ __ _____ __ _______ ____ (SubTypeP NAME1:id NAME2:id): boolean expr _____ This returns true if NAME1 is a structured type which has been _____ !:Included in the definition of structured type NAME2, possibly through intermediate structure definitions. (In other words, the _____ _____ selectors of NAME1 can be applied to NAME2.) Now the function which defines the beasties, in all its gory glory: Defstruct Defstruct ____ ___ _______ __ ____ ____ _____ __ ____ __ _____ (Defstruct NAME-AND-OPTIONS:{id,list} [SLOT-DESCS:{id,list}]): id fexpr Defines a record-structure data type. A general call to Defstruct Defstruct Defstruct looks like this: (in RLISP syntax) defstruct( struct-name( option-1, option-2, ... ), slot-description-1, slot-description-2, ... ); The name of the defined structure is returned. Slot-descriptions are: slot-name( default-init, slot-option-1, slot-option-2, ... ) __ Struct-name and slot-name are ids. If there are no options following a name in a spec, it can be a bare id with no option argument list. The default-init form is optional and may be omitted. The default-init form is evaluated EACH TIME a structure is to be constructed and the value is used as the initial value of the slot. Options are either a keyword id, or the keyword followed by its argument list. Options are described below. _____ _____ _____ macro macro A call to a constructor macro has the form: MakeThing( slot-name-1( value-expr-1 ), slot-name-2( value-expr-2 ), ... ); The slot-name:value lists override the default-init values which were part of the structure definition. Note that the slot-names look like unary functions of the value, so the parens can be left off. A call to MakeThing with no arguments of course takes all of the default values. The order of evaluation of the default-init forms and the list of assigned values is undefined, so code should not depend upon the ordering. ____________ ____ Implementors Note: Common/LispMachine Lisps define it this way, but Is this necessary? It wouldn't be too tough to make the order be the same as the struct defn, or the argument order in the constructor call. Maybe they PSL Manual 7 February 1983 Utilities section 17.6 page 17.17 think such things should not be advertised and thus constrained in the future. Or perhaps the theory is that constructs such as this can be compiled more efficiently if the ordering is flexible?? Also, should the overridden default-init forms be evaluated or not? I think not. _____ _____ _____ macro macro The alterant macro calls have a similar form: AlterThing( thing, slot-name-1 value-expr-1, slot-name-2 value-expr-2, ... ); The first argument evaluates to the struct to be altered. (The optional parens were left off here.) This is just a multiple-assignment form, which eventually goes through the slot depositors. Remember that the slot-names are used, not the depositor names. (See !:Prefix, below.) The altered structure instance is returned as the value of an Alterant macro. Implementators note: Common/LispMachine Lisp defines this such that all of the slots are altered in parallel AFTER the new value forms are evaluated, but still with the order of evaluation of the forms undefined. This seemed to lose more than it gained, but arguments for its worth will be entertained. 17.6.1. Options 17.6.1. Options 17.6.1. Options Structure options appear as an argument list to the struct-name. Many of the options themselves take argument lists, which are sometimes optional. Option ids all start with a colon (!:), on the theory that this distinguishes them from other things. By default, the names of the constructor, alterant and predicate macros are MakeName, AlterName and NameP. "Name" is the struct-name. The !:Constructor, !:Alterant, and !:Predicate options can be used to override the default names. Their argument is the name to use, and a name of NIL causes the respective macro not to be defined at all. The !:Creator option causes a different form of constructor to be defined, in addition to the regular "Make" constructor (which can be suppressed.) As in the !:Constructor option above, an argument supplies the name of the macro, but the default name in this case is CreateName. A call to a Creator macro has the form: CreateThing( slot-value-1, slot-value-2, ... ); ___ ____ __ _______ All of the slot-values of the structure must be present, in the order they appear in the structure definition. No checking is done, other than assuring that the number of values is the same as the number of slots. For ___ ___ ___________ obvious reasons, constructors of this form are not recommended for Utilities 7 February 1983 PSL Manual page 17.18 section 17.6 structures with many fields, or which may be expanded or modified. Slot selector macros may appear on either the left side or the right side of an assignment. They are by default named the same as the slot-names, but can be given a common prefix by the !:Prefix option. If !:Prefix does not have an argument, the structure name is the prefix. If there is an argument, it should be a string or an id whose print name is the prefix. The !:Include option allows building a new structure definition as an extension of an old one. The required argument is the name of a previously defined structure type. The access functions for the slots of the source type also works on instances of the new type. This can be used to build hierarchies of types. The source types contain generic information in common to the more specific subtypes which !:Include them. The !:IncludeInit option takes an argument list of "slot-name(default- init)" pairs, like slot-descriptors without slot-options, and files them away to modify the default-init values for fields inherited as part of the !:Included structure type. 17.6.2. Slot Options 17.6.2. Slot Options 17.6.2. Slot Options Slot-options include the !:Type option, which has an argument declaring the type of the slot as a type id or list of permissible type ids. This is not enforced now, but anticipates the Mode system structures. The !:UserGet and !:UserPut slot-options allow overriding the simple vector reference and assignment semantics of the generated selector macros with user-defined functions. The !:UserGet FNAME is a combination of the slot-name and a !:Prefix if applicable. The !:UserPut FNAME is the same, with "Put" prefixed. One application of this capability is building depositors which handle the incremental maintenance of parallel data structures as a side effect, such as automatically maintaining display file representations of objects which are resident in a remote display processor in parallel with modifications to the LISP structures which describe the objects. The Make and Create macros bypass the depositors, while Alter uses them. 17.6.3. A Simple Example 17.6.3. A Simple Example 17.6.3. A Simple Example (Input lines have a "> " prompt at the beginning.) PSL Manual 7 February 1983 Utilities section 17.6 page 17.19 > % (Do definitions twice to see what functions were defined.) > macro procedure TWICE u; list( 'PROGN, second u, second u ); TWICE > % A definition of Complex, structure with Real and Imaginary parts > % Redefine to see what functions were defined. Give 0 Init values > TWICE > Defstruct( Complex( !:Creator(Complex) ), R(0), I(0) ); *** Function `MAKECOMPLEX' has been redefined *** Function `ALTERCOMPLEX' has been redefined *** Function `COMPLEXP' has been redefined *** Function `COMPLEX' has been redefined *** Function `R' has been redefined *** Function `PUTR' has been redefined *** Function `I' has been redefined *** Function `PUTI' has been redefined *** Defstruct `COMPLEX' has been redefined COMPLEX > C0 := MakeComplex(); % Constructor with default inits. [COMPLEX 0 0] > ComplexP C0;% Predicate. T > C1:=MakeComplex( R 1, I 2 ); % Constructor with named values. [COMPLEX 1 2] > R(C1); I(C1);% Named selectors. 1 2 > C2:=Complex(3,4) % Creator with positional values. [COMPLEX 3 4] > AlterComplex( C1, R(2), I(3) ); % Alterant with named values. [COMPLEX 2 3] > C1; [COMPLEX 2 3] > R(C1):=5; I(C1):=6; % Named depositors. 5 6 > C1; [COMPLEX 5 6] > % Show use of Include Option. (Again, redef to show fns defined.) > TWICE Utilities 7 February 1983 PSL Manual page 17.20 section 17.6 > Defstruct( MoreComplex( !:Include(Complex) ), Z(99) ); *** Function `MAKEMORECOMPLEX' has been redefined *** Function `ALTERMORECOMPLEX' has been redefined *** Function `MORECOMPLEXP' has been redefined *** Function `Z' has been redefined *** Function `PUTZ' has been redefined *** Defstruct `MORECOMPLEX' has been redefined MORECOMPLEX > M0 := MakeMoreComplex(); [MORECOMPLEX 0 0 99] > M1 := MakeMoreComplex( R 1, I 2, Z 3 ); [MORECOMPLEX 1 2 3] > R C1; 5 > R M1; 1 > % A more complicated example: The structures which are used in the > % Defstruct facility to represent defstructs. (The EX prefix has > % been added to the names to protect the innocent...) > TWICE% Redef to show fns generated. > Defstruct( > EXDefstructDescriptor( !:Prefix(EXDsDesc), !:Creator ), >DsSize(!:Type int ), % (Upper Bound of vector.) >Prefix(!:Type string ), >SlotAlist( !:Type alist ), % (Cdrs are SlotDescriptors.) >ConsName( !:Type fnId ), >AltrName( !:Type fnId ), >PredName( !:Type fnId ), >CreateName( !:Type fnId ), >Include( !:Type typeid ), >InclInit( !:Type alist ) > ); *** Function `MAKEEXDEFSTRUCTDESCRIPTOR' has been redefined *** Function `ALTEREXDEFSTRUCTDESCRIPTOR' has been redefined *** Function `EXDEFSTRUCTDESCRIPTORP' has been redefined *** Function `CREATEEXDEFSTRUCTDESCRIPTOR' has been redefined *** Function `EXDSDESCDSSIZE' has been redefined *** Function `PUTEXDSDESCDSSIZE' has been redefined *** Function `EXDSDESCPREFIX' has been redefined *** Function `PUTEXDSDESCPREFIX' has been redefined *** Function `EXDSDESCSLOTALIST' has been redefined *** Function `PUTEXDSDESCSLOTALIST' has been redefined *** Function `EXDSDESCCONSNAME' has been redefined *** Function `PUTEXDSDESCCONSNAME' has been redefined *** Function `EXDSDESCALTRNAME' has been redefined *** Function `PUTEXDSDESCALTRNAME' has been redefined PSL Manual 7 February 1983 Utilities section 17.6 page 17.21 *** Function `EXDSDESCPREDNAME' has been redefined *** Function `PUTEXDSDESCPREDNAME' has been redefined *** Function `EXDSDESCCREATENAME' has been redefined *** Function `PUTEXDSDESCCREATENAME' has been redefined *** Function `EXDSDESCINCLUDE' has been redefined *** Function `PUTEXDSDESCINCLUDE' has been redefined *** Function `EXDSDESCINCLINIT' has been redefined *** Function `PUTEXDSDESCINCLINIT' has been redefined *** Defstruct `EXDEFSTRUCTDESCRIPTOR' has been redefined EXDEFSTRUCTDESCRIPTOR > TWICE% Redef to show fns generated. > Defstruct( > EXSlotDescriptor( !:Prefix(EXSlotDesc), !:Creator ), >SlotNum( !:Type int ), >InitForm( !:Type form ), >SlotFn(!:Type fnId ), % Selector/Depositor id. >SlotType( !:Type type ), % Hm... >UserGet( !:Type boolean ), >UserPut( !:Type boolean ) > ); *** Function `MAKEEXSLOTDESCRIPTOR' has been redefined *** Function `ALTEREXSLOTDESCRIPTOR' has been redefined *** Function `EXSLOTDESCRIPTORP' has been redefined *** Function `CREATEEXSLOTDESCRIPTOR' has been redefined *** Function `EXSLOTDESCSLOTNUM' has been redefined *** Function `PUTEXSLOTDESCSLOTNUM' has been redefined *** Function `EXSLOTDESCINITFORM' has been redefined *** Function `PUTEXSLOTDESCINITFORM' has been redefined *** Function `EXSLOTDESCSLOTFN' has been redefined *** Function `PUTEXSLOTDESCSLOTFN' has been redefined *** Function `EXSLOTDESCSLOTTYPE' has been redefined *** Function `PUTEXSLOTDESCSLOTTYPE' has been redefined *** Function `EXSLOTDESCUSERGET' has been redefined *** Function `PUTEXSLOTDESCUSERGET' has been redefined *** Function `EXSLOTDESCUSERPUT' has been redefined *** Function `PUTEXSLOTDESCUSERPUT' has been redefined *** Defstruct `EXSLOTDESCRIPTOR' has been redefined EXSLOTDESCRIPTOR > END; NIL Utilities 7 February 1983 PSL Manual page 17.22 section 17.7 17.7. DefConst 17.7. DefConst 17.7. DefConst DefConst DefConst _ __ _ ______ _________ _____ (DefConst [U:id V:number]): Undefined macro DefConst DefConst DefConst is a simple means for defining and using symbolic constants, as an alternative to the heavy-handed NEWNAM or DEFINE facility in REDUCE/RLISP. Constants are defined thus: DefConst(FooSize, 3); or as sequential pairs: DEFCONST(FOOSIZE, 3, BARSIZE, 4); Const Const _ __ ______ _____ (Const U:id): number macro Const Const They are referred to by the macro Const, so CONST(FOOSIZE) would be replaced by 3. 17.8. Functions for Sorting 17.8. Functions for Sorting 17.8. Functions for Sorting The Gsort module provides functions for sorting lists and vectors. Some __________ ________ of the functions take a comparison function as an argument. The comparison function takes two arguments and returns NIL if they are out of order, i.e. if the second argument should come before the first in the sorted result. Lambda expressions are acceptable as comparison functions. Gsort Gsort _____ ____ ______ ___ __ __ ________ ____ ______ ____ (Gsort TABLE:{list,vector} leq-fn:{id,function}): {list,vector} expr ____ ______ ___ __ Returns a sorted list or vector. LEQ-FN is the comparison _____ function used to determine the sorting order. The original TABLE Gsort Gsort is unchanged. Gsort uses a stable sorting algorithm. In other _ _ _ words, if X appears before Y in the original table then X will _ _ _ appear before Y in the final table unless X and Y are out of _ _ order. (An unstable sort, on the other hand, might swap X and Y _ _ even if they're in order. This could happen when X and Y have the same "key field", so either one could come first without making a difference to the comparison function.) GmergeSort GmergeSort _____ ____ ______ ___ __ __ ________ ____ ______ ____ (GmergeSort TABLE:{list,vector} leq-fn:{id,function}): {list,vector} expr Gsort Gsort _____ The same as Gsort, but destructively modifies the TABLE argument. GmergeSort Gsort GmergeSort Gsort GmergeSort has the advantage of being somewhat faster than Gsort. Note that you should use the value returned by the function-- PSL Manual 7 February 1983 Utilities section 17.8 page 17.23 don't depend on the modified argument to give the right answer. IdSort IdSort _____ ____ ______ ____ ______ ____ (IdSort TABLE:{list,vector}): {list,vector} expr __ Returns a table of ids sorted into alphabetical order. The original table is unchanged. Case is not significant in determining the alphabetical order. The table may contain ______ __ strings as well as ids. The following example illustrates the use of Gsort. 1 lisp> (load gsort) NIL 2 lisp> (setq X '(3 8 -7 2 1 5)) (3 8 -7 2 1 5) 3 lisp> % Sort from smallest to largest. 3 lisp> (Gsort X 'leq) (-7 1 2 3 5 8) 4 lisp> % Sort from largest to smallest. 4 lisp> (GmergeSort X 'geq) (8 5 3 2 1 -7) 5 lisp> % Note that X was "destroyed" by GmergeSort. 5 lisp> X (3 2 1 -7) 6 lisp> 6 lisp> % Here's IdSort, taking a vector as its argument. 6 lisp> (IdSort '[the quick brown fox jumped over the lazy dog]) [BROWN DOG FOX JUMPED LAZY OVER QUICK THE THE] 7 lisp> 7 lisp> % Some examples of user defined comparison functions... 7 lisp> (setq X '(("Joe" . 20000) ("Moe" . 21000) ("Larry" . 7000))) (("Joe" . 20000) ("Moe" . 21000) ("Larry" . 7000)) 8 lisp> 8 lisp> % First, sort the list alphabetically according to name, 8 lisp> % using a lambda expression as the comparison function. 8 lisp> (Gsort X 8 lisp> '(lambda (X Y) (string-not-greaterp (car X) (car Y)))) (("Joe" . 20000) ("Larry" . 7000) ("Moe" . 21000)) 9 lisp> 9 lisp> % Now, define a comparison function that compares cdrs of 9 lisp> % pairs, and returns T if the first is less than or equal 9 lisp> % to the second. 9 lisp> (de cdr_leq (pair1 pair2) 9 lisp> (leq (cdr pair1) (cdr pair2))) CDR_LEQ 10 lisp> 10 lisp> % Use the cdr_leq function to sort X. 10 lisp> (Gsort X 'cdr_leq) (("Larry" . 7000) ("Joe" . 20000) ("Moe" . 21000)) Utilities 7 February 1983 PSL Manual page 17.24 section 17.9 17.9. Hashing Cons 17.9. Hashing Cons 17.9. Hashing Cons HCons HCons HCONS is a loadable module. The HCons function creates unique dotted HCons Eq HCons Eq HCons _ _ Eq HCons _ _ _ Eq _ pairs. In other words, HCons(A, B) Eq HCons(C, D) if and only if A Eq C Eq _ Eq _ and B Eq D. This allows rapid tests for equality between structures, at the cost of expending more time in creating the structures. The use of HCons HCons HCons may also save space in cases where lists share common substructure, since only one copy of the substructure is stored. Hcons Hcons ____ ____ _____ Hcons works by keeping a pair hash table of all pairs that have been HCons HCons created by HCons. (So the space advantage of sharing substructure may be offset by the space consumed by table entries.) This hash table also allows the system to store property lists for pairs--in the same way that LISP has property lists for identifiers. HCons RplacA RplacD HCons ______ ___ RplacA RplacD Pairs created by HCons should not be modified with RplacA and RplacD. Doing so will make the pair hash table inconsistent, as well as being very likely to modify structure shared with something that you don't wish to change. Also note that large numbers may be equal without being eq, so the HCons Eq HCons HCons Eq HCons HCons of two large numbers may not be Eq to the HCons of two other numbers that appear to be the same. (Similar warnings hold for strings and vectors.) The following "user" functions are provided by HCONS: HCons HCons _ ___ ____ _____ (HCons [U:any]): pair macro HCons HCons The HCons macro takes one or more arguments and returns their "hashed cons" (right associatively). With two arguments this Cons Cons corresponds to a call of Cons. HList HList _ ___ ____ _____ (HList [U:any]): list nexpr HList List HList List HList is the "HCONS version" of the List function. HCopy HCopy _ ___ ___ _____ (HCopy U:any): any macro HCopy Copy HCopy HCopy Copy HCopy HCopy is the HCONS version of the Copy function. Note that HCopy Copy Copy serves a very different purpose than Copy, which is usually used to copy a structure so that destructive changes can be made to HCopy HCopy the copy without changing the original. HCopy only copies those Cons Cons parts of the structure which haven't already been "Consed HCons HCons together" by HCons. HAppend HAppend _ ____ _ ____ ____ ____ (HAppend U:list V:list): list expr HCons Append HCons Append The HCons version of Append. PSL Manual 7 February 1983 Utilities section 17.9 page 17.25 HReverse HReverse _ ____ ____ ____ (HReverse U:list): list expr HCons Reverse HCons Reverse The HCons version of Reverse. Get Put Get Put The following two functions can be used to "Get" and "Put" properties for pairs or identifiers. The pairs for these functions must be created by HCons SetF HCons SetF HCons. These functions are known to the SetF macro. Extended-Put Extended-Put _ __ ____ ___ __ ____ ___ ___ ____ (Extended-Put U:{id,pair} IND:id PROP:any): any expr Extended-Get Extended-Get _ __ ____ ___ ___ ___ ____ (Extended-Get U:{id,pair} IND:any): any expr 17.10. Graph-to-Tree 17.10. Graph-to-Tree 17.10. Graph-to-Tree GRAPH-TO-TREE is a loadable module. For resident functions printing circular lists see Section 15.8. Graph-to-Tree Graph-to-Tree _ ____ ____ ____ (Graph-to-Tree A:form): form expr Graph-to-Tree Graph-to-Tree The function Graph-to-Tree copies an arbitrary s-expression, removing circularity. It does NOT show non-circular shared Eq Eq structure. Places where a substructure is Eq to one of its ancestors are replaced by non-interned ids of the form <n> where n is a small integer. The parent is replaced by a two element list of the form (<n>: u) where the n's match, and u is the (de-circularized) structure. This is most useful in adapting any printer for use with circular structures. CPrint CPrint _ ___ ___ ____ (CPrint A:any): NIL expr CPrint CPrint The function CPrint, also defined in the module GRAPH-TO-TREE, is PrettyPrint Graph-to-Tree PrettyPrint Graph-to-Tree simply (PrettyPrint (Graph-to-Tree X)). Note that GRAPH-TO-TREE is very embryonic. It is MUCH more inefficient than it needs to be, heavily consing. A better implementation would use a stack (vector) instead of lists to hold intermediate expressions for comparison, and would not copy non-circular structure. In addition facilities should be added for optionally showing shared structure, for performing the inverse operation, and for also editing long or deep structures. Finally, the output representation was chosen at random and can probably be improved, or at least brought in line with CL or some other standard. Utilities 7 February 1983 PSL Manual page 17.26 section 17.11 17.11. Inspect Utility 17.11. Inspect Utility 17.11. Inspect Utility INSPECT is a loadable module. Inspect Inspect ________ ______ ____ (Inspect FILENAME:string): expr This is a simple utility which scans the contents of a source file to tell what functions are defined in it. It will be embellished slightly to permit the on-line querying of certain Inspect Inspect attributes of files. Inspect reads one or more files, printing and collecting information on defined functions. Usage: (LOAD INSPECT) (INSPECT "file-name") % Scans the file, and prints proc % names. It also % builds the lists ProcedureList!* % FileList!* and ProcFileList!* % File-Name can DSKIN other files On the Fly printing is controlled by !*PrintInspect, default is T. Other lists built include FileList!* and ProcFileList!*, which is a list of (procedure . filename) for multi-file processing. For more complete process, do: (LOAD INSPECT) (OFF PRINTINSPECT) (INSPECTOUT) (DSKIN ...) (DSKIN ...) (INSPECTEND)