/** * (c) 2000-2011 Carlos G�mez Rodr�guez, todos los derechos reservados / all rights reserved. * Licencia en license.txt / License in license.txt * File created: 20/03/2011 13:49:03 */ package eu.irreality.age.spell; import java.util.StringTokenizer; import eu.irreality.age.NaturalLanguage; import eu.irreality.age.World; /** * @author carlos * * Note that this doesn't implement SpellingCorrector because it is a higher level class * that uses correctors internally. */ public class AGESpellChecker { World w; NaturalLanguage lang; SpellingCorrector verbCorrector; ReferenceNameCorrector nameCorrector; private static int MINLENGTH = 3; public AGESpellChecker ( World w , NaturalLanguage lang ) { this.w = w; this.lang = lang; verbCorrector = lang.getVerbSpellingCorrector(); nameCorrector = lang.initNameCorrector(w); } /** * If for some reason it is necessary to make modifications to word lists, it will be necessary to rebuild * the corrector for removals to take place (words can be added on the fly via the SpellingCorrector * interface, but not removed) */ public void rebuild() { verbCorrector = lang.getVerbSpellingCorrector(); nameCorrector = lang.initNameCorrector(w); } /** * Changes a verb/name to a correct one. Can use dictionary of verbs, names, or both. * @param word The word that is to be corrected. * @param useVerbs use the verb dictionary if true. * @param useNames use the name dictionary if true. * @param caseInsensitive make the correction case-insensitive. Note that this makes the result (if correction kicks in) always lowercase, i.e. "COSER" and "COZER" will be corrected to "coser". * @return */ public String correctVerbOrName ( String w , boolean useVerbs , boolean useNames , boolean caseInsensitive ) { //TODO Eventually make this consistent, i.e., if original word was uppercase, return uppercase correction. /* StringTokenizer st = new StringTokenizer ( commandString ); if ( !st.hasMoreTokens() ) return commandString; String firstWord = st.nextToken(); */ String word = w; if ( caseInsensitive ) word = w.toLowerCase(); String corrected = w; if ( word.length() >= MINLENGTH ) { Correction verbCorrection = verbCorrector.getBestCorrection(word); Correction nameCorrection = nameCorrector.getBestCorrection(word); if ( useVerbs && verbCorrection != null && verbCorrection.getDistance() < 0.01 ) corrected = verbCorrection.getWord(); else if ( useNames && nameCorrection != null && nameCorrection.getDistance() < 0.01 ) corrected = nameCorrection.getWord(); else if ( useVerbs && verbCorrection != null && verbCorrection.getDistance() < 1.01 ) corrected = verbCorrection.getWord(); else if ( useNames && nameCorrection != null && nameCorrection.getDistance() < 1.01 ) corrected = nameCorrection.getWord(); } else { //we don't correct anything for words of length <= minlength, but if we recognized the word as a verb, we set lowercase for consistency. //(not for nouns, we don't have data about which words of length <= 2 appear in reference names) if ( useVerbs && lang.isVerb(word) ) corrected = word; } /* if ( corrected != null ) word = corrected; if ( !st.hasMoreTokens() ) return firstWord; else return firstWord + " " + st.nextToken(""); */ return corrected; } /** * Performs verb correction on the first word in the string, * verb/name correction on the rest. * @param s Command string to correct, example "mriar cocche". * @return Corrected string, example "mirar coche". */ public String correctCommandString ( String s ) { StringTokenizer st = new StringTokenizer ( s ); StringBuffer result = new StringBuffer(); if ( !st.hasMoreTokens() ) return s; String firstWord = st.nextToken(); String correctedFirstWord = correctVerbOrName(firstWord,true,true,true); result.append(correctedFirstWord); while ( st.hasMoreTokens() ) { String nextWord = st.nextToken(); String correctedNextWord = correctVerbOrName(nextWord,false,true,true); result.append(" "); result.append(correctedNextWord); } return result.toString(); } /** * Adds a new name to the names known by the spell checker. * This can be used by games that add reference names dynamically. * @param s The name to be added. */ public void addNewName ( String s ) { nameCorrector.addReferenceName(s); } }