More work.
[idzebra-moved-to-github.git] / doc / zebra.sgml
1 <!doctype linuxdoc system>
2
3 <!--
4   $Id: zebra.sgml,v 1.7 1995-11-28 16:47:24 adam Exp $
5 -->
6
7 <article>
8 <title>Zebra Server - Administrators's Guide and Reference
9 <author>Index Data, <tt/info@index.ping.dk/
10 <date>$Revision: 1.7 $
11 <abstract>
12 The Zebra information server combines a versatile fielded/free-text
13 search engine with a Z39.50-1995 frontend to provide a powerful and flexible
14 information management system. This document explains the procedure for
15 installing and configuring the system, and outlines the possibilities
16 for managing data and providing Z39.50
17 services using the software.
18 </abstract>
19
20 <toc>
21
22 <sect>Introduction
23
24 <sect1>Overview
25
26 <p>
27 The Zebra system is a fielded free-text indexing and retrieval engine with a
28 Z39.50 frontend. You can use any commercial or freeware Z39.50 client
29 to access data stored in Zebra.
30
31 The Zebra server is our first step towards the development of a fully
32 configurable, open information system. Eventually, it will be paired
33 off with a powerful Z39.50 client to support complex information
34 management tasks within almost any application domain. We're making
35 the server available now because it's no fun to be in the open
36 information retrieval business all by yourself. We want to allow
37 people with interesting data to make their things
38 available in interesting ways, without having to start out
39 by implementing yet another protocol stack from scratch.
40
41 This document is an introduction to the Zebra system. It will tell you
42 how to compile the software, and how to prepare your first database.
43 It also explains how the server can be configured to give you the
44 functionality that you need.
45
46 You should read <it/Specifying and Using Application (Database)
47 Profiles/, which is bundled with the YAZ documentation, to learn how
48 records are formatted, and how you can configure Zebra to handle
49 different types of Z39.50 application profiles.
50
51 <sect1>Features
52
53 <p>
54 This is a listing of some of the most important features of the
55 system.
56
57 <itemize>
58
59 <item>
60 Supports updating - records can be added and deleted without
61 rebuilding the index.
62
63 <item>
64 Supports large databases - files for indices, etc. can be
65 automatically partitioned over multiple disks.
66
67 <item>
68 Supports arbitrarily complex records - base input format is an
69 SGML-like syntax which allows nested (structured) data elements, as
70 well as variant forms of data.
71
72 <item>
73 Supports boolean queries as well as relevance-ranking (free-text)
74 searching. Right truncation and masking in terms are supported, as
75 well as full regular expressions.
76
77 <item>
78 Supports multiple concrete syntaxes
79 for record exchange (depending on the configuration): GRS-1, SUTRS,
80 ISO2709 (*MARC). Records can be mapped between record syntaxes and
81 schema on the fly.
82
83 <item>
84 Protocol support:
85
86 <itemize>
87
88 <item>
89 Protocol facilities: Init, Search, Retrieve, Browse.
90
91 <item>
92 Piggy-backed presents are honored in the search-request.
93
94 <item>
95 Named result sets are supported.
96
97 <item>
98 Easily configured to support different application profiles, with
99 tables for attribute sets, tag sets, and abstract syntaxes.
100 Additional tables control facilities such as element mappings to
101 different schema (eg., GILS-to-USMARC).
102
103 <item>
104 Complex composition specifications using Espec-1 are partially
105 supported (simple element requests only).
106
107 <item>
108 Element Set Names are established the Espec-1 capability of the
109 system, and are given in configuration files as simple element
110 requests (and possibly variant requests).
111
112 <item>
113 Some variant support (not fully implemented yet).
114
115 <item>
116 Using the YAZ toolkit for the protocol implementation, the
117 server can utilise a plug-in XTI/mOSI implementation (not included) to
118 provide SR services over an OSI stack, as well as Z39.50 over TCP/IP.
119
120 </itemize>
121
122 </itemize>
123
124 <sect1>Future Work
125
126 <p>
127 This is an early alfa-release of the software, to allow you to look at
128 it - try it out, and assess whether it can be of use to you. We expect
129 this version to be followed by a succession of beta-releases until we
130 arrive at a stable first version.
131
132 These are some of the plans that we have for the software in the near
133 and far future, approximately ordered after their relative importance.
134 Items marked with an
135 asterisk will be implemented before the
136 last beta release.
137
138 <itemize>
139
140 <item>
141 *Allow the system to handle additional input formats. Specifically
142 MARC records and general, structured ASCII records (such as mail/news
143 files) parameterized by regular expressions.
144
145 <item>
146 *Complete the support for variants. Finalize support for the WAIS
147 retrieval methodology.
148
149 <item>
150 *Finalize the data element <it/include/ facility to support multimedia
151 data elements in records.
152
153 <item>
154 *Port the system to Windows NT.
155
156 <item>
157 Add robust database updating - tolerant to crashes or hard interrupts
158 during register updating.
159
160 <item>
161 Add online updating, to permit register updating while users are
162 accessing the system.
163
164 <item>
165 Add index and data compression to save disk space.
166
167 <item>
168 Add more sophisticated relevance ranking mechanisms. Add support for soundex
169 and stemming. Add relevance feedback support.
170
171 <item>
172 Add Explain support.
173
174 <item>
175 Add support for very large records by implementing segmentation and
176 variant pieces.
177
178 <item>
179 Support the Item Update extended service of the protocol.
180
181 <item>
182 The Zebra search engine supports approximate string matching in the
183 index. We'd like to find a way to support and control this from RPN.
184
185 <item>
186 We want to add a management system that allows you to
187 control your databases and configuration tables from a graphical
188 interface. We'll probably use Tcl/Tk to stay platform-independent.
189
190 </itemize>
191
192 Programmers thrive on user feedback. If you are interested in a facility that
193 you don't see mentioned here, or if there's something you think we
194 could do better, please drop us a mail. If you think it's all really
195 neat, you're of course welcome to drop us a line saying that, too.
196 <sect>Introduction
197
198 <sect>Compiling the software
199
200 <p>
201 Zebra uses the YAZ package to implement Z39.50, so you
202 have to compile YAZ before going further. Specifically, Zebra uses
203 the YAZ header files in <tt>yaz/include/..</tt> and its public library
204 <tt>yaz/lib/libyaz.a</tt>.
205
206 As with YAZ, an ANSI C compiler is required in order to compile the Zebra
207 server system &mdash; GNU C works fine.
208
209 Unpack the Zebra software. You might put Zebra in the same directory level
210 as YAZ, for example if YAZ is placed in ..<tt>/src/yaz-</tt>.., then
211 Zebra is placed in ..<tt>/src/zebra-</tt>.
212
213 Edit the top-level <tt>Makefile</tt> in the Zebra directory in which
214 you specify the location of YAZ by setting make variables.
215 The <tt>OSILIB</tt> should be empty if YAZ wasn't compiled with
216 MOSI support. Some systems, such as Solaris, have separate socket
217 libraries and for those systems you need to specify the
218 <tt>NETLIB</tt> variable.
219
220 When you are done editing the <tt>Makefile</tt> type:
221 <tscreen><verb>
222 $ make
223 </verb></tscreen>
224
225 If successful, two executables have been created in the sub-directory
226 <tt/index/.
227 <descrip>
228 <tag><tt>zebrasrv</tt></tag> The Z39.50 server and search engine.
229 <tag><tt>zebraidx</tt></tag> The administrative tool for the search index.
230 </descrip>
231
232 <sect>Quick Start
233
234 <p>
235 This section will get you started quickly! We will try to index a few sample
236 GILS records that are included with the Zebra distribution. Go to the
237 <tt>test</tt> subdirectory. There you will find a configuration
238 file named <tt>zebra.cfg</tt> with the following contents:
239 <tscreen><verb>
240 # Where are the YAZ tables located.
241 profilePath: /usr/local/yaz
242
243 # Files that describe the attribute sets supported.
244 attset: bib1.att
245 attset: gils.att
246 </verb></tscreen>
247
248 Now, edit the file and set <tt>profilePath</tt> to the path of the
249 YAZ profile tables (sub directory <tt>tab</tt> of YAZ).
250
251 The 48 test records are located in the sub directory <tt>records</tt>.
252 To index these, type:
253 <tscreen><verb>
254 $ ../index/zebraidx -t grs update records
255 </verb></tscreen>
256
257 In the command above the option <tt>-t</tt> specified the record
258 type &mdash; in this case <tt>grs</tt>. The word <tt>update</tt> followed
259 by a directory root updates all files below that directory node.
260
261 If your indexing command went successful, you are now ready to
262 fire up a server. To start a server on port 2100, type:
263 <tscreen><verb>
264 $ ../index/zebrasrv tcp:@:2100
265 </verb></tscreen>
266
267 The Zebra index that you've just made has one database called Default. It will
268 return either USMARC, GRS-1, or SUTRS depending on what your client asks
269 for.
270
271 To test the server, you can use any Z39.50 client (1992 or later). For
272 instance, you can use the demo client that comes with YAZ: Just cd to
273 the <tt/client/ subdirectory of the YAZ distribution and type:
274
275 <tscreen><verb>
276 $ client tcp:localhost:2100
277 </verb></tscreen>
278
279 When the client has connected, you can type:
280
281 <tscreen><verb>
282 Z> find surficial
283 Z> show 1
284 </verb></tscreen>
285
286 To try other retrieval formats for the same record, try:
287
288 <tscreen><verb>
289 Z>format sutrs
290 Z>show 1
291 Z>format grs-1
292 Z>show 1
293 </verb></tscreen>
294
295 If you've made it this far, there's a reasonably good chance that
296 you've made it through the compilation OK.
297
298 <sect>Administrating Zebra
299
300 <p>
301
302 Unlike many other retrieval systems, Zebra offers incremental
303 modifications of an existing index. Needless to say, these facilities
304 make the administration of Zebra a bit more complicated than
305 systems that use the &dquot;index-it-all&dquot; approach.
306
307 Normally, when Zebra modifies the index it reads a number of records
308 that you specify.
309 Depending on your specifications and on the contents of each record
310 one the following events take place for each record:
311 <descrip>
312 <tag>Insert</tag> The record is indexed as if it never occurred
313 before. Either the Zebra system doesn't know how to identify the record or
314 Zebra can identify the record but didn't find it to be already indexed.
315 <tag>Modify</tag> The record has already been indexed. In this case
316 either the contents of the record or the location (file) of the record
317 indicates that it has been indexed before.
318 <tag>Delete</tag> The record is deleted from the index. As in the
319 update-case it must be able to identify the record.
320 </descrip>
321
322 Please note that in both the modify- and delete- case the Zebra
323 indexer must be able to make a unique key that identifies the record in
324 question.
325
326 To administrate the Zebra retrieval system, you run the
327 <tt>zebraidx</tt> program. This program supports a number of options
328 which are preceded by a minus, and a few commands (not preceded by
329 minus).
330
331 Both the Zebra administrative tool and the Z39.50 server share a
332 set of index files and a global configuration file. The
333 name of the configuration file defaults to <tt>zebra.cfg</tt>.
334 The configuration file includes specifications on how to index
335 various kinds of records and where the other configuration files
336 are located. <tt>zebrasrv</tt> and <tt>zebraidx</tt> <em>must</em>
337 be run in the same directory where the configuration file if you do
338 not indicate the location of the configuration file by option
339 <tt>-c</tt>.
340
341 <sect1>Record types
342 <p>
343 Indexing is a record-per-record process, in which
344 either insert/modify/delete will occur. Before a record is indexed
345 search keys are extracted from whatever might be the layout the
346 original record (sgml,html,text, etc..). The Zebra system 
347 currently only supports SGML-like, structured records and unstructured text
348 records.
349 To specify a particular extraction process, use either the
350 command line option <tt>-t</tt> or specify a
351 <tt>recordType</tt> setting in the configuration file.
352
353 <sect1>The Zebra Configuration File
354 <p>
355 The Zebra configuration file, read by <tt>zebraidx</tt> and
356 <tt>zebrasrv</tt> defaults to <tt>zebra.cfg</tt> unless specified
357 by <tt>-c</tt> option.
358
359 You can edit the configuration file with a normal text editor.
360 Setting names and values are seperated by colons in the file. Lines
361 starting with a hash sign (<tt/#/) are treated as comments.
362
363 A set of records that share common characteristics are called a group.
364 When <tt>zebraidx</tt> is run and you wish to address a given group
365 you specify that group with the <tt>-g</tt> option. In this case
366 settings that have the group name as their prefix will be used
367 by <tt>zebraidx</tt> and not default values. The default values have no prefix.
368
369 The group is written before the option itself separated by a dot.
370 For instance, to set the record type for group <tt/public/ to <tt/grs/ (structured records)
371 you would write:
372
373 <tscreen><verb>
374 public.recordType: grs
375 </verb></tscreen>
376
377 To set the default value of the record type to text write:
378
379 <tscreen><verb>
380 recordType: text
381 </verb></tscreen>
382
383 The configuration settings are summarized below. They will be
384 explained further in the following sections.
385
386 <descrip>
387 <tag><it>group</it>recordType<it>name</it></tag>
388  Specifies how records with the file extension <it>name</it> should
389  be handled by the indexer. This option may also be specified
390  as a command line option (<tt>-t</tt>).
391 <tag><it>group</it>recordId</tag>
392  Specifies how the record is to be identified when updated.
393 <tag><it>group</it>database</tag>
394  Specifies the Z39.50 database.
395 <tag><it>group</it>storeKeys</tag>
396  Specifies whether key information should be saved for a given
397  group of records. If you plan to update/delete this type of
398  records later this should be specified as 1; otherwise it
399  should be 0 (default).
400 <tag><it>group</it>storeData</tag>
401  Specifies whether the records should be stored internally
402  in the Zebra system tables. If you want to maintain the raw records yourself,
403  this option should be false (0). If you want Zebra to take care of the records
404  for you, it should be true(1).
405 <tag>register</tag> 
406  Specifies the location of the various files that Zebra uses to represent
407  your system.
408 <tag>profilePath</tag>
409  Specifies the location of profile specification paths.
410 <tag>attset</tag> 
411  Specifies the filename(s) of attribute set files for use in searching.
412 </descrip>
413
414 <sect1>Locating Records
415 <p>
416 The default behaviour of the Zebra system is to reference the
417 records from their original location, i.e. where they were found when you
418 ran <tt/zebraidx/.
419
420 If your records files are temporary - for example if you retrieve
421 them from the outside, or if they where temporarily mounted on a CD-ROM,
422 you may want Zebra to make a copy of them. To do this,
423 you specify 1 (true) in the <tt>storedata</tt> setting. When
424 the Z39.50 server retrieves records they will be read from the
425 internal file structures of the system.
426
427 <sect1>Indexing with no Record IDs (Simple Indexing)
428
429 <p>
430 If you have a set of records that you <em/never/ wish to delete
431 or modify you may find &dquot;indexing without records IDs&dquot; convenient.
432 This indexing method uses less space than the other methods and
433 is simple to use. 
434
435 To use this method, you simply don't provide the <tt>recordId</tt> entry
436 for the group of files that you index. To add a set of records you use
437 <tt>zebraidx</tt> with the <tt>update</tt> command. The
438 <tt>update</tt> command will always add all of the records to the index
439 becuase Zebra doesn't know how to match the new set of records with
440 existing records.
441
442 Consider a system in which you have a group of text files called
443 <tt>simple</tt>. That group of records should belong to a Z39.50 database
444 called <tt>textbase</tt>. The following <tt/zebra.cfg/ file will suffice:
445
446 <tscreen><verb>
447 profilePath: /usr/local/yaz
448 attset: bib1.att
449 attset: gils.att
450 simple.recordType: text
451 simple.database: textbase
452 </verb></tscreen>
453
454 Since the existing records in an index can not be addressed by their
455 IDs, it is impossible to delete records when using this method.
456
457 <sect1>Indexing with File Record IDs
458
459 <p>
460 If you have a set of external records that you wish to index you may
461 use the file key feature of the Zebra system. In short, the file key
462 feature mirrors a directory structure and its files efficiently. To
463 perform indexing of a directory with file keys, you specify the top-level
464 directory after the <tt>update</tt> command. The command will recursively
465 traverse the directories and compare each with whatever have been
466 indexed before in the same directory. If a file is new (not in
467 the previous version of the directory) it is inserted;
468 if a file was already indexed and it has been modified
469 since the last insertion the index is also modified; if a file is missing
470 since the last visit it is deleted from the index.
471
472 The resulting system is easy to administer. To delete a record
473 you simply have to delete the corresponding file (with <tt/rm/). 
474 To force update of a given file, you may use the <tt>touch</tt>
475 command. And to add files create new files (or directories with files).
476 For your changes to take effect you must run <tt>zebraidx</tt> with
477 the same directory root again.
478
479 To use this method, you must specify <tt>file</tt> as the value
480 of <tt>recordId</tt> in the configuration file. In the configuration
481 also set <tt>storeKeys</tt> to <tt>1</tt>, since the Zebra
482 indexer must save additional information per record in order to
483 modify/delete the records at a later time.
484
485 For example, to update group <tt>esdd</tt> records below
486 <tt>/home/grs</tt> you could type:
487 <tscreen><verb>
488 $ zebraidx -g esdd update /home/grs
489 </verb></tscreen>
490
491 The corresponding configuration file includes:
492 <tscreen><verb>
493 esdd.recordId: file
494 esdd.recordType: grs
495 esdd.storeKeys: 1
496 </verb></tscreen>
497
498 <em>Important note: You cannot start out with a group of records with simple
499 indexing (no record IDs as in the previous section) and then later
500 enable file record Ids. Zebra must know from the first time that you
501 index the group that
502 the files should be indexed with file record IDs.
503 </em>
504
505 You cannot explicitly delete records when using this method. Instead
506 you have to delete the files from the file system (or remove them)
507 and then run <tt>zebraidx</tt> with the <tt>update</tt> again.
508
509 <sect1>Indexing with General Record IDs
510 <p>
511 When using this method you specify an (almost) arbritrary record key
512 based on the contents of the record itself and other system
513 information. If you have a group of records that have an external
514 ID associated with each records, this method is convenient. For
515 example, the record may contain a title or a unique ID-number. In either
516 case you specify the Z39.50 attribute set and use-attribute location
517 in which this information is stored.
518
519 As before, the record ID is defined by the <tt>recordId</tt> setting
520 in the configuration file. The value of the record ID specification
521 consists of one or more tokens separated by whitespace. The resulting
522 ID is
523 represented in the index by concatenating the tokens and separating them by
524 ASCII value (1).
525
526 There are three kinds of tokens:
527 <descrip>
528 <tag>Internal record info</tag> The token refers to a key that is
529 extracted from the record. The syntax of this token is
530  <tt/(/ <em/set/ <tt/,/ <em/use/ <tt/)/, where <em/set/ is the
531 attribute set ordinal number and <em/use/ is the use value of the attribute.
532 <tag>System variable</tag> The system variables are preceded by
533 <verb>$</verb> and immediately followed by the system variable name, which
534 may one of
535  <descrip>
536  <tag>group</tag> Group name.
537  <tag>database</tag> Current database specified.
538  <tag>type</tag> Record type.
539  </descrip>
540 <tag>Constant string</tag> A string used as part of id &mdash; surrounded
541  by single- or double quotes.
542 </descrip>
543
544 The test GILS records that comes with the Zebra distribution contain a
545 unique ID
546 in the Control-Identifier field. This field is mapped to the Bib-1
547 use attribute 1007. To use this field as a record id, specify
548 <tt>(1,1007)</tt> as the value of the <tt>recordId</tt> in the
549 configuration file. If you have other record types that don't
550 contain an ID in the same field, you might add the record type
551 in the record id of the gils records as well, to prevent matches
552 of other types of records. In this case the recordId might be
553 set like this:
554 <tscreen><verb>
555 gils.recordId: $type (1,1007)
556 </verb></tscreen>
557
558 As for the file record id case described in the previous section
559 updating your system is simply a matter of running <tt>zebraidx</tt>
560 with the <tt>update</tt> command. However, the update with general
561 keys is considerably slower than with file record IDs, since all files
562 visited must be (re)read to find their IDs. 
563
564 You may have noticed that when using the general record IDs
565 method, you can only add or modify existing records with the <tt>update</tt>
566 command. If you wish to delete records, you must use another command,
567 <tt>delete</tt>, which a root directory as a parameter. This will remove
568 all records that match the files below the root directory.
569
570 <sect1>Register location
571
572 <p>
573 Normally, the index files that form dictionaries, inverted
574 files, record info, etc., are stored in the directory where you run
575 <tt>zebraidx</tt>. If you wish to store these, possibly large, files
576 somewhere else, you must add the <tt>register</tt> entry to the
577 configuration file. Furthermore, the Zebra system allows its file
578 structures to
579 span multiple file systems, which is useful if a very large number of
580 records are stored.
581
582 The value <tt>register</tt> of register is a sequence of tokens.
583 Each token takes the form:
584 <tscreen>
585 <em>dir</em><tt>:</tt><em>size</em>. 
586 </tscreen>
587 The <em>dir</em> specifies a directory in which index files will be
588 stored and the <em>size</em> specifies the maximum size of all
589 files in that directory. The Zebra indexer system fill each directory
590 in the order specified and use the next specified directories as needed.
591 The <em>size</em> is an integer followed by a qualifier
592 code, <tt>M</tt> for megabytes, <tt>k</tt> for kilobytes.
593
594 For instance, if you have two spare disks :) and the first disk is mounted
595 on <tt>/d1</tt> and has 200 Mb of free space and the
596 second, mounted on <tt>/d2</tt> has 300 Mb, you could
597 put this entry in your configuration file:
598 <tscreen><verb>
599 register: /d1:200M /d2:300M
600 </verb></tscreen>
601
602 <sect>The Z39.50 Server
603
604 <p>
605
606 <sect1>Running the server
607 <p>
608 The server <tt>zebrasrv</tt> supports the same set of options as the 
609 test server <tt>ztest</tt> that comes with YAZ. As for the 
610 <tt>zebraidx</tt> the option <tt>-c</tt> specifies the configuration
611 filename. When the Zebra server is executed with its normal log level it 
612 prints (not too detailed) information about the incoming queries. 
613 This is useful if you don't happen to know what attributes your client sends.
614
615 Note that the server doesn't support the static mode (-S). 
616
617 <sect>License
618
619 <p>
620 Copyright &copy; 1995, Index Data.
621
622 All rights reserved.
623
624 Use and redistribution in source or binary form, with or without
625 modification, of any or all of this software and documentation is
626 permitted, provided that the following conditions are met:
627
628 1. This copyright and permission notice appear with all copies of the
629 software and its documentation. Notices of copyright or attribution
630 which appear at the beginning of any file must remain unchanged.
631
632 2. The names of Index Data or the individual authors may not be used to
633 endorse or promote products derived from this software without specific
634 prior written permission.
635
636 3. Source code or binary versions of this software and its documentation
637 may be used in not-for-profit applications. For profit aplications -
638 including marketing a product based in whole or in part on this software,
639 or providing for-pay database services - must obtain a commercial
640 license from Index Data.
641
642 THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
643 EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
644 WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
645 IN NO EVENT SHALL INDEX DATA BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
646 INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
647 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR
648 NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
649 LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
650 OF THIS SOFTWARE.
651
652 <sect>About Index Data
653
654 <p>
655 Index Data is a consulting and software-development enterprise that
656 specialises in library and information management systems. Our
657 interests and expertise span a broad range of related fields, and one
658 of our primary, long-term objectives is the development of a powerful
659 information management
660 system with open network interfaces and hypermedia capabilities.
661
662 We make this software available free of charge for noncommercial
663 purposes, as a service to the networking community, and to further
664 the development of quality software for open network communication.
665
666 We'll be happy to answer questions about the software, and about ourselves
667 in general.
668
669 <tscreen>
670 Index Data&nl
671 Ryesgade 3&nl
672 DK-2200 K&oslash;benhavn N&nl
673 </tscreen>
674
675 <p>
676 <tscreen><verb>
677 Phone: +45 3536 3672
678 Fax  : +45 3536 0449
679 Email: info@index.ping.dk
680 </verb></tscreen>
681
682 The <it>Random House College Dictionary</it>, 1975 edition
683 offers this definition of the 
684 word &dquot;Zebra&dquot;:
685
686 <it>
687 Zebra, n., any of several horselike, African mammals of the genus Equus,
688 having a characteristic pattern of black or dark-brown stripes on
689 a whitish background.
690 </it>
691
692 </article>