#include <stdint.h>
#include <stdlib.h>
#include "el_runtime.h"

el_val_t str_ends(el_val_t s, el_val_t suf);
el_val_t str_last_char(el_val_t s);
el_val_t str_last2(el_val_t s);
el_val_t str_last3(el_val_t s);
el_val_t str_drop_last(el_val_t s, el_val_t n);
el_val_t is_vowel(el_val_t c);
el_val_t morph_apply_suffix(el_val_t base, el_val_t suffix);
el_val_t en_irregular_plural(el_val_t word);
el_val_t en_irregular_singular(el_val_t word);
el_val_t en_irregular_verb(el_val_t base);
el_val_t en_verb_3sg(el_val_t base);
el_val_t en_should_double_final(el_val_t base);
el_val_t en_verb_past(el_val_t base);
el_val_t en_verb_gerund(el_val_t base);
el_val_t en_pluralize_regular(el_val_t singular);
el_val_t en_verb_form(el_val_t base, el_val_t tense, el_val_t person, el_val_t number);
el_val_t agree_determiner(el_val_t det, el_val_t noun);
el_val_t morph_pluralize(el_val_t noun, el_val_t profile);
el_val_t morph_map_canonical(el_val_t verb, el_val_t code);
el_val_t morph_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number, el_val_t profile);
el_val_t morph_inflect(el_val_t word, el_val_t features, el_val_t profile);
el_val_t pluralize(el_val_t singular);
el_val_t singularize(el_val_t plural);
el_val_t verb_form(el_val_t base, el_val_t tense, el_val_t person, el_val_t number);
el_val_t irregular_plural(el_val_t word);
el_val_t irregular_singular(el_val_t word);
el_val_t ja_verb_group(el_val_t dict_form);
el_val_t ja_ichidan_stem(el_val_t dict_form);
el_val_t ja_godan_stem_change(el_val_t dict_form, el_val_t row);
el_val_t ja_conjugate(el_val_t dict_form, el_val_t form);
el_val_t ja_particle(el_val_t gram_case);
el_val_t ja_noun_phrase(el_val_t noun, el_val_t gram_case);
el_val_t ja_question_particle(void);
el_val_t ja_make_question(el_val_t sentence);

el_val_t ja_verb_group(el_val_t dict_form) {
  if (str_eq(dict_form, EL_STR("\xe3\x81\x99\xe3\x82\x8b"))) {
    return EL_STR("irregular");
  }
  if (str_eq(dict_form, EL_STR("\xe3\x81\x8f\xe3\x82\x8b"))) {
    return EL_STR("irregular");
  }
  if (str_eq(dict_form, EL_STR("\xe3\x81\x8f\xe3\x82\x8b"))) {
    return EL_STR("irregular");
  }
  if (str_eq(dict_form, EL_STR("\xe3\x81\x84\xe3\x82\x8b"))) {
    return EL_STR("irregular");
  }
  if (str_eq(dict_form, EL_STR("\xe3\x81\x82\xe3\x82\x8b"))) {
    return EL_STR("irregular");
  }
  if (str_eq(dict_form, EL_STR("\xe3\x81\xa0"))) {
    return EL_STR("irregular");
  }
  if (str_eq(dict_form, EL_STR("suru"))) {
    return EL_STR("irregular");
  }
  if (str_eq(dict_form, EL_STR("kuru"))) {
    return EL_STR("irregular");
  }
  if (str_eq(dict_form, EL_STR("iru"))) {
    return EL_STR("irregular");
  }
  if (str_eq(dict_form, EL_STR("aru"))) {
    return EL_STR("irregular");
  }
  if (str_eq(dict_form, EL_STR("da"))) {
    return EL_STR("irregular");
  }
  if (str_ends_with(dict_form, EL_STR("\xe3\x82\x8b"))) {
    return EL_STR("ichidan");
  }
  if (str_ends_with(dict_form, EL_STR("eru"))) {
    return EL_STR("ichidan");
  }
  if (str_ends_with(dict_form, EL_STR("iru"))) {
    return EL_STR("ichidan");
  }
  return EL_STR("godan");
  return 0;
}

el_val_t ja_ichidan_stem(el_val_t dict_form) {
  if (str_ends_with(dict_form, EL_STR("\xe3\x82\x8b"))) {
    el_val_t n = str_len(dict_form);
    return str_drop_last(dict_form, 1);
  }
  if (str_ends_with(dict_form, EL_STR("ru"))) {
    el_val_t n = str_len(dict_form);
    return str_slice(dict_form, 0, (n - 2));
  }
  return dict_form;
  return 0;
}

el_val_t ja_godan_stem_change(el_val_t dict_form, el_val_t row) {
  el_val_t n = str_len(dict_form);
  if (n == 0) {
    return dict_form;
  }
  if (str_eq(row, EL_STR("i"))) {
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x8f"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x8d"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x90"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x8e"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x99"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x97"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xa4"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\xa1"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xac"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\xab"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xb6"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\xb3"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x82\x80"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\xbf"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x82\x8b"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x82\x8a"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x86"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x84"));
    }
    if (str_ends_with(dict_form, EL_STR("ku"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("ki"));
    }
    if (str_ends_with(dict_form, EL_STR("gu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("gi"));
    }
    if (str_ends_with(dict_form, EL_STR("su"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("shi"));
    }
    if (str_ends_with(dict_form, EL_STR("tsu"))) {
      return el_str_concat(str_drop_last(dict_form, 3), EL_STR("chi"));
    }
    if (str_ends_with(dict_form, EL_STR("nu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("ni"));
    }
    if (str_ends_with(dict_form, EL_STR("bu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("bi"));
    }
    if (str_ends_with(dict_form, EL_STR("mu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("mi"));
    }
    if (str_ends_with(dict_form, EL_STR("ru"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("ri"));
    }
    if (str_ends_with(dict_form, EL_STR("u"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("i"));
    }
    return dict_form;
  }
  if (str_eq(row, EL_STR("a"))) {
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x8f"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x8b"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x90"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x8c"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x99"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x95"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xa4"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x9f"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xac"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\xaa"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xb6"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\xb0"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x82\x80"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\xbe"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x82\x8b"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x82\x89"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x86"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x82\x8f"));
    }
    if (str_ends_with(dict_form, EL_STR("ku"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("ka"));
    }
    if (str_ends_with(dict_form, EL_STR("gu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("ga"));
    }
    if (str_ends_with(dict_form, EL_STR("su"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("sa"));
    }
    if (str_ends_with(dict_form, EL_STR("tsu"))) {
      return el_str_concat(str_drop_last(dict_form, 3), EL_STR("ta"));
    }
    if (str_ends_with(dict_form, EL_STR("nu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("na"));
    }
    if (str_ends_with(dict_form, EL_STR("bu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("ba"));
    }
    if (str_ends_with(dict_form, EL_STR("mu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("ma"));
    }
    if (str_ends_with(dict_form, EL_STR("ru"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("ra"));
    }
    if (str_ends_with(dict_form, EL_STR("u"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("wa"));
    }
    return dict_form;
  }
  if (str_eq(row, EL_STR("te"))) {
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x8f"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x84"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x90"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x84"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x99"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x97"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xa4"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\xa3"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xac"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x82\x93"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xb6"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x82\x93"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x82\x80"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x82\x93"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x82\x8b"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\xa3"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x86"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\xa3"));
    }
    if (str_ends_with(dict_form, EL_STR("ku"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("i"));
    }
    if (str_ends_with(dict_form, EL_STR("gu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("i"));
    }
    if (str_ends_with(dict_form, EL_STR("su"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("shi"));
    }
    if (str_ends_with(dict_form, EL_STR("tsu"))) {
      return el_str_concat(str_drop_last(dict_form, 3), EL_STR("tt"));
    }
    if (str_ends_with(dict_form, EL_STR("nu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("n"));
    }
    if (str_ends_with(dict_form, EL_STR("bu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("n"));
    }
    if (str_ends_with(dict_form, EL_STR("mu"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("n"));
    }
    if (str_ends_with(dict_form, EL_STR("ru"))) {
      return el_str_concat(str_drop_last(dict_form, 2), EL_STR("tt"));
    }
    if (str_ends_with(dict_form, EL_STR("u"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("tt"));
    }
    return dict_form;
  }
  return dict_form;
  return 0;
}

el_val_t ja_conjugate(el_val_t dict_form, el_val_t form) {
  el_val_t group = ja_verb_group(dict_form);
  if (str_eq(group, EL_STR("irregular"))) {
    if (str_eq(dict_form, EL_STR("\xe3\x81\x99\xe3\x82\x8b"))) {
      if (str_eq(form, EL_STR("present"))) {
        return EL_STR("\xe3\x81\x99\xe3\x82\x8b");
      }
      if (str_eq(form, EL_STR("past"))) {
        return EL_STR("\xe3\x81\x97\xe3\x81\x9f");
      }
      if (str_eq(form, EL_STR("negative"))) {
        return EL_STR("\xe3\x81\x97\xe3\x81\xaa\xe3\x81\x84");
      }
      if (str_eq(form, EL_STR("volitional"))) {
        return EL_STR("\xe3\x81\x97\xe3\x82\x88\xe3\x81\x86");
      }
      if (str_eq(form, EL_STR("polite"))) {
        return EL_STR("\xe3\x81\x97\xe3\x81\xbe\xe3\x81\x99");
      }
      if (str_eq(form, EL_STR("polite-past"))) {
        return EL_STR("\xe3\x81\x97\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f");
      }
      if (str_eq(form, EL_STR("polite-neg"))) {
        return EL_STR("\xe3\x81\x97\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93");
      }
      if (str_eq(form, EL_STR("te"))) {
        return EL_STR("\xe3\x81\x97\xe3\x81\xa6");
      }
      return dict_form;
    }
    if (str_eq(dict_form, EL_STR("suru"))) {
      if (str_eq(form, EL_STR("present"))) {
        return EL_STR("suru");
      }
      if (str_eq(form, EL_STR("past"))) {
        return EL_STR("shita");
      }
      if (str_eq(form, EL_STR("negative"))) {
        return EL_STR("shinai");
      }
      if (str_eq(form, EL_STR("volitional"))) {
        return EL_STR("shiyou");
      }
      if (str_eq(form, EL_STR("polite"))) {
        return EL_STR("shimasu");
      }
      if (str_eq(form, EL_STR("polite-past"))) {
        return EL_STR("shimashita");
      }
      if (str_eq(form, EL_STR("polite-neg"))) {
        return EL_STR("shimasen");
      }
      if (str_eq(form, EL_STR("te"))) {
        return EL_STR("shite");
      }
      return dict_form;
    }
    if (str_eq(dict_form, EL_STR("\xe3\x81\x8f\xe3\x82\x8b"))) {
      if (str_eq(form, EL_STR("present"))) {
        return EL_STR("\xe3\x81\x8f\xe3\x82\x8b");
      }
      if (str_eq(form, EL_STR("past"))) {
        return EL_STR("\xe3\x81\x8d\xe3\x81\x9f");
      }
      if (str_eq(form, EL_STR("negative"))) {
        return EL_STR("\xe3\x81\x93\xe3\x81\xaa\xe3\x81\x84");
      }
      if (str_eq(form, EL_STR("volitional"))) {
        return EL_STR("\xe3\x81\x93\xe3\x82\x88\xe3\x81\x86");
      }
      if (str_eq(form, EL_STR("polite"))) {
        return EL_STR("\xe3\x81\x8d\xe3\x81\xbe\xe3\x81\x99");
      }
      if (str_eq(form, EL_STR("polite-past"))) {
        return EL_STR("\xe3\x81\x8d\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f");
      }
      if (str_eq(form, EL_STR("polite-neg"))) {
        return EL_STR("\xe3\x81\x8d\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93");
      }
      if (str_eq(form, EL_STR("te"))) {
        return EL_STR("\xe3\x81\x8d\xe3\x81\xa6");
      }
      return dict_form;
    }
    if (str_eq(dict_form, EL_STR("kuru"))) {
      if (str_eq(form, EL_STR("present"))) {
        return EL_STR("kuru");
      }
      if (str_eq(form, EL_STR("past"))) {
        return EL_STR("kita");
      }
      if (str_eq(form, EL_STR("negative"))) {
        return EL_STR("konai");
      }
      if (str_eq(form, EL_STR("volitional"))) {
        return EL_STR("koyou");
      }
      if (str_eq(form, EL_STR("polite"))) {
        return EL_STR("kimasu");
      }
      if (str_eq(form, EL_STR("polite-past"))) {
        return EL_STR("kimashita");
      }
      if (str_eq(form, EL_STR("polite-neg"))) {
        return EL_STR("kimasen");
      }
      if (str_eq(form, EL_STR("te"))) {
        return EL_STR("kite");
      }
      return dict_form;
    }
    if (str_eq(dict_form, EL_STR("\xe3\x81\x84\xe3\x82\x8b"))) {
      if (str_eq(form, EL_STR("present"))) {
        return EL_STR("\xe3\x81\x84\xe3\x82\x8b");
      }
      if (str_eq(form, EL_STR("past"))) {
        return EL_STR("\xe3\x81\x84\xe3\x81\x9f");
      }
      if (str_eq(form, EL_STR("negative"))) {
        return EL_STR("\xe3\x81\x84\xe3\x81\xaa\xe3\x81\x84");
      }
      if (str_eq(form, EL_STR("volitional"))) {
        return EL_STR("\xe3\x81\x84\xe3\x82\x88\xe3\x81\x86");
      }
      if (str_eq(form, EL_STR("polite"))) {
        return EL_STR("\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99");
      }
      if (str_eq(form, EL_STR("polite-past"))) {
        return EL_STR("\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f");
      }
      if (str_eq(form, EL_STR("polite-neg"))) {
        return EL_STR("\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93");
      }
      if (str_eq(form, EL_STR("te"))) {
        return EL_STR("\xe3\x81\x84\xe3\x81\xa6");
      }
      return dict_form;
    }
    if (str_eq(dict_form, EL_STR("iru"))) {
      if (str_eq(form, EL_STR("present"))) {
        return EL_STR("iru");
      }
      if (str_eq(form, EL_STR("past"))) {
        return EL_STR("ita");
      }
      if (str_eq(form, EL_STR("negative"))) {
        return EL_STR("inai");
      }
      if (str_eq(form, EL_STR("volitional"))) {
        return EL_STR("iyou");
      }
      if (str_eq(form, EL_STR("polite"))) {
        return EL_STR("imasu");
      }
      if (str_eq(form, EL_STR("polite-past"))) {
        return EL_STR("imashita");
      }
      if (str_eq(form, EL_STR("polite-neg"))) {
        return EL_STR("imasen");
      }
      if (str_eq(form, EL_STR("te"))) {
        return EL_STR("ite");
      }
      return dict_form;
    }
    if (str_eq(dict_form, EL_STR("\xe3\x81\x82\xe3\x82\x8b"))) {
      if (str_eq(form, EL_STR("present"))) {
        return EL_STR("\xe3\x81\x82\xe3\x82\x8b");
      }
      if (str_eq(form, EL_STR("past"))) {
        return EL_STR("\xe3\x81\x82\xe3\x81\xa3\xe3\x81\x9f");
      }
      if (str_eq(form, EL_STR("negative"))) {
        return EL_STR("\xe3\x81\xaa\xe3\x81\x84");
      }
      if (str_eq(form, EL_STR("volitional"))) {
        return EL_STR("\xe3\x81\x82\xe3\x82\x8d\xe3\x81\x86");
      }
      if (str_eq(form, EL_STR("polite"))) {
        return EL_STR("\xe3\x81\x82\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99");
      }
      if (str_eq(form, EL_STR("polite-past"))) {
        return EL_STR("\xe3\x81\x82\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f");
      }
      if (str_eq(form, EL_STR("polite-neg"))) {
        return EL_STR("\xe3\x81\x82\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93");
      }
      if (str_eq(form, EL_STR("te"))) {
        return EL_STR("\xe3\x81\x82\xe3\x81\xa3\xe3\x81\xa6");
      }
      return dict_form;
    }
    if (str_eq(dict_form, EL_STR("aru"))) {
      if (str_eq(form, EL_STR("present"))) {
        return EL_STR("aru");
      }
      if (str_eq(form, EL_STR("past"))) {
        return EL_STR("atta");
      }
      if (str_eq(form, EL_STR("negative"))) {
        return EL_STR("nai");
      }
      if (str_eq(form, EL_STR("volitional"))) {
        return EL_STR("arou");
      }
      if (str_eq(form, EL_STR("polite"))) {
        return EL_STR("arimasu");
      }
      if (str_eq(form, EL_STR("polite-past"))) {
        return EL_STR("arimashita");
      }
      if (str_eq(form, EL_STR("polite-neg"))) {
        return EL_STR("arimasen");
      }
      if (str_eq(form, EL_STR("te"))) {
        return EL_STR("atte");
      }
      return dict_form;
    }
    if (str_eq(dict_form, EL_STR("\xe3\x81\xa0"))) {
      if (str_eq(form, EL_STR("present"))) {
        return EL_STR("\xe3\x81\xa0");
      }
      if (str_eq(form, EL_STR("past"))) {
        return EL_STR("\xe3\x81\xa0\xe3\x81\xa3\xe3\x81\x9f");
      }
      if (str_eq(form, EL_STR("negative"))) {
        return EL_STR("\xe3\x81\xa7\xe3\x81\xaf\xe3\x81\xaa\xe3\x81\x84");
      }
      if (str_eq(form, EL_STR("volitional"))) {
        return EL_STR("\xe3\x81\xa0\xe3\x82\x8d\xe3\x81\x86");
      }
      if (str_eq(form, EL_STR("polite"))) {
        return EL_STR("\xe3\x81\xa7\xe3\x81\x99");
      }
      if (str_eq(form, EL_STR("polite-past"))) {
        return EL_STR("\xe3\x81\xa7\xe3\x81\x97\xe3\x81\x9f");
      }
      if (str_eq(form, EL_STR("polite-neg"))) {
        return EL_STR("\xe3\x81\xa7\xe3\x81\xaf\xe3\x81\x82\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93");
      }
      if (str_eq(form, EL_STR("te"))) {
        return EL_STR("\xe3\x81\xa7");
      }
      return dict_form;
    }
    if (str_eq(dict_form, EL_STR("da"))) {
      if (str_eq(form, EL_STR("present"))) {
        return EL_STR("da");
      }
      if (str_eq(form, EL_STR("past"))) {
        return EL_STR("datta");
      }
      if (str_eq(form, EL_STR("negative"))) {
        return EL_STR("dewanai");
      }
      if (str_eq(form, EL_STR("volitional"))) {
        return EL_STR("darou");
      }
      if (str_eq(form, EL_STR("polite"))) {
        return EL_STR("desu");
      }
      if (str_eq(form, EL_STR("polite-past"))) {
        return EL_STR("deshita");
      }
      if (str_eq(form, EL_STR("polite-neg"))) {
        return EL_STR("dewaarimarsen");
      }
      if (str_eq(form, EL_STR("te"))) {
        return EL_STR("de");
      }
      return dict_form;
    }
    return dict_form;
  }
  if (str_eq(group, EL_STR("ichidan"))) {
    el_val_t stem = ja_ichidan_stem(dict_form);
    if (str_eq(form, EL_STR("present"))) {
      return dict_form;
    }
    if (str_eq(form, EL_STR("past"))) {
      return el_str_concat(stem, EL_STR("\xe3\x81\x9f"));
    }
    if (str_eq(form, EL_STR("negative"))) {
      return el_str_concat(stem, EL_STR("\xe3\x81\xaa\xe3\x81\x84"));
    }
    if (str_eq(form, EL_STR("volitional"))) {
      return el_str_concat(stem, EL_STR("\xe3\x82\x88\xe3\x81\x86"));
    }
    if (str_eq(form, EL_STR("polite"))) {
      return el_str_concat(stem, EL_STR("\xe3\x81\xbe\xe3\x81\x99"));
    }
    if (str_eq(form, EL_STR("polite-past"))) {
      return el_str_concat(stem, EL_STR("\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f"));
    }
    if (str_eq(form, EL_STR("polite-neg"))) {
      return el_str_concat(stem, EL_STR("\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93"));
    }
    if (str_eq(form, EL_STR("te"))) {
      return el_str_concat(stem, EL_STR("\xe3\x81\xa6"));
    }
    return dict_form;
  }
  if (str_eq(form, EL_STR("present"))) {
    return dict_form;
  }
  if (str_eq(form, EL_STR("polite"))) {
    el_val_t istem = ja_godan_stem_change(dict_form, EL_STR("i"));
    return el_str_concat(istem, EL_STR("\xe3\x81\xbe\xe3\x81\x99"));
  }
  if (str_eq(form, EL_STR("polite-past"))) {
    el_val_t istem = ja_godan_stem_change(dict_form, EL_STR("i"));
    return el_str_concat(istem, EL_STR("\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x9f"));
  }
  if (str_eq(form, EL_STR("polite-neg"))) {
    el_val_t istem = ja_godan_stem_change(dict_form, EL_STR("i"));
    return el_str_concat(istem, EL_STR("\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93"));
  }
  if (str_eq(form, EL_STR("negative"))) {
    el_val_t astem = ja_godan_stem_change(dict_form, EL_STR("a"));
    return el_str_concat(astem, EL_STR("\xe3\x81\xaa\xe3\x81\x84"));
  }
  if (str_eq(form, EL_STR("volitional"))) {
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x86"))) {
      return el_str_concat(str_drop_last(dict_form, 1), EL_STR("\xe3\x81\x8a\xe3\x81\x86"));
    }
    el_val_t istem = ja_godan_stem_change(dict_form, EL_STR("i"));
    return el_str_concat(istem, EL_STR("\xe3\x82\x8d\xe3\x81\x86"));
  }
  if (str_eq(form, EL_STR("te"))) {
    el_val_t tstem = ja_godan_stem_change(dict_form, EL_STR("te"));
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x90"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x81\x84\xe3\x81\xa7"));
    }
    if (str_ends_with(dict_form, EL_STR("gu"))) {
      return el_str_concat(tstem, EL_STR("ide"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xac"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x82\x93\xe3\x81\xa7"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xb6"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x82\x93\xe3\x81\xa7"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x82\x80"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x82\x93\xe3\x81\xa7"));
    }
    if (str_ends_with(dict_form, EL_STR("nu"))) {
      return el_str_concat(tstem, EL_STR("nde"));
    }
    if (str_ends_with(dict_form, EL_STR("bu"))) {
      return el_str_concat(tstem, EL_STR("nde"));
    }
    if (str_ends_with(dict_form, EL_STR("mu"))) {
      return el_str_concat(tstem, EL_STR("nde"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x99"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x81\x97\xe3\x81\xa6"));
    }
    if (str_ends_with(dict_form, EL_STR("su"))) {
      return el_str_concat(tstem, EL_STR("shite"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x8f"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x81\xa6"));
    }
    if (str_ends_with(dict_form, EL_STR("ku"))) {
      return el_str_concat(tstem, EL_STR("te"));
    }
    return el_str_concat(tstem, EL_STR("\xe3\x81\xa6"));
  }
  if (str_eq(form, EL_STR("past"))) {
    el_val_t tstem = ja_godan_stem_change(dict_form, EL_STR("te"));
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x90"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x81\x84\xe3\x81\xa0"));
    }
    if (str_ends_with(dict_form, EL_STR("gu"))) {
      return el_str_concat(tstem, EL_STR("ida"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xac"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x82\x93\xe3\x81\xa0"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\xb6"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x82\x93\xe3\x81\xa0"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x82\x80"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x82\x93\xe3\x81\xa0"));
    }
    if (str_ends_with(dict_form, EL_STR("nu"))) {
      return el_str_concat(tstem, EL_STR("nda"));
    }
    if (str_ends_with(dict_form, EL_STR("bu"))) {
      return el_str_concat(tstem, EL_STR("nda"));
    }
    if (str_ends_with(dict_form, EL_STR("mu"))) {
      return el_str_concat(tstem, EL_STR("nda"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x99"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x81\x97\xe3\x81\x9f"));
    }
    if (str_ends_with(dict_form, EL_STR("su"))) {
      return el_str_concat(tstem, EL_STR("shita"));
    }
    if (str_ends_with(dict_form, EL_STR("\xe3\x81\x8f"))) {
      return el_str_concat(tstem, EL_STR("\xe3\x81\x9f"));
    }
    if (str_ends_with(dict_form, EL_STR("ku"))) {
      return el_str_concat(tstem, EL_STR("ta"));
    }
    return el_str_concat(tstem, EL_STR("\xe3\x81\x9f"));
  }
  return dict_form;
  return 0;
}

el_val_t ja_particle(el_val_t gram_case) {
  if (str_eq(gram_case, EL_STR("nominative"))) {
    return EL_STR("\xe3\x81\x8c");
  }
  if (str_eq(gram_case, EL_STR("accusative"))) {
    return EL_STR("\xe3\x82\x92");
  }
  if (str_eq(gram_case, EL_STR("dative"))) {
    return EL_STR("\xe3\x81\xab");
  }
  if (str_eq(gram_case, EL_STR("genitive"))) {
    return EL_STR("\xe3\x81\xae");
  }
  if (str_eq(gram_case, EL_STR("topic"))) {
    return EL_STR("\xe3\x81\xaf");
  }
  if (str_eq(gram_case, EL_STR("instrumental"))) {
    return EL_STR("\xe3\x81\xa7");
  }
  if (str_eq(gram_case, EL_STR("locative"))) {
    return EL_STR("\xe3\x81\xab");
  }
  if (str_eq(gram_case, EL_STR("ablative"))) {
    return EL_STR("\xe3\x81\x8b\xe3\x82\x89");
  }
  if (str_eq(gram_case, EL_STR("direction"))) {
    return EL_STR("\xe3\x81\xb8");
  }
  if (str_eq(gram_case, EL_STR("comitative"))) {
    return EL_STR("\xe3\x81\xa8");
  }
  return EL_STR("");
  return 0;
}

el_val_t ja_noun_phrase(el_val_t noun, el_val_t gram_case) {
  el_val_t p = ja_particle(gram_case);
  if (str_eq(p, EL_STR(""))) {
    return noun;
  }
  return el_str_concat(noun, p);
  return 0;
}

el_val_t ja_question_particle(void) {
  return EL_STR("\xe3\x81\x8b");
  return 0;
}

el_val_t ja_make_question(el_val_t sentence) {
  return el_str_concat(sentence, ja_question_particle());
  return 0;
}

