spell User’s Manual

This manual is for spell version 0.0.3.

Table of Contents


1 Introduction

The spell library provides protocols and implementations of those protocols for automatic spell-checking and suggestion of likely corrections. In addition to the spelling of words, dictionary entries contain information about word types and properties of the words such as case, gender and number. At the moment, English is the only supported language.


2 External Protocols

This chapter describes the external protocols provided by the spell library.


2.1 English Protocol

This protocol provides the highest level of abstraction within the spell library. The protocol consists of a few functions that perform the most common operations with minimal setup effort.

Function: spell:english-lookup string

Return a (possibly empty) list of entries in the English dictionary the spelling of which matches string.

The returned entries are instances of word. More than one entry in the dictionary can match string due to different word types or multiple combinations of properties within a word type that share a common spelling.

Note that clients which are interested only in the validity of string and not in the matching dictionary entries can treat the return value as a generalized Boolean.

Examples:

(spell:english-lookup "lithp")
⇒ NIL

(spell:english-lookup "lisp")
⇒ (#<EXPLICIT-BASE-VERB "lisp" person:ANY number:ANY ... infinitive:SELF {1004ED5993}>
   #<EXPLICIT-BASE-NOUN "lisp" number:SINGULAR case:NIL gender:NIL {1004ED3533}>)
Function: spell:english-check-paragraph string

Check the paragraph of English text string for spelling errors and return a list of detected errors.

The return value of this function is a possibly empty list of entries of the form (start-index . end-index). The start-index and end-index within each entry designate a sub-string of string that corresponds to a misspelled word.

Example:

(spell:english-check-paragraph "In Polish, a horse is koń, and in German, it's
das Pferd.")
⇒ ((22 . 25) (47 . 50) (51 . 56))

The three pairs in the result correspond to sub-strings that are not valid English words:

(loop :with string = "In Polish, a horse is koń, and in German, it's
das Pferd."
      :for (start . end) :in (spell:english-check-paragraph string)
      :collect (subseq string start end))
⇒ ("koń" "das" "Pferd")
Function: spell:english-corrections string &key threshold variants group-by count

Return entries from the English dictionary that are at most threshold removed from string in terms of edit-distance. Return two values: a list of entries and a Boolean which indicates whether string is spelled correctly according to the English dictionary. By default, the elements of the list that is the first return value are unique strings that correspond to the spellings of matching dictionary entries. The caller can use the group-by parameter (see below) to make the function return pairs of word instances and spellings instead.

If supplied, threshold has to be a non-negative integer that controls the maximum edit-distance of returned corrections from string. Note that the value 0 for threshold is not very useful since english-lookup is a simpler way to perform that operation.

If supplied, variants has to be a function that accepts as its arguments a string and another function which it must call once for each case variant of the string that should be considered. The default value is a more complete and sophisticated version of the following:

(lambda (continuation string)
  (funcall continuation string)
  (when ‘certain-conditions’
    (funcall continuation (string-decapitalized string)))
  (when ‘certain-conditions’)
    (funcall continuation (string-downcase string)))

If supplied, group-by has to be either :spelling or :entry. It controls whether word objects are included in elements of the returned list. If group-by is :entry, elements are of the form (word . spelling). If group-by is :spelling, elements are strings and each string is one spelling. The default is :spelling. Note that the value of group-by influences the number returned elements since a spelling that corresponds to multiple entries will be reported once for :spelling but multiple times for :entry.

If supplied, count controls the maximum number of entries that are returned as the first value.

Examples:

(spell:english-corrections "lisp" :threshold 1)
⇒ ("lisp" "lisps" "list" "lip" "limp" "wisp") T

(spell:english-corrections "lifp" :threshold 1)
⇒ ("lift" "life" "lip" "lisp" "limp") NIL

(spell:english-corrections
 "abc" :threshold 1
       :variants (lambda (continuation string)
                   (funcall continuation (string-upcase string))))
⇒ ("ABC" "ABCs") T

(spell:english-corrections
 "abc" :threshold 1
       :variants (lambda (continuation string)
                   (funcall continuation (string-upcase string)))
       :group-by :entry)
⇒ ((#<EXPLICIT-BASE-NOUN "ABC" number:SINGULAR ...> . "ABC")
   (#<EXPLICIT-BASE-NOUN "ABC" number:PLURAL ... > . "ABCs"))
  T

2.2 Word Protocols

Entries in spell dictionaries are conceptually pair: an (implicit) string that is the spelling and a word object that characterizes the word type and the type-specific properties of the word. Word objects are instance of subclasses of word. spell defines the following sub-classes of word and associated readers:

Word Class word

Class: spell:word ()

Superclass for all word classes.

Generic Function: spell:base word

Return the base word of word.

For words of type noun, the base word is usually the nominative, singular variant of the word.

For words of type verb, the base word is usually the infinitive variant of the word.

Word Class adjective

Class: spell:adjective (word)

Instances represent adjectives, that is a property of a noun together with the degree of that property.

Generic Function: spell:degree word

Return a keyword which indicates the degree for word.

Possible values are :positive, :comparative and :superlative.

Examples

zinkier#<EXPLICIT-BASE-ADJECTIVE "zincy" degree:COMPARATIVE {100CEA1883}>
wroughter#<EXPLICIT-BASE-ADJECTIVE "wrought" degree:COMPARATIVE {100CE576D3}>
well-wornest#<EXPLICIT-BASE-ADJECTIVE "well-worn" degree:SUPERLATIVE {100CD45EF3}>

Word Class adverb

Class: spell:adverb (word)

Instances represent adverb, that is a property of a verb.

Examples

unstoppably#<EXPLICIT-BASE-ADVERB "unstoppably" {100CB2E753}>
twistingly#<EXPLICIT-BASE-ADVERB "twistingly" {100CA301F3}>
together#<EXPLICIT-BASE-ADVERB "together" {100C86C173}>

Word Class conjunction

Class: spell:conjunction (word)

Direct instances represent conjunctions, that is words which connect sentences or clauses.

Examples

seeing#<EXPLICIT-BASE-CONJUNCTION "seeing" {100B542143}>
providing#<EXPLICIT-BASE-CONJUNCTION "provided" {100AE1B513}>
either#<EXPLICIT-BASE-CONJUNCTION "either" {100E468F43}>

Word Class subordinate

Class: spell:subordinate (word, conjunction)

Instances represent subordinates, that is conjunctions which connect a dependent and an independent clause.

Examples

whether#<EXPLICIT-BASE-SUBORDINATE "whether" {100CD84A83}>
that#<EXPLICIT-BASE-SUBORDINATE "that" {100C77D873}>
if#<EXPLICIT-BASE-SUBORDINATE "if" {1001A7DFB3}>

Word Class determiner

Class: spell:determiner (word)

Instances are determiners, that is words which determine one or more aspect, such as the grammatical number, of a noun. Also a superclass for several more specific determiner classes.

Generic Function: spell:number word

Return a keyword which indicates the number for entities related to word.

If word is a verb, the keyword indicates the number of agents who perform the action.

If word is a noun, the keyword indicates the number of objects or people the noun refers to. Similarly for pronouns.

If word is a determiner (or a more specific word sub type), the number refers to the associated noun.

Possible values are :any, :singular and :plural.

Word Class article

Class: spell:article (word, determiner)

Instances are articles, that is determiners which specify whether a noun refers to a particular or an arbitrary entity.

Generic Function: spell:determinate word

Return a Boolean which indicates whether the noun associated with word refers to particular or an arbitrary entity.

Examples

the#<EXPLICIT-BASE-ARTICLE "the" number:SINGULAR determinate:T {100C7C2133}>
a#<EXPLICIT-BASE-ARTICLE "a" number:SINGULAR determinate:NIL {100E468F83}>
an#<EXPLICIT-BASE-ARTICLE "an" number:SINGULAR determinate:NIL {100E468F93}>

Word Class demonstrative-adjective

Class: spell:demonstrative-adjective (word, determiner)

Instances represent demonstrative adjectives, that is determiners which highlight the fact that an associated noun is identifiable from the context.

Examples

this#<EXPLICIT-BASE-DEMONSTRATIVE-ADJECTIVE "this" number:SINGULAR {100C7DA0E3}>
these#<EXPLICIT-BASE-DEMONSTRATIVE-ADJECTIVE "these" number:PLURAL {100C7C0D23}>
that#<EXPLICIT-BASE-DEMONSTRATIVE-ADJECTIVE "that" number:SINGULAR {100C7935C3}>

Word Class interrogative-adjective

Class: spell:interrogative-adjective (word, determiner)

Instances represent interrogative adjectives, that is adjectives

Examples

which#<EXPLICIT-BASE-INTERROGATIVE-ADJECTIVE "which" number:ANY {100CD85E23}>
what#<EXPLICIT-BASE-INTERROGATIVE-ADJECTIVE "what" number:ANY {100CD758B3}>

Word Class possessive-adjective

Class: spell:possessive-adjective (word, determiner)

Instances represent possessive adjectives, that is determiners which mark a noun as being possessed by another entity.

Generic Function: spell:refnumber word

Return a keyword which indicates the grammatical number of the possessing entity referenced by word.

Possible values are :any, :singular and :plural.

Generic Function: spell:person word

Return a keyword which indicates the grammatical person of entities associated with word.

Possible values are :any, :first, :second, :third.

Generic Function: spell:gender word

Return a keyword which indicates the gender of entities related to word.

Possible values are nil, :masculine, :feminine and :neuter.

Examples

its#<EXPLICIT-BASE-POSSESSIVE-ADJECTIVE "its" number:ANY gender:ANY person:THIRD refnumber:SINGULAR {100284BA73}>
his#<EXPLICIT-BASE-POSSESSIVE-ADJECTIVE "his" number:ANY gender:MASCULINE person:THIRD refnumber:SINGULAR {100191CA63}>
her#<EXPLICIT-BASE-POSSESSIVE-ADJECTIVE "her" number:ANY gender:FEMININE person:THIRD refnumber:SINGULAR {10018B6E93}>

Word Class quantifier

Class: spell:quantifier (word, determiner)

Instances are quantifiers, that is determiners which specify count or amount of a noun.

Examples

enough#<EXPLICIT-BASE-QUANTIFIER "enough" number:ANY {100E468EA3}>
eleven#<EXPLICIT-BASE-QUANTIFIER "eleven" number:PLURAL {100E468EB3}>
either#<EXPLICIT-BASE-QUANTIFIER "either" number:SINGULAR {100E468EC3}>

Word Class interjection

Class: spell:interjection (word)

Instances represent interjections, that is words which interrupt the sequence of words within a sentence or the sequence of sentences.

Examples

bye-bye#<EXPLICIT-BASE-INTERJECTION "bye-bye" {100E468733}>
blimey#<EXPLICIT-BASE-INTERJECTION "blimey" {100E468743}>
begorra#<EXPLICIT-BASE-INTERJECTION "begorra" {100E468753}>

Word Class noun

Class: spell:noun (word)

Direct instances represent generic nouns. Also a superclass for more specific noun classes.

The generic function gender can be applied to words of this class.

Generic Function: spell:case word

Return a keyword which indicates the grammatical case of word.

Possible values are :nominative, :genitive, :accusative and :nominative-or-accusative.

The generic function number can be applied to words of this class.

Examples

yellow-flags#<EXPLICIT-BASE-NOUN "yellow-flag" number:PLURAL case:NIL gender:NIL {100CE77343}>
worrywarts#<EXPLICIT-BASE-NOUN "worrywart" number:PLURAL case:NIL gender:NIL {100CE3AB53}>
woodrushes#<EXPLICIT-BASE-NOUN "woodrush" number:PLURAL case:NIL gender:NIL {100CE1CF13}>

Word Class noun-verb-contraction

Class: spell:noun-verb-contraction (word, verb, noun)

Instances are of type noun and also of type verb and are formed as a contraction of one noun and one verb.

Examples

’twould#<EXPLICIT-BASE-NOUN-VERB-CONTRACTION "it would" person:THIRD number:SINGULAR tense:PRESENT-SIMPLE negative:NIL contraction:NIL strength:WEAK infinitive:NIL case:NIL gender:NEUTER {100E4687D3}>
’twill#<EXPLICIT-BASE-NOUN-VERB-CONTRACTION "it will" person:THIRD number:SINGULAR tense:PRESENT-SIMPLE negative:NIL contraction:NIL strength:WEAK infinitive:NIL case:NIL gender:NEUTER {100E4687E3}>
’twas#<EXPLICIT-BASE-NOUN-VERB-CONTRACTION "it was" person:THIRD number:SINGULAR tense:PAST negative:NIL contraction:NIL strength:STRONG infinitive:NIL case:NIL gender:NEUTER {100E4687F3}>

Word Class proper-noun

Class: spell:proper-noun (word, noun)

Instances represent proper nouns, that is generally names.

Examples

Zaragozas#<EXPLICIT-BASE-PROPER-NOUN "Zaragoza" number:PLURAL case:NIL gender:NIL {100E468CD3}>
Trinidad#<EXPLICIT-BASE-PROPER-NOUN "Trinidad" number:SINGULAR case:NIL gender:NIL {100E468CE3}>
Sloughs#<EXPLICIT-BASE-PROPER-NOUN "Slough" number:PLURAL case:NIL gender:NIL {100E468CF3}>

Word Class preposition

Class: spell:preposition (word)

Instances represent prepositions, that is words which indicate the spatial, temporal, logical, etc. relations between other words.

Examples

although#<EXPLICIT-BASE-PREPOSITION "although" {100E468363}>
alongside#<EXPLICIT-BASE-PREPOSITION "alongside" {100E468373}>
albeit#<EXPLICIT-BASE-PREPOSITION "albeit" {100E468383}>

Word Class pronoun

Class: spell:pronoun (word)

Direct instances represent generic pronouns. Also a superclass for several more specific pronoun classes.

Generic Function: spell:negative word

Return a Boolean which indicates whether the meaning of word is in some way negative.

If word is a verb, a true value indicates that the absence of the action represented by the verb.

If word is a pronoun, a true value indicates the complement of the set of entities for which the non negated pronoun would stand in.

The generic function case can be applied to words of this class.

The generic function gender can be applied to words of this class.

The generic function number can be applied to words of this class.

The generic function person can be applied to words of this class.

Examples

everyone#<EXPLICIT-BASE-PRONOUN "everyone" person:THIRD number:SINGULAR gender:NIL case:NOMINATIVE-OR-ACCUSATIVE negative:NIL {100E4682C3}>
everybody#<EXPLICIT-BASE-PRONOUN "everybody" person:THIRD number:SINGULAR gender:NIL case:NOMINATIVE-OR-ACCUSATIVE negative:NIL {100E4682D3}>
either#<EXPLICIT-BASE-PRONOUN "either" person:THIRD number:SINGULAR gender:NIL case:NOMINATIVE-OR-ACCUSATIVE negative:NIL {100E4682E3}>

Word Class demonstrative-pronoun

Class: spell:demonstrative-pronoun (word, pronoun)

Instances represent demonstrative pronouns, that is shorthand references which highlight an entity that is identifiable from the context.

Examples

there#<EXPLICIT-BASE-DEMONSTRATIVE-PRONOUN "there" person:NIL number:ANY gender:NIL case:NOMINATIVE negative:NIL {100C7ABD73}>
that#<EXPLICIT-BASE-DEMONSTRATIVE-PRONOUN "that" person:NIL number:ANY gender:NIL case:NOMINATIVE negative:NIL {100C793B83}>
here#<EXPLICIT-BASE-DEMONSTRATIVE-PRONOUN "here" person:NIL number:ANY gender:NIL case:NOMINATIVE negative:NIL {10017CCF13}>

Word Class personal-pronoun

Class: spell:personal-pronoun (word, pronoun)

Instances represent personal pronouns, that is shorthand references to a noun which designates a person.

Examples

he#<EXPLICIT-BASE-PERSONAL-PRONOUN "he" person:THIRD number:SINGULAR gender:MASCULINE case:NOMINATIVE negative:NIL {10018DE123}>
her#<EXPLICIT-BASE-PERSONAL-PRONOUN "her" person:THIRD number:SINGULAR gender:FEMININE case:ACCUSATIVE negative:NIL {10018A1023}>
I#<EXPLICIT-BASE-PERSONAL-PRONOUN "I" person:FIRST number:SINGULAR gender:NIL case:NOMINATIVE negative:NIL {100E468E93}>

Word Class possessive-pronoun

Class: spell:possessive-pronoun (word, pronoun)

Instances represent possessive pronouns, that is shorthand references to an object that is possessed by an entity which is identifiable from the context.

The generic function refnumber can be applied to words of this class.

Examples

theirs#<EXPLICIT-BASE-POSSESSIVE-PRONOUN "theirs" person:THIRD number:ANY gender:NIL case:NOMINATIVE negative:NIL refnumber:PLURAL {100C7A00C3}>
its#<EXPLICIT-BASE-POSSESSIVE-PRONOUN "it" person:THIRD number:ANY gender:NIL case:NOMINATIVE negative:NIL refnumber:SINGULAR {100284BAE3}>
his#<EXPLICIT-BASE-POSSESSIVE-PRONOUN "his" person:THIRD number:ANY gender:MASCULINE case:NOMINATIVE negative:NIL refnumber:SINGULAR {100191CA13}>

Word Class reflexive-pronoun

Class: spell:reflexive-pronoun (word, pronoun)

Instances represent possessive pronouns, that is shorthand references that link the object back to the subject which is identifiable from the context.

Examples

yourselves#<EXPLICIT-BASE-REFLEXIVE-PRONOUN "yourselves" person:SECOND number:PLURAL gender:NIL case:NOMINATIVE negative:NIL {100CE88F43}>
yourself#<EXPLICIT-BASE-REFLEXIVE-PRONOUN "yourself" person:SECOND number:SINGULAR gender:NIL case:NOMINATIVE negative:NIL {100CE88ED3}>
thyself#<EXPLICIT-BASE-REFLEXIVE-PRONOUN "thyself" person:SECOND number:SINGULAR gender:NIL case:NOMINATIVE negative:NIL {100C819263}>

Word Class verb

Class: spell:verb (word)

Direct instances represent generic verbs. Also a superclass for more specific verb classes.

Generic Function: spell:infinitive word

Return a keyword which indicates whether and which kind of infinitive word is.

Possible values are nil, :self and :to.

Generic Function: spell:strength word

Return a keyword which indicates the grammatical strength of word.

Only verb instances have the strength property which is either weak or strong. Weak means that the past tense of the verb is formed by adding a suffix while strong means that the past tense form of the verb has a different stem than the infinitive form.

Possible values are :weak and :strong.

Generic Function: spell:contraction word

Return a Boolean which indicates whether word is a contraction of two words.

For instances of the verb class a true value of the contraction property always goes together with a true value of the negative property. In other words these contractions consist of the base verb and the word not as in won t.

The generic function negative can be applied to words of this class.

Generic Function: spell:tense word

Return a keyword which indicates the time of the action for word.

Possible values are nil, :present-simple, :progressive, :past, :perfect-participle, :passive-perfect-participle.

The generic function number can be applied to words of this class.

The generic function person can be applied to words of this class.

Examples

wannaed#<EXPLICIT-BASE-VERB "wanna" person:ANY number:ANY tense:PERFECT-PARTICIPLE negative:NIL contraction:NIL strength:WEAK infinitive:NIL {100CCC6423}>
visaing#<EXPLICIT-BASE-VERB "visa" person:ANY number:ANY tense:PROGRESSIVE negative:NIL contraction:NIL strength:WEAK infinitive:NIL {100CC4B743}>
validating#<EXPLICIT-BASE-VERB "validate" person:ANY number:ANY tense:PROGRESSIVE negative:NIL contraction:NIL strength:WEAK infinitive:NIL {100CB97F03}>

Word Class verb-verb-contraction

Class: spell:verb-verb-contraction (word, verb)

Instances are verbs that are formed as a contraction of two verbs.

Examples

might’ve#<EXPLICIT-BASE-VERB-VERB-CONTRACTION "might have" person:ANY number:ANY tense:PRESENT-SIMPLE negative:NIL contraction:NIL strength:WEAK infinitive:SELF {1002FC7EE3}>
may’ve#<EXPLICIT-BASE-VERB-VERB-CONTRACTION "may have" person:ANY number:ANY tense:PRESENT-SIMPLE negative:NIL contraction:NIL strength:WEAK infinitive:SELF {1002CEDB93}>
could’ve#<EXPLICIT-BASE-VERB-VERB-CONTRACTION "could have" person:ANY number:ANY tense:PRESENT-SIMPLE negative:NIL contraction:NIL strength:WEAK infinitive:SELF {100E468FA3}>

2.3 Dictionary Protocol

Generic Function: spell:entry-count dictionary

Return the number of entries in dictionary.

Example:

(spell:entry-count spell::*english-dictionary*)
⇒ 347488
Generic Function: spell:map-entries function dictionary

Call function for each entry in dictionary.

The lambda-list of function has to be compatible with (spelling word) where word is the word object of the entry and spelling is the spelling of the entry as a string.

spelling is passed as a separate argument because it cannot be obtained from word.

Example:

(prog ((i 0))
  (spell:map-entries (lambda (spelling word)
                       (cond ((<= 7000 (incf i) 7005)
                              (format t "~D ~10A ~A~%" i spelling word))
                             ((> i 10005)
                              (return))))
                     spell::*english-dictionary*))
-| 7000 Highlander #<EXPLICIT-BASE-NOUN "Highlander" number:SINGULAR case:NIL gender:NIL {101ACF7AF3}>
-| 7001 Highlands' #<EXPLICIT-BASE-PROPER-NOUN "Highland" number:PLURAL case:GENITIVE gender:NIL {101AD086E3}>
-| 7002 Highlands  #<EXPLICIT-BASE-PROPER-NOUN "Highland" number:PLURAL case:NIL gender:NIL {101AD087C3}>
-| 7003 Highland   #<EXPLICIT-BASE-PROPER-NOUN "Highland" number:SINGULAR case:NIL gender:NIL {101AD088A3}>
-| 7004 Hilary's   #<EXPLICIT-BASE-PROPER-NOUN "Hilary" number:SINGULAR case:GENITIVE gender:NIL {101AD08983}>
-| 7005 Hilarys'   #<EXPLICIT-BASE-PROPER-NOUN "Hilary" number:PLURAL case:GENITIVE gender:NIL {101AD08A63}>
Generic Function: spell:lookup string dictionary

Return a (possibly empty) list of entries in dictionary the spelling of which matches string.

Example:

(spell:lookup "bright" spell::*english-dictionary*)
⇒ (#<EXPLICIT-BASE-ADVERB "bright" {101B1CE6B3}>
   #<EXPLICIT-BASE-ADJECTIVE "bright" degree:POSITIVE {101B1CE663}>
   #<EXPLICIT-BASE-NOUN "bright" number:SINGULAR case:NIL gender:NIL {101B1CE633}>)
Generic Function: spell:map-similar function string dictionary threshold &key group-by

Call function for each entry in dictionary for which the edit-distance to string is below threshold. The entries are reported in order of increasing edit-distance from string.

The lambda-list of function has to be compatible with either (spelling word distance) if group-by is :entry or (spelling distance) if group-by is :spelling. word is the matching word object, spelling is a string that is the spelling of word (which is not obtainable from word itself) and distance is the edit-distance between spelling and string.

string is the query string and can be of any subtype of cl:string. At the moment, the case of string is left untouched and only dictionary entries that match the case are reported.

dictionary is a dictionary.

threshold is a non-negative integer which controls how similar to string in terms of edit-distance the reported entries have to be.

group-by controls whether word objects are included in calls of function. If group-by is :entry, function is called with three arguments: spelling, word and distance. If group-by is :spelling, function is called with two arguments, spelling and distance. The default is :entry. Note that the value of group-byr influences the number of times function is called since a spelling that corresponds to multiple entries will be reported once for :spelling but multiple times for :entry.

Example:

(spell:map-similar
 (lambda (spelling word distance)
   (format t "~D ~10S ~A~%" distance spelling (class-name (class-of word))))
 "lisp" spell::*english-dictionary* 1)
-| 0 "lisp"     EXPLICIT-BASE-NOUN
-| 0 "lisp"     EXPLICIT-BASE-VERB
-| 1 "limp"     EXPLICIT-BASE-NOUN
-| 1 "limp"     EXPLICIT-BASE-ADJECTIVE
-| 1 "limp"     EXPLICIT-BASE-VERB
-| 1 "lip"      EXPLICIT-BASE-NOUN
-| 1 "lip"      EXPLICIT-BASE-VERB
-| 1 "lisps"    EXPLICIT-BASE-NOUN
-| 1 "lisps"    EXPLICIT-BASE-VERB
-| 1 "list"     EXPLICIT-BASE-NOUN
-| 1 "list"     EXPLICIT-BASE-VERB
-| 1 "wisp"     EXPLICIT-BASE-NOUN
-| 1 "wisp"     EXPLICIT-BASE-VERB
⇒ NIL

With :group-by :spelling

(spell:map-similar
 (lambda (spelling distance)
   (format t "~D ~S~%" distance spelling))
 "lisp" spell::*english-dictionary* 1 :group-by :spelling)
-| 0 "lisp"
-| 1 "lisps"
-| 1 "list"
-| 1 "lip"
-| 1 "limp"
-| 1 "wisp"
⇒ NIL
Generic Function: spell:map-corrections function string dictionary threshold &key variants group-by

Call function for each entry in dictionary for which the edit-distance to a variant of string is below threshold. The entries are reported in order of increasing edit-distance from variants of string.

The lambda-list of function has to be compatible with either (spelling word distance) if group-by is :entry or (spelling distance) if group-by is :spelling. word is the matching word object, spelling is a string that is the spelling of word (which is not obtainable from word itself) and distance is the edit-distance between spelling and one variant of string.

string is the query string and can be of any subtype of cl:string.

dictionary is a dictionary.

threshold is a non-negative integer which controls how similar to a variant of string in terms of edit-distance the reported entries have to be.

variants controls which variants in terms of capitalization and case of string should be considered. If supplied, the value of variants has to be a function the lambda-list of which has to compatible with (continuation string) where string is the string mentioned above and continuation is a function that should be called once for each case-modified variant of string. Note that capitalization and case information should ideally be contained in dictionary entries. The implementation of that improvement would make this parameter unnecessary.

group-by controls whether word objects are included in calls of function. If group-by is :entry, function is called with three arguments, spelling, word and distance. If group-by is :spelling, function is called with two arguments, spelling and distance. The default is :entry. Note that the value of group-by influences the number of times function is called since a spelling that corresponds to multiple entries will be reported once for :spelling but multiple times for :entry.

Examples:

(spell:map-corrections
 (lambda (spelling word distance)
   (format t "~D ~10S ~A~%" distance spelling (class-name (class-of word))))
 "lisp" spell::*english-dictionary* 1)
-| 0 "lisp"     EXPLICIT-BASE-NOUN
-| 0 "lisp"     EXPLICIT-BASE-VERB
-| 1 "lisps"    EXPLICIT-BASE-NOUN
-| 1 "lisps"    EXPLICIT-BASE-VERB
-| 1 "list"     EXPLICIT-BASE-NOUN
-| 1 "list"     EXPLICIT-BASE-VERB
-| 1 "lip"      EXPLICIT-BASE-NOUN
-| 1 "lip"      EXPLICIT-BASE-VERB
-| 1 "limp"     EXPLICIT-BASE-NOUN
-| 1 "limp"     EXPLICIT-BASE-ADJECTIVE
-| 1 "limp"     EXPLICIT-BASE-VERB
-| 1 "wisp"     EXPLICIT-BASE-NOUN
-| 1 "wisp"     EXPLICIT-BASE-VERB
⇒ NIL

(spell:map-corrections
 (lambda (spelling word distance)
   (format t "~D ~10S ~A~%" distance spelling (class-name (class-of word))))
 "lifp" spell::*english-dictionary* 1)
-| 1 "lift"     EXPLICIT-BASE-NOUN
-| 1 "lift"     EXPLICIT-BASE-VERB
-| 1 "life"     EXPLICIT-BASE-NOUN
-| 1 "lip"      EXPLICIT-BASE-NOUN
-| 1 "lip"      EXPLICIT-BASE-VERB
-| 1 "lisp"     EXPLICIT-BASE-NOUN
-| 1 "lisp"     EXPLICIT-BASE-VERB
-| 1 "limp"     EXPLICIT-BASE-NOUN
-| 1 "limp"     EXPLICIT-BASE-ADJECTIVE
-| 1 "limp"     EXPLICIT-BASE-VERB
⇒ NIL
Generic Function: spell:corrections string dictionary threshold &key variants group-by count

Return corrections from dictionary that are within threshold of the misspelled word string. Return two values: a list of corrections and a Boolean which indicates whether string is spelled correctly according to dictionary.

The list of entries which is returned as the first value is ordered according to increasing edit-distance between string and the respective entry. Depending on group-by (see below), entries in the list are either strings that are spellings of entries in dictionary or pairs of the form (word . spelling). If the second return value is true, which indicates that string is spelled correctly, the first return value includes one or more entries which correspond to string.

dictionary is a dictionary.

threshold is a non-negative integer which controls how similar to a variant of string in terms of edit-distance the reported entries have to be.

variants controls which variants in terms of capitalization and case of string should be considered. If supplied, the value of variants has to be a function the lambda-list of which has to compatible with (continuation string) where string is the string mentioned above and continuation is a function that should be called once for each case-modified variant of string. Note that capitalization and case information should ideally be contained in dictionary entries. The implementation of that improvement would make this parameter unnecessary.

group-by controls whether word objects are included in elements of the returned list. If group-by is :entry, elements are of the form (word . spelling). If group-by is :spelling, elements are strings and each string is one spelling. The default is :entry. Note that the value of group-by influences the number returned elements since a spelling that corresponds to multiple entries will be reported once for :spelling but multiple times for :entry.

If supplied, count limits the maximum number of entries that are returned as the first value.

Examples:

(spell:corrections "lisp" spell::*english-dictionary* 0 :group-by :spelling)
⇒ ("lisp") T

(spell:corrections "lifp" spell::*english-dictionary* 1 :group-by :spelling)
⇒ ("lift" "life" "lip" "lisp" "limp") NIL

(spell:corrections "lisp" spell::*english-dictionary* 2 :group-by :spelling :count 3)
⇒ ("lisp" "lisps" "list") T
Generic Function: spell:insert word string dictionary

Insert word into dictionary as an entry for string.

word must be an instance of word.

dictionary must be a mutable dictionary. A “raw” dictionary is mutable, a “compacted” dictionary is not mutable.

Generic Function: spell:load-dictionary source &key into

Turn the word information in source into into or a new dictionary and return that dictionary.

source can be a stream, a string or pathname or some other sequence. If source is a stream, it must be an open character input stream. The word information is read from the stream. If source is a string a pathname it is a designator for a file that should be opened and read. If source is some other sequence, the sequence elements must be of the types discussed above. The word information from all source is combined into one dictionary in that case.

If supplied, into must be a mutable dictionary into which the word information should be loaded. The function returns into in that case. Otherwise the function creates a new dictionary, loads the word information into it and returns it.


Concept index


Function and macro and variable and type index

Index EntrySection

S
spell:adjectiveWord Protocols
spell:adverbWord Protocols
spell:articleWord Protocols
spell:baseWord Protocols
spell:caseWord Protocols
spell:conjunctionWord Protocols
spell:contractionWord Protocols
spell:correctionsDictionary Protocol
spell:degreeWord Protocols
spell:demonstrative-adjectiveWord Protocols
spell:demonstrative-pronounWord Protocols
spell:determinateWord Protocols
spell:determinerWord Protocols
spell:english-check-paragraphEnglish Protocol
spell:english-correctionsEnglish Protocol
spell:english-lookupEnglish Protocol
spell:entry-countDictionary Protocol
spell:genderWord Protocols
spell:infinitiveWord Protocols
spell:insertDictionary Protocol
spell:interjectionWord Protocols
spell:interrogative-adjectiveWord Protocols
spell:load-dictionaryDictionary Protocol
spell:lookupDictionary Protocol
spell:map-correctionsDictionary Protocol
spell:map-entriesDictionary Protocol
spell:map-similarDictionary Protocol
spell:negativeWord Protocols
spell:nounWord Protocols
spell:noun-verb-contractionWord Protocols
spell:numberWord Protocols
spell:personWord Protocols
spell:personal-pronounWord Protocols
spell:possessive-adjectiveWord Protocols
spell:possessive-pronounWord Protocols
spell:prepositionWord Protocols
spell:pronounWord Protocols
spell:proper-nounWord Protocols
spell:quantifierWord Protocols
spell:reflexive-pronounWord Protocols
spell:refnumberWord Protocols
spell:strengthWord Protocols
spell:subordinateWord Protocols
spell:tenseWord Protocols
spell:verbWord Protocols
spell:verb-verb-contractionWord Protocols
spell:wordWord Protocols


Changelog

Release 0.3 (not yet released)
  • A new protocol enables clients to find dictionary entries that are similar to a given string or corrections for a given misspelled word.

    The following new functions provide increasingly abstract functionality for enumerating similar words and corrections: spell:map-similar, spell:map-corrections and spell:corrections.

    For convenience, the function spell:english-corrections automatically uses the English dictionary and considers the appropriate case variants of the supplied string.

  • Documentation is now available in the documentation directory.
  • The new function map-entries calls a supplied function for each entry in a given dictionary.
Release 0.2 (2025-01-05)
  • The README.org file now uses the org-mode format. The examples have been updated.
  • The spell/simple system is now an alias for the spell system since the improved memory footprint makes the former unnecessary.
  • Compilation and loading times as well as memory footprint have been significantly reduced.
  • Dictionaries can now be built from multiple source files. Additional words are now loaded from data/english-additions.txt.
Release 0.1 (2024-12-20)
  • Initial release with basic lookup for the English dictionary but slow compilation and loading and a big memory footprint.