/*
 * Anthyの統語モデル 
 *
 * 隣接するmetawordを結合していくことにより構文木を作る
 * 困難な点は
 * (1)日本語の妥当なモデルを使う
 * (2)計算量の爆発を抑える
 *
 * Copyright (C) 2003-2004 TABATA Yusuke
 */
#include <splitter.h>
#include "wordborder.h"

/* 合成されたmeta_word */
static struct meta_word *hl_mws;

void
anthy_init_segclass(struct seg_class *sc)
{
  sc->head_pos = POS_NONE;
  sc->tail_pos = POS_NONE;
  sc->tail_ct = CT_NONE;
  sc->tail_type = SEG_NONE;
}

static void
do_combine(struct splitter_context *sc, int type,
	   struct meta_word *mw1, struct meta_word *mw2)
{
  struct meta_word *res;
  res = anthy_do_combine_metaword(sc, type,
				  mw1, mw2);
  res->mw_count = mw1->mw_count + mw2->mw_count;
  res->seg_class = mw2->seg_class;
  if (0) {
    anthy_print_metaword(sc, res);
  }
  /* 合成済みのmeta_wordをlistに追加する */
  res->composed = hl_mws;
  hl_mws = res;
  /* balance分の補正、適当なので、そのうち計算しなおすこと */
  res->score -= 400;
}

/* 「〜は」「〜が」 */
static void
try_combine_subject(struct splitter_context *sc,
		    struct meta_word *mw1, struct meta_word *mw2)
{
  if ((mw2->seg_class.tail_type & SEG_INDECLINABLE) ||
      (mw2->seg_class.tail_type & SEG_DECLINABLE)) {
    do_combine(sc, MW_SENTENCE,
	       mw1, mw2);
  }
}

/* 「〜な」「〜の」連体詞 連体*/
static void
try_combine_rt_modifier(struct splitter_context *sc,
			struct meta_word *mw1, struct meta_word *mw2)
{
  if (mw2->seg_class.tail_type & SEG_SUBJECT) {
    do_combine(sc, MW_MODIFIED,
	       mw1, mw2);
  }
  if (mw2->seg_class.head_pos == POS_NOUN) {
    do_combine(sc, MW_MODIFIED,
	       mw1, mw2);
  }
}

/* 「〜を」 */
static void
try_combine_wo(struct splitter_context *sc,
	       struct meta_word *mw1, struct meta_word *mw2)
{
  if (mw2->seg_class.tail_type & SEG_INDECLINABLE) {
    do_combine(sc, MW_MODIFIED,
	       mw1, mw2);
  }
}

/* 「〜と」 */
static void
try_combine_to(struct splitter_context *sc,
	       struct meta_word *mw1, struct meta_word *mw2)
{
  if (mw2->seg_class.head_pos == POS_V) {
    do_combine(sc, MW_MODIFIED,
	       mw1, mw2);
  }
}

/* 副詞 */
static void
try_combine_adverb(struct splitter_context *sc,
		   struct meta_word *mw1, struct meta_word *mw2)
{
  if (mw2->seg_class.tail_type & SEG_MODIFIER_TO) {
    do_combine(sc, MW_MODIFIED, mw1, mw2);
  }
}
/* 連体形 */
static void
try_combine_rentai(struct splitter_context *sc,
		   struct meta_word *mw1, struct meta_word *mw2)
{
  if (mw2->seg_class.head_pos & POS_NOUN) {
    do_combine(sc, MW_MODIFIED, mw1, mw2);
  }
}

/** 連接するmeta_wordに対して、左側のmeta_wordのパターンに応じて
    結合を試す*/
static void
try_combine(struct splitter_context *sc,
	    struct meta_word *mw1, struct meta_word *mw2)
{
  if (mw1->seg_class.tail_type & SEG_SUBJECT) {
    //try_combine_subject(sc, mw1, mw2);
  }
  if (mw1->seg_class.tail_type & SEG_RT_MODIFIER) {
    try_combine_rt_modifier(sc, mw1, mw2);
  }
  if (mw1->seg_class.tail_type & SEG_MODIFIER_WO) {
    try_combine_wo(sc, mw1, mw2);
  }
  if (mw1->seg_class.tail_type & SEG_MODIFIER_TO) {
    try_combine_to(sc, mw1, mw2);
  }
  if (mw1->seg_class.tail_type & SEG_ADVERB) {
    try_combine_adverb(sc, mw1, mw2);
  }
  if (mw1->seg_class.tail_ct == CT_RENTAI) {
    try_combine_rentai(sc, mw1, mw2);
  }
}

/**/
void
anthy_make_syntactic_metaword(struct splitter_context *sc)
{
  int i, right;
  struct word_split_info_cache *info = sc->word_split_info;
  struct meta_word *mw, *mw2;
  /**/
  if (anthy_splitter_debug_flags() & SPLITTER_DEBUG_S) {
    return ;
  }
  return ;
  hl_mws = 0;
  /* このループはmetaword.cのcombine_metaword()と同じ */
  for (i = 0; i < sc->char_count; i++){
    for (mw = info->cnode[i].mw;
	 mw; mw = mw->next) {
      if (mw->len + i == sc->char_count) {
	continue;
      }
      for (mw2 = info->cnode[mw->len+i].mw; 
	   mw2; mw2 = mw2->next) {
	/* mwとmw2の結合にtry */
	try_combine(sc, mw, mw2);
      }
    }
  }
  /* 合成したmeta_wordに対して */
  for (mw = hl_mws; mw; mw = mw->composed) {
    right = mw->from + mw->len;
    if (right == sc->char_count) {
      continue ;
    }
    for (mw2 = info->cnode[right].mw; mw2; mw2 = mw2->next) {
      try_combine(sc, mw, mw2);
    }
  }
}
