home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume12 / ops5 / part01 next >
Encoding:
Internet Message Format  |  1987-10-12  |  11.5 KB

  1. Subject:  v12i016:  OPS5 in Common Lisp, Part01/05
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: eric@dlcdev.UUCP (eric van tassell)
  7. Posting-number: Volume 12, Issue 16
  8. Archive-name: ops5/part01
  9.  
  10. [  I have not done anything with this code.  --r$  ]
  11.  
  12. [  Alert readers will note the conflict copyright/p-d claims in the
  13.    first paragraph.  This source has been on CompuServe, apparently
  14.    with the author's permission.  That, coupled with the note asking
  15.    users to join a mailing list leads me to believe that this is PD
  16.    code.  I can't imagine what the foriegn restrictions might be,
  17.    since nothing in here is covered by export regulations.  --r$  ]
  18.  
  19. OPS5 is has been made public domain by C. Lanny Forgy. There are, I
  20. believe, some restrictions on transporting OPS5 to some foreign
  21. countries (which countries is pretty obvious).  The code is copyrighted
  22. by Forgy, and anyone considering using it for commercial purposes
  23. should probably contact him at CMU first.
  24.  
  25. The Vax Common Lisp and TI Explorer versions were ported by Dan Neiman
  26. of the University of Massachusetts, COINS Dept.  They are *not*
  27. guaranteed to be 100% bug free, particularly in the I/O functions, but
  28. any bugs found should be mostly syntactic in nature.  The TI Explorer
  29. takes advantage of some non-standard features not normally in Common
  30. Lisp (such as the "e keyword) and is somewhat cleaner; the Vax Lisp
  31. version is more generic and will run on more systems.  The Common Lisp
  32. versions are far from optimized, the major emphasis was on getting them
  33. working and there are many idioms which could be expressed more
  34. compactly and efficiently.
  35.  
  36. Modifications to OPS itself.  The ported versions of OPS are faithful
  37. to the manual with the following exceptions, Common Lisp already
  38. possesses functions remove, write, and call; the OPS5 functions have
  39. been renamed oremove, owrite, and ocall respectively.  The OPS5
  40. compilation functions have been modified to perform this renaming
  41. automagically for RHS functions.  The user will have to remember to use
  42. oremove when removing working memory from the top level.
  43.  
  44. Test programs:  There are not a lot of OPS5 benchmark programs
  45. available.  The monkey and bananas program was included in the original
  46. distribution.  The sort and Towers of Hanoi problems demonstrate OPS5,
  47. but are not particularly good exemplars of the tasks that you want to
  48. solve using a production system.
  49.  
  50.  
  51. Questions about these versions of OPS5 can be directed to Dan Neiman,
  52. at electronic mail addresses CSNET: dann@cs.umass.edu,
  53. dann@umass-cs.csnet
  54.           CompuServe: 72277,2604
  55.           Real Mail: COINS Dept.
  56.                      Lederle Graduate Research Center
  57.                      UMass
  58.                      Amherst, MA 01003  
  59.  
  60. --------------------
  61. Appearing below is output from the diff utility (UNIX 4.3 bsd, if it
  62. matters) indicating the changes needed to make the "Common Lisp" OPS5
  63. source posted to this forum compatible with Gold Hill "GC 286 Developer."
  64. Explanatory material is interspersed, denoted by ***. This file also
  65. includes comments on GC 286 versus ExperLisp and ExperCommon Lisp on
  66. the Macintosh.
  67.  
  68. With these changes, OPS5 compiles without errors, though I haven't 
  69. verified all of its behaviors yet: the math operators seem to be
  70. a little squirrely. The monkeys-and-bananas benchmark LOADS without
  71. error and RUNs in a little over 5 seconds (COMPAQ DeskPro 286, 3 MB
  72. extended memory, 8 MHz clock/6 MHz bus); this is on the order of
  73. three times the time reported by Production Systems for a Symbolics
  74. machine in their OPS83 advertising. Highly cost-effective!
  75.  
  76. This is the first thing we've tackled with GC 286 -- the COMPAQ was just
  77. delivered a week ago, and we discovered and downloaded the OPS5 source
  78. over that weekend. We're surely looking forward to refining it with some
  79. of the Rete tools discussed in the January AIE. GC 286 is a wonder:
  80. my co-workers, who think a Symbolics is a personal computer, were visibly
  81. impressed by the excellent integration of the GMACS editor into the
  82. GC 286 environment, and by the ability to jump from Lisp into DOS -- for
  83. example, to run a terminal emulator and bring Lisp files down from the
  84. VAX (which is Ethernetted to the Symbolics machines). They're already
  85. starting to ship me Symbolics code with requests to investigate its
  86. portability to GC 286 for delivery.
  87.  
  88. A final holiday note: I called my contact at Gold Hill to pass on some of
  89. these impressions, the day before Christmas at 4:45 Boston time. "He's on
  90. vacation," I was told, "but maybe I can help you." "Who's this?," I asked
  91. innocently. Turned out to be Eugene Wang, president of the company... we
  92. had a most enjoyable discussion of micro Lisps and the ANSI Lisp effort.
  93. Some people are just a pleasure to do business with.
  94.  
  95. As a long-time user and generally a fan of ExperLisp (and now ExperCommon
  96. Lisp), I can't help but regret some of the differences between Exper and
  97. GC. Neither is uniformly better. Exper has the wonderful Mac editing 
  98. interface, but GMACS is a more workmanlike environment with a lot more
  99. power in searches, moves by expression, etc. ExperCommon can only edit
  100. files up to 32K, requiring aggravating segmentation of the 100+K OPS5
  101. source, while GMACS works quite happily with the whole thing at once.
  102. ExperCommon chokes on the OPS5 definitions of { and }, since it uses
  103. those as multi-line comment delimiters, and on OPS5 functions whose names
  104. begin with $ since it defines that as a macro character for "hex value to
  105. follow."
  106.  
  107. GC 286 runs elementary benchmarks like FIBONACCI about 30% slower in
  108. its interpreter than ExperLisp 1.5 requires in its incremental compiler;
  109. GC is faster than Exper 1.5 by a factor of 10 when compiled (the times
  110. for Exper are on a 1 MB Mac with ExperLisp configured for 24,000 cons
  111. cells and 4800 symbols; GC times are on the configuration given above).
  112.  
  113. On the other hand, the complete Mac toolbox integration of ExperCommon
  114. is going to make for some really sensational applications. Imagine an
  115. implementation of OPEN that makes the filename &optional, and if null
  116. goes into the standard file dialogue for mouse-menu selection of any
  117. file (with appropriate restrictions on type) in the entire hierarchical
  118. file system. Nice...
  119.  
  120. If this sounds as if I'm not sure which I prefer, that's pretty accurate.
  121. Muscle memory for GMACS keychords is developing quickly, and it's easy to
  122. get spoiled by on-line documentation and all the other GC goodies. The
  123. Mac user interface is hard to beat, though, and Apple's future CPU
  124. upgrade path looks fairly smooth (compared to the chaos of 286 vs. 386
  125. and IBM vs. Microsoft operating system intentions). I was at the meeting
  126. of the Personal Computer Professionals Association that is reported in
  127. PC Week's December 23rd issue, and the two front-page articles on the
  128. meeting accurately capture the uproar. 1987 will be a tough year for
  129. standards.
  130.  
  131. Herewith the diff results:
  132.  
  133. *** The == function is intended for small-integer comparisons. GC 286
  134. *** appears to generate "eq" integers +/- 32767.
  135.  
  136. 78c78,80
  137. < (defun == (x y) (= x y))
  138. ---
  139. > ;(defun == (x y) (= x y))
  140. >
  141. > (defun == (x y) (eq x y))
  142.  
  143. *** CHARACTER is valid CL but not implemented as a GC primitive.
  144.  
  145. 194c196,198
  146. <
  147. ---
  148. >
  149. > (defun character (x) (coerce x 'character))
  150. >
  151.  
  152. *** The REMOVE-DUPLICATES function is commented out in the posted version,
  153. *** but is not implemented as a GC primitive so needs to be enabled.
  154.  
  155. *** CxxxxR functions such as CADDDR are valid CL but not GC primitives.
  156. *** Several changes are necessary to accommodate this, for example...
  157.  
  158. 944c949
  159. < (defun memory-part (mem-node) (car (cadddr mem-node)))
  160. ---
  161. > (defun memory-part (mem-node) (car (car (cdddr mem-node))))
  162.  
  163. 1044c1049
  164. <        (equal (cddddr a) (cddddr b))
  165. ---
  166. >        (equal (cdr (cdddr a)) (cdr (cdddr b)))
  167.  
  168. *** Here is an old-form DO that totally confuses CL. The GC compiler told
  169. *** me that it was assuming "K" and "-" to be special variables...!
  170.  
  171. 2225,2226c2228,2230
  172. <         (do k (- width size) (1- k) (not (> k 0)) (princ '| | port))
  173. <         (princ value port)))
  174. ---
  175. >         (do ((k (- width size) (1- k)))
  176. >           ((not (> k 0)) (princ '| | port)))
  177. >     (princ value port)))
  178.  
  179. *** I'm not sure what the "correct" behavior is, but the following change
  180. *** makes GC 286 print ^, as desired, instead of its ASCII value:
  181.  
  182. 2596c2601
  183. <          (princ '^ port)
  184. ---
  185. >          (princ '|^| port)
  186.  
  187. *** More CxxxxR revisions...
  188.  
  189. 2904c2903
  190. < (defun find-right-mem (node) (memory-part (cadddr node)))
  191. ---
  192. > (defun find-right-mem (node) (memory-part (car (cdddr node))))
  193.  
  194. 3099c3093
  195. <   (check-last-substr-index (cadddr x)))
  196. ---
  197. >   (check-last-substr-index (car (cdddr x))))
  198.  
  199. *** The remaining changes are implementations and re-bindings that
  200. *** should be self-explanatory, except for the "MATH" file load: this
  201. *** is needed because GC does not AUTOLOAD library functions called
  202. *** from compiled code, generating an error message that is highly
  203. *** cryptic but *is* explained in a READ.ME file distributed with the
  204. *** compiler.
  205.  
  206. > ;;; Calls and function definitions added for GC286
  207. >
  208. > (load (string-append SYS::*LISP-LIBRARY-PATHNAME* "MATH"))
  209. >
  210. > ;;; INTERSECTION as defined here works when interpreted, but not when
  211. > ;;; compiled. For now, put it in USERINIT and comment it out of this
  212. > ;;; source.
  213. >
  214. > ; (defun intersection (s1 s2 &rest keys&values)
  215. > ;   (let ((:test (or (cadr (member ':test keys&values)) #'eql))
  216. > ;     (:test-not (cadr (member ':test-not keys&values)))
  217. > ;     (:key  (or (cadr (member ':key  keys&values)) #'identity))
  218. > ;     (result nil))
  219. > ;    (do ((patterns s1 (cdr patterns)))
  220. > ;     ((null patterns) (nreverse result))
  221. > ;     (let ((pattern (funcall :key (car patterns))))
  222. > ;     (do ((data s2 (cdr data)))
  223. > ;         ((null data))
  224. > ;       (let ((datum (funcall :key (car data))))
  225. > ;         (if (or (funcall :test pattern datum)
  226. > ;                 (and :test-not (not (funcall :test-not pattern datum))))
  227. > ;             (pushnew datum result ':test :test))))))))
  228. >
  229.  
  230. *** The use of (SETF (SYMBOL-FUNCTION...) ...) instead of DEFUN generates a
  231. *** compiler warning that (for example) GREATERP is referenced but not defined.
  232. *** Of course, it works anyway.
  233.  
  234. > (setf (symbol-function 'greaterp) #'>)
  235. >
  236.  
  237. *** PRINC-TO-STRING is valid CL but not a GC primitive.
  238.  
  239. > (defun princ-to-string (x)
  240. >   (let ((outstream (make-string-output-stream)))
  241. >     (princ x outstream)
  242. >     (get-output-stream-string outstream)))
  243. >
  244.  
  245. *** TYIPEEK is *not* CL, but I think the following does what's intended:
  246.  
  247. > (defun tyipeek (&optional input-stream &aux inchar)
  248. >   (prog1
  249. >     (setq inchar (read-char input-stream))
  250. >     (unread-char inchar input-stream)))
  251. >
  252. > (setf (symbol-function 'difference) #'-
  253. >       (symbol-function 'times     ) #'*)
  254. >
  255.  
  256. *** EQUALP is valid CL, though not GC, and I think this is a correct
  257. *** implementation:
  258.  
  259. > (defun equalp (x y)
  260. >   (or (equal x y)
  261. >       (and (numberp x) (numberp y) (= x y))
  262. >       (and (characterp x) (characterp y) (char-equal x y))
  263. >       (and (consp x) (consp y) (equalp (car x) (car y))
  264. >                              (equalp (cdr x) (cdr y)))))
  265. >
  266.  
  267. --------------------
  268. ;Common Lisp Support Functions: 
  269. ;These functions are not defined in vanilla Common Lisp, but are used
  270. ;in the OPSMODS.l code and in OPS5.
  271.  
  272.  
  273. (defun putprop(name val att)
  274.    (setf (get name att) val))
  275.  
  276. (defun memq(obj lis)
  277.     (member obj lis :test #'eq))
  278.  
  279. (defun fix(num)
  280.     (round num))
  281.     
  282.  
  283. (defun assq(item alist)
  284.      (assoc item alist :test #'eq))
  285.  
  286. (defun ncons(x) (cons x nil))
  287.  
  288. (defun neq(x y) (not (eq x y)))
  289.  
  290. (defun delq(obj list)
  291.    (delete obj list :test #'eq))
  292.  
  293. (defmacro comment(&optional &rest x) nil) ;comment is a noop
  294.  
  295. (defun plus(x y)
  296.    (+ x y))
  297.  
  298. (defun quotient(x y)
  299.    (/ x y))
  300.  
  301. (defun flatc(x)
  302.    (length (princ-to-string x)))
  303.