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