/*
Copyright 2010-2012 by Bits and Pixels, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* The Adjective class determines superlative and comparative forms of
* adjectives. For example, "fast" is an attribute that may be applied
* to a noun "car", but questions involving car and fast may ask, for
* instance "is this car faster than that car?". The speech recognizer
* as well as the interpreter needs to know that the user may ask about
* "faster" or "fastest" instead of "fast." Adjective uses some rules
* about forming those variants from the original adjective.
*/
package com.jaivox.interpreter;
// using rules from
// http://www.eflnet.com/tutorials/adjcompsup.php
import java.io.*;
import java.util.*;
import com.jaivox.util.Log;
/**
* The Adjective class determines superlative and comparative forms of
* adjectives. For example, "fast" is an attribute that may be applied
* to a noun "car", but questions involving car and fast may ask, for
* instance "is this car faster than that car?". The speech recognizer
* as well as the interpreter needs to know that the user may ask about
* "faster" or "fastest" instead of "fast." Adjective uses some rules
* about forming those variants from the original adjective.
*/
public class Adjective {
String vowels = "aeiouy";
public Adjective () {
}
/**
* Analyze a word, assumed to be an adjective to determine its normal,
* comparative and superlative forms using some rules about English. The
* analysis does not work in all cases due to special cases in English.
@param word
@return a string containing three forms of the adjective
*/
public String analyze (String word) {
String in = word;
int k = countsyllables (in);
// System.out.println (in+" "+k+" syllables");
String s = analyzespecial (in);
if (s == null) {
if (k == 1) s = analyzeone (in);
else if (k == 2) s = analyzetwo (in);
else s = analyzemore (in);
}
return s;
}
String analyzespecial (String word) {
if (word.equals ("good")) return "good, better, best";
else if (word.equals ("bad")) return "bad, worse, worst";
else if (word.equals ("far")) return "far, farther, farthest";
else if (word.equals ("little")) return "little, less, least";
else if (word.equals ("many")) return "many, more, most";
else if (word.equals ("slow")) return "slow, slower, slowest";
else return null;
}
String analyzeone (String word) {
StringBuffer sb = new StringBuffer ();
sb.append (word);
// if it ends with e, just add r for comparative st for superlative
if (word.endsWith ("e")) {
sb.append (", "+word+"r");
sb.append (", "+word+"st");
String s = new String (sb);
return s;
}
int n = word.length ();
// if it ends with y change the ending to i and add er or est
if (word.endsWith ("y")) {
String stub = word.substring (0, n-1);
sb.append (", "+stub+"ier");
sb.append (", "+stub+"iest");
String s = new String (sb);
return s;
}
char c = word.charAt (n-2);
char d = word.charAt (n-1);
// if it ends with VC double the C and add er or est
if (isvowel (c) && iscons (d)) {
sb.append (", "+word);
sb.append (d);
sb.append ("er");
sb.append (", "+word);
sb.append (d);
sb.append ("est");
String s = new String (sb);
return s;
}
// otherwise just add er or est
sb.append (", "+word+"er");
sb.append (", "+word+"est");
String s = new String (sb);
return s;
}
String analyzetwo (String word) {
StringBuffer sb = new StringBuffer ();
sb.append (word);
// if it ends with y change the ending to i and add er or est
int n = word.length ();
if (word.endsWith ("y")) {
String stub = word.substring (0, n-1);
sb.append (", "+stub+"ier");
sb.append (", "+stub+"iest");
String s = new String (sb);
return s;
}
// if it ends with er, le or ow, just add er or est
else if (word.endsWith ("–er") || word.endsWith ("le") || word.endsWith ("ow")) {
sb.append (", "+word+"er");
sb.append (", "+word+"est");
String s = new String (sb);
return s;
}
else {
return analyzemore (word);
}
}
String analyzemore (String word) {
StringBuffer sb = new StringBuffer ();
sb.append (word);
sb.append (", more "+word);
sb.append (", most "+word);
String s = new String (sb);
return s;
}
int getinteger (String word) {
try {
int v = Integer.parseInt (word);
return v;
}
catch (Exception e) {
return -1;
}
}
int countsyllables (String word) {
int count = 0;
// count vowel groups between consonants
int n = word.length ();
boolean seencons = true;
// just ignore last letter like e in nice, but allow multiple vowels at end
for (int i=0; i<n-1; i++) {
char c = word.charAt (i);
if (iscons (c)) {
seencons = true;
continue;
}
else {
if (isvowel (c)) {
if (seencons) count++;
seencons = false;
continue;
}
}
}
return count;
}
boolean isletter (char c) {
if (c >= 'a' && c <= 'z') return true;
else return false;
}
boolean isvowel (char c) {
int pos = vowels.indexOf (c);
if (pos == -1) return false;
else return true;
}
boolean iscons (char c) {
if (isletter (c) && !isvowel (c)) return true;
else return false;
}
};