turner@imagen.UUCP (02/24/87)
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # actor.mar # contnt.mar # expert.mar # files.mar # logo.mar # This archive created: Mon Feb 23 15:33:29 1987 # By: D'arc Angel (The Houses of the Holy) export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'actor.mar'" '(3017 characters)' if test -f 'actor.mar' then echo shar: "will not over-write existing file 'actor.mar'" else cat << \SHAR_EOF > 'actor.mar' "Actor Goes on Stage" by Andrew P. Bernat March 1987 AI EXPERT Listing 1. A Comparison of ACTOR and Smalltalk-80 /* ACTOR solution to Towers of Hanoi */ /* Create a new class named TowerOfHanoi to handle the problem. The new class is directly beneath Object in the hierarchy; Object being at the top of the class hierarchy.*/ inherit(Object, #TowerOfHanoi, nil, nil, nil); /* Here we set the compiler's curClass instance variable, which specifies which class the following messages are to apply to. */ Compiler.curClass := TowerOfHanoi; /* Define a new message named moveTower */ Def moveTower(self, height, from, to, use) { if height > 0 then moveTower(self, height - 1, from, use, to); moveDisk(self, from, to); moveTower(self, height - 1, use, to, from); endif; } /* Define a new message named moveDisk */ Def moveDisk(self, from, to) { eol(ThePort); print(from); print("->"); print(to); } /* Add a new member of class Object to the system dictionary, which is also named Actor, at key location sample */ Actor[#sample] := new(Object); /* Send message moveTower to the object sample. sample, being of class Object, will respond using the code defined above. The parameters say to use three disks, and move them from tower 1 to tower 3 using tower 2 */ moveTower(sample, 3, 1, 3, 2); " Tower of Hanoi code as implemented in Smalltalk/V. Note that these messages and methods would be implemented directly through the System Browser. " " Declare a new sublcass of Object." Object subclass: #TowerOfHanoi " Instance variables would be declared here, but none are needed. " TowerOfHanoi methods " Declare the moveTower message. " moveTower: height from: ftower to: ttower using: utower (> height 0) ifTrue: [self moveTower: height - 1 from: ftower to: utower using: ttower. self moveDisk: ftower to: ttower. self moveTower: height - 1 from: utower to: ttower using: ftower] " Declare the moveDisk message. Transcript is a the standard output window." moveDisk: ftower to: ttower Transcript cr. Transcript show: ftower. Transcript show: '->'. Transcript show: ttower. " To execute, evaluate (new TowerOfHanoi) moveTower: 3 from: 1 to: 3 using: 2" SHAR_EOF if test 3017 -ne "`wc -c < 'actor.mar'`" then echo shar: "error transmitting 'actor.mar'" '(should have been 3017 characters)' fi fi echo shar: "extracting 'contnt.mar'" '(2489 characters)' if test -f 'contnt.mar' then echo shar: "will not over-write existing file 'contnt.mar'" else cat << \SHAR_EOF > 'contnt.mar' Table of Contents AI EXPERT Magazine March 1987 Theme: Intelligent Data Bases ARTICLES Object-oriented Data Base Design by Bob Peterson The object-oriented data model is the natural result of the union of two technologies: object-oriented programming and database management. This article discusses the idea of object-oriented databases, contrasting this new development with classical approaches to data management. Intelligent Data Bases and Nial by M. A. Jenkins Here we describe an architecture for an intelligent decision support system designed within a single language framework called the Nested Interactive Array Language (NIAL) -- which combines ideas from LISP, APL, Pascal, and logic programming into one coherent system. On Stage with Actor by Andrew P. Bernat ACTOR is a new programming language intended to make the flexibility and power of the object-oriented programming style even more available to microcomputer users. Comparing Actor to Digitalk's Smalltalk/V, we will look at how well Actor meets the the goal of bringing the power of object-oriented programming down to the PC. Learn Logo Before LISP by Michael McMillan This author suggests a novel way to learn LISP that will give the student a solid backround in symbolic computation -- learn LOGO first! He claims that Logo has been the victim of its own success as an educational language, and contends that it can also be important to the 'grown-up world' of computer science and artificial intelligence. DEPARTMENTS Brain Waves Larry Harris, C.E.O., Artificial Intelligence Corp. "The Marriage of AI and Data Base Technology" AI Insider by Susan Shepard Expert's Toolbox "Heuristic State Space Search" by Marc Rettig AI Apprentice "Breaking with Tradition: Nonlinear Reading" by Beverly and Bill Thompson In Practice "The Making of a Tax Expert" by Harvey Newquist Book Store "Machine Learning, Soar, and the Art of PROLOG" by Dr. Lance B. Eliot Software Reviews: LISP on the Micro, Part II: by Susan Shepard, et. al. Personal Consultant Plus by Susan Shepard SHAR_EOF if test 2489 -ne "`wc -c < 'contnt.mar'`" then echo shar: "error transmitting 'contnt.mar'" '(should have been 2489 characters)' fi fi echo shar: "extracting 'expert.mar'" '(7056 characters)' if test -f 'expert.mar' then echo shar: "will not over-write existing file 'expert.mar'" else cat << \SHAR_EOF > 'expert.mar' Expert's Toolbox -- March 1987 "Heuristic State Space Search" by Marc Rettig Listings 1 and 2 Listing 1 ; STATE-SPACE SEARCH PROCEDURE ; These functions provide a general control structure for ; solving problems using heuristic search. In order to apply ; this method to a particular problem, you must write the ; functions: initial-state, goal, successors, and print-solution. ; See the "Expert's Toolbox" column in the March AI-Expert ; for a description of this algorithm and an example of its use. ; ; Algorithm given by Dr. Ralph Grishman, New York University, ; after Nils Nilsson, "Principles of Artificial Intelligence". ; Adapted for Xlisp by Marc Rettig (76703,1037). (defun search () (prog (open closed n m successor-list same) ; Step 1. Put initial state on open. (setq open (list (initial-state))) ; Step 2. If open is empty, exit with failure. expand: (cond ((null open) (print 'failure) (return nil))) ; Step 3. Remove state from open with minimum g + h and ; call it n. (open is sorted by increasing g + h, so ; this is first element.) Put n on closed. ; Exit with success if n is a goal node. (setq n (car open)) (setq open (cdr open)) (setq closed (cons n closed)) (trace 'expanding n) (cond ((goal n) (print-solution n) (return t))) ; For each m in successors(m): (setq successor-list (successors n)) next-successor: (cond ((null successor-list) (go expand:))) (setq m (car successor-list)) (setq successor-list (cdr successor-list)) (trace 'successor m) (cond ((setq same (find m open)) ; if m is on open, reset g if new value is smaller (cond ((< (get m 'g) (get same 'g)) (setq open (add m (remove same open)))))) ((setq same (find m closed)) ; If m is on closed and new value of g is smaller, ; remove state from closed and add it to open with new g. (cond ((< (get m 'g) (get same 'g)) (setq closed (remove same closed)) (setq open (add m open))))) (t ; else add m to open (setq open (add m open)))) (go next-successor:))) (defun add (state s-list) ; Inserts state into s-list so that list remains ordered ; by increasing g + h. (cond ((null s-list) (list state)) ((> (+ (get (car s-list) 'g) (get (car s-list) 'h)) (+ (get state 'g) (get state 'h))) (cons state s-list)) (t (cons (car s-list) (add state (cdr s-list)))))) (defun find (state s-list) ; returns first entry on s-list whose position is same ; as that of state. (cond ((null s-list) nil) ((equal (get state 'position) (get (car s-list) 'position)) (car s-list)) (t (find state (cdr s-list))))) Listing 2 ; M I S S I O N A R I E S A N D C A N N I B A L S ; ; The following routines, when used in conjunction with the state-space ; search procedure, solve the missionaries and cannibals problem. Three ; missionaries and 3 cannibals are located on the right bank of a river, ; along with a two-man rowboat. We must find a way of moving all the ; missionaries and cannibals to the left bank. However, if at any time ; there are more cannibals than missionaries on a bank, the cannibals will ; exhibit a consuming interest in the misssionaries; this must be avoided. ; ; Each state is represented by an atom with the following properties: ; position -- a list of three elements, ; the number of missionaries on the right bank ; the number of cannibals on the right bank ; the position of the boat (left or right) ; g -- the estimated g for that state ; h -- the estimated h (value of function heuristic) ; parent -- the preceding state on the path from the initial state ; (the preceding state which gives rise to the least g, ; if there are several) (defun initial-state () ; return the initial state (build-state 3 3 'right 0 nil)) (defun successors (state) ; returns the successors of state ; note that procedure try uses state and new-g, and modifies suc (prog (m c boat new-g suc) ; extract parameters of current position and put in m, c, and boat (setq m (car (get state 'position))) (setq c (cadr (get state 'position))) (setq boat (caddr (get state 'position))) ; g of new state = g of old state + 1 (all crossings are unit cost) (setq new-g (+ 1 (get state 'g))) (cond ((equal boat 'right) (try (- m 2) c 'left new-g) (try (- m 1) c 'left new-g) (try (- m 1) (- c 1) 'left new-g) (try m (- c 1) 'left new-g) (try m (- c 2) 'left new-g)) (t ; boat is on left (try (+ m 2) c 'right) (try (+ m 1) c 'right) (try (+ m 1) (+ c 1) 'right) (try m (+ c 1) 'right) (try m (+ c 2) 'right))) (return suc))) (defun try (new-m new-c new-boat new-g) ; if position(new-m,new-c,new-boat) is valid, add new state to suc (cond ((valid new-m new-c) (setq suc (cons (build-state new-m new-c new-boat new-g state) suc))))) (defun valid (miss cann) ; returns true if having 'miss' missionaries and 'cann' cannibals ; on the right bank is a valid state (and (>= miss 0) (>= cann 0) (< miss 4) (< cann 4) (or (zerop miss) (>= miss cann)) (or (zerop (- 3 miss)) (>= (- 3 miss) (- 3 cann))))) (defun build-state (miss cann boat g parent) ; creates a new state with parameters as specified by argument list (prog (newstate) (setq newstate (gensym)) (putprop newstate (list miss cann boat) 'position) (putprop newstate g 'g) (putprop newstate (heuristic miss cann boat) 'h) (putprop newstate parent 'parent) (return newstate))) (defun heuristic (miss cann boat) ; our heuristic (h) function (cond ((equal boat 'left) (* 2 (+ miss cann))) (t ; boat is on right (* 2 (max 0 (+ miss cann -2)))))) (defun goal (state) ; returns true if state is a goal state (no missionaries or cannibals on right) (and (zerop (car (get state 'position))) (zerop (cadr (get state 'position))))) (defun print-solution (state) ; invoked by search algorithm with goal state, ; prints sequence of states from initial state to goal. (cond ((null state) (print 'solution:)) (t (print-solution (get state 'parent)) (print (get state 'position)) )) ) (defun trace (comment state) ; if trace-switch is true, print out comment and position ; associated with state (cond (trace-switch (print `(,comment state ,state with position ,(get state 'position) h(x) = ,(get state 'h)))))) SHAR_EOF if test 7056 -ne "`wc -c < 'expert.mar'`" then echo shar: "error transmitting 'expert.mar'" '(should have been 7056 characters)' fi fi echo shar: "extracting 'files.mar'" '(751 characters)' if test -f 'files.mar' then echo shar: "will not over-write existing file 'files.mar'" else cat << \SHAR_EOF > 'files.mar' Articles and Departments that have Additional On-Line Files AI EXPERT March 1987 "Intelligent Data Bases" (Note: Contents page is in file CONTNT.MAR) ARTICLES RELEVANT FILES -------- -------------- March Table of Contents CONTNT.MAR Actor Goes on Stage ACTOR.MAR by Andrew P. Bernat Learn LOGO Before LISP LOGO.MAR by Mike McMillan DEPARTMENTS Expert's Toolbox EXPERT.MAR "Heuristic State Space Search" by Marc Rettig SHAR_EOF if test 751 -ne "`wc -c < 'files.mar'`" then echo shar: "error transmitting 'files.mar'" '(should have been 751 characters)' fi fi echo shar: "extracting 'logo.mar'" '(7528 characters)' if test -f 'logo.mar' then echo shar: "will not over-write existing file 'logo.mar'" else cat << \SHAR_EOF > 'logo.mar' Learn LOGO Before LISP by Mike McMillan March 1987 issue of AI EXPERT Sidebars 1, 2, and 3 Sidebar 1 The following is a list of the LISP primitives, predicates, functions and their Logo equivalents. Those functions that do not have a Logo equivalent have been noted. Please remember that most, if not all, of the LISP functions that are not duplicated in Logo can be written in Logo. Logo is powerful enough to create functions that behave like their LISP equivalents. The LISP function is listed first, followed by the Logo equivalent or N/A, meaning Logo does not have that function. CAR - FIRST GET - GETPROP CDR - BUTFIRST PUTPROP - PUTPROP CXXXR - FIRST BUTFIRST...BUTFIRST REMPROP - REMPROP LAST - LAST PLIST - PLIST CONS - FPUT (FIRST PUT) ATOM - WORDP APPEND - LPUT (LAST PUT) NULL - EMPTYP LIST - LIST NUMBERP - NUMBERP NCONC - N/A (NCONC IN EXPERLOGO) SYMBOLP - N/A RPLACA - N/A (RPLACA IN EXPERLOGO) LISTP - LISTP RPLACD - N/A (RPLACD IN EXPERLOGO) EQUAL - EQUALP NREVERSE - N/A MEMBER - MEMBERP ASSOC - N/A (FINDKEY IN EXPERLOGO) GREATERP - GREATERP LENGTH - COUNT LESSP - LESSP REVERSE - N/A(REVERSE IN EXPERLOGO)ZEROP - N/A SUBST - N/A (SUBST IN EXPERLOGO) MINUSP - N/A LCONC - N/A PLUSP - N/A TCONC - N/A EVENP - N/A SETQ - MAKE ODDP - N/A SETF - N/A COND - IF SET - N/A IF - IF DEFUN - TO This is not an exhaustive list; several of the more compli-cated or lesser-used LISP functions have been left out. The reader should see from this list, though, just how much of LISP has been implemented in Logo. Sidebar 2 Writing LISP Functions in Logo Many of the LISP primitives and predicates that are not duplicated in Logo can be written in Logo. Logo's power as a symbolic computation language allows the programmer to do this. For example, in LISP there is a powerful primitive called ASSOC. ASSOC looks for a key that is part of an association list. For example, if we set up the following association: (SETQ 'JANE '((OCCUPATION STUDENT) (MAJOR COMPUTER-SCIENCE) (LANGUAGE LISP))) ASSOC can retrieve the information we have set up. Writing in LISP: (ASSOC 'LANGUAGE SALLY), the computer will respond: (LANGUAGE LISP). ASSOC is not defined in Logo. It is, however, very easy to create. We set up the association by writing: MAKE "SALLY [[OCCUPATION STUDENT] [MAJOR COMPUTER.SCIENCE] [LANGUAGE LISP]]. We define the ASSOC primitive as follows: TO ASSOC :KEY :OBJECT IF EMPTYP :OBJECT [OUTPUT "? STOP] IF EQUALP FIRST FIRST :OBJECT :KEY [OUTPUT FIRST :OBJECT STOP] OUTPUT ASSOC :KEY BF :OBJECT END Our Logo ASSOC goes through the association list recur- sively, checking each key to see if it matches the argument given. If there is nothing in the association list, or if it cannot find a match, ASSOC will output a question mark. When a match is found, the key and the object are output and the proce- dure stops. ASSOC is a fairly complicated example. Several of the LISP primitives that do not have Logo equivalents can be defined in one or two lines of Logo code. For example, to define the Logo version of LISP's ZEROP, we write: TO MY-ZEROP: NUMBER IF EQUALP :NUMBER "0 [OUTPUT "TRUE] IF EQUALP LAST :NUMBER "0 [OUTPUT "TRUE] [OUTPUT "FALSE] END The extensibility of Logo is helpful in the study of LISP. the student trying to model LISP expressions in Logo will often need to write LISP primitives and predicates in Logo in order to use them. I found in my own study that writing a LISP function in Logo gave me a deeper understanding of that function. It takes a higher magnitude of understanding to write a function than it does just to use the function. Sidebar 3 ExperLogo - A LISP-like Logo One version of Logo stands out from the others as being the most LISP-like in its form and structure - ExperLogo from Exper- Telligence. ExperLogo's LISPness is apparent in several dif- ferent areas - from its rules of evaluation to its toolchest of primitives and predicates. The first noticeable LISP-like feature of ExperLogo is the way it evaluates its expressions. In ExperLogo every expression is evaluated, meaning that primitives and predicates will print the results of their evaluation on the screen without the need for a PRINT command. This element of first-classness is an im- portant feature of LISP that is not found in most versions of Logo. For example, in most Logos to print the value of a variable the variable has to be combined with a PRINT command, such as PRINT :PEOPLE. In ExperLogo only the variable has to be written, as in :PEOPLE, which is much like the way it would be done in LISP - (PEOPLE). ExperLogo is also more LISP-like in the way values are bound to variables. In most Logos a value is bound to a variable by writing MAKE "NAME "TOM. In ExperLogo you can write: MAKE NAME TOM. In LISP it would be (SETQ NAME TOM). Expressions that evaluate to true or false in ExperLogo return values in the same manner as LISP, either T or NIL, which is unlike most Logos, which return TRUE or FALSE. Another area of ExperLogo that makes it so comparable to LISP is its expanded list of LISP-like primitives and predicates. In most versions of Logo there is not a primitive similar to LISP's REVERSE, which takes the elements of a list and reverse their order. ExperLogo has REVERSE. In LISP the primitive SUBST is used to substitute a new ex- pression for an old expression in some target expression, say a list. Most versions of Logo do not have this powerful primitive; ExperLogo does. A very powerful primitive in LISP is ASSOC (discussed in another sidebar). Most Logos do not have this primitive, though it can be written in Logo. ExperLogo has this primitive under another name - FINDKEY. FINDKEY works just like ASSOC; it takes a key word (atom) and an expression as arguments and then finds the element that goes with the key. Here is a list of functions in ExperLogo which are not found in other Logos but can be found in LISP: ELEMS, FINDKEY, NCONC, NPUT, PAIRLIST, REMOVE, REVERSE, RPLACA, RPLACD, SORT, SORTKEY and SUBST. Some of these functions do not duplicate their LISP equivalent's name, but in following the Logo tradition are more mnemonic, hence easier to remember and understand. ExperLogo at this time is available only for the Macintosh, but if you have a Mac and are looking for a Logo with a high degree of LISP similarity, I would highly recommend looking at this excellent Logo implementation. SHAR_EOF if test 7528 -ne "`wc -c < 'logo.mar'`" then echo shar: "error transmitting 'logo.mar'" '(should have been 7528 characters)' fi fi exit 0 # End of shell archive -- --------------- C'est la vie, C'est la guerre, C'est la pomme de terre Mail: Imagen Corp. 2650 San Tomas Expressway Santa Clara, CA 95052-8101 UUCP: ...{decvax,ucbvax}!decwrl!imagen!turner AT&T: (408) 986-9400