mirror of
https://github.com/PDP-10/its.git
synced 2026-03-27 02:24:15 +00:00
90 lines
2.8 KiB
Plaintext
Executable File
90 lines
2.8 KiB
Plaintext
Executable File
.comment -*- Mode:TEXT; -*-
|
|
.comment ASSQ, ASSOC
|
|
.document ASSQ - Making Association Lists; using ASSQ and ASSOC to get the info
|
|
.tag ASSQ
|
|
Lesson Searching Constructs ASSQ and ASSOC, Version 2
|
|
Kent M. Pitman, 5/27/79
|
|
revised by Victoria Pigman, 9/1/82
|
|
|
|
A very useful type of structure which is used often by Lisp programmers is
|
|
something called an Association list (or alist). It is a list which the user
|
|
can construct which has special things true about it that make it easy to
|
|
search through. In particular, it is a list of lists, and the first element of
|
|
each of the sub-lists is a tag that you would like to keep information about.
|
|
For instance:
|
|
|
|
.eval-print
|
|
(SETQ INFO-LIST '((DOG MAMMAL)
|
|
(CAT MAMMAL)
|
|
(LIZARD REPTILE)))
|
|
|
|
Notice that this list, INFO-LIST, is composed of sub-lists, each of which
|
|
contains information about the thing in the CAR of the sub-list. There are
|
|
functions which will retrieve the element of INFO-LIST which has a CAR that
|
|
is the same as some value we ask for. The most efficient of these is a function
|
|
called ASSQ. ASSQ returns the sub-list containing the info we desired, or NIL
|
|
if such a list was not found. (INFO-LIST has been set up for you.)
|
|
|
|
For example:
|
|
|
|
(ASSQ 'DOG INFO-LIST) should return (DOG MAMMAL)
|
|
(ASSQ 'FROG INFO-LIST) should return NIL
|
|
.try
|
|
Like MEMQ, ASSQ only works for finding symbols. Here's another example to
|
|
give a try...
|
|
|
|
(ASSQ '(FOO BAR) '(((FOO BAR) WE LOSE!) (A B)))
|
|
.try
|
|
But like with MEMQ, there is a function we can resort to when we have more
|
|
complex things to look for: ASSOC. This function will look for numbers or
|
|
lists. Example:
|
|
|
|
(ASSOC '(FOO BAR) '(((FOO BAR) WE WIN) (A B)))
|
|
|
|
returns ((FOO BAR) WE WIN)
|
|
|
|
(ASSOC '(BAR BAZ) '(((FOO BAR) IF IT FINDS THEN ASSOC IT IS BROKEN)
|
|
(A B)))
|
|
|
|
returns NIL.
|
|
.try
|
|
Let's do something useful with Association lists now. Suppose we define
|
|
some functions:
|
|
|
|
.eval-print
|
|
(DEFUN INIT-DATABASE () (SETQ DATABASE NIL))
|
|
|
|
.eval-print
|
|
(DEFUN DEFINE-CATEGORY (THING CATEGORY)
|
|
(SETQ DATABASE ;remember that "thing"
|
|
(CONS (LIST THING CATEGORY) DATABASE)) ;has a category of "category"
|
|
'DEFINED) ;return something so the user knows it worked
|
|
|
|
.eval-print
|
|
(DEFUN WHAT-CATEGORY? (THING)
|
|
(COND ((NOT (ASSQ THING DATABASE)) ;thing was not in database
|
|
'(SORRY -- MAY YOU SHOULD TEACH IT TO ME?))
|
|
(T
|
|
(CADR (ASSQ THING DATABASE))))) ;just return the info about it
|
|
|
|
|
|
Try doing the following:
|
|
|
|
(INIT-DATABASE) ; have to make sure our database is initialized!
|
|
(DEFINE-CATEGORY 'HORSE 'MAMMAL)
|
|
(DEFINE-CATEGORY 'FROG 'AMPHIBIAN)
|
|
(WHAT-CATEGORY? 'HORSE)
|
|
(WHAT-CATEGORY? 'DOG)
|
|
.try
|
|
To define ASSQ in Lisp, by the way, we'd just do this:
|
|
|
|
.pp
|
|
(DEFUN MYASSQ (TAG A-LIST)
|
|
(COND ((NULL A-LIST)
|
|
NIL)
|
|
((EQ TAG (CAAR A-LIST))
|
|
(CAR A-LIST))
|
|
(T
|
|
(MYASSQ TAG (CDR A-LIST)))))
|
|
.next LAMBDA
|