/* trigram-decoder.c generated by valac 0.56.19, the Vala compiler
 * generated from trigram-decoder.vala, do not modify */

/*
 * Copyright (C) 2012-2014 Daiki Ueno <ueno@gnu.org>
 * Copyright (C) 2012-2014 Red Hat, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <glib-object.h>
#include "libkkc/libkkc.h"
#include <glib.h>
#include <float.h>
#include <math.h>
#include <gobject/gvaluecollector.h>
#include <stdlib.h>
#include <string.h>
#include <gee.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

#define KKC_TYPE_PATH_COST_FUNC (kkc_path_cost_func_get_type ())
#define KKC_PATH_COST_FUNC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_PATH_COST_FUNC, KkcPathCostFunc))
#define KKC_PATH_COST_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_PATH_COST_FUNC, KkcPathCostFuncClass))
#define KKC_IS_PATH_COST_FUNC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_PATH_COST_FUNC))
#define KKC_IS_PATH_COST_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_PATH_COST_FUNC))
#define KKC_PATH_COST_FUNC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_PATH_COST_FUNC, KkcPathCostFuncClass))

typedef struct _KkcPathCostFunc KkcPathCostFunc;
typedef struct _KkcPathCostFuncClass KkcPathCostFuncClass;
typedef struct _KkcPathCostFuncPrivate KkcPathCostFuncPrivate;
typedef struct _KkcParamSpecPathCostFunc KkcParamSpecPathCostFunc;

#define KKC_TYPE_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC (kkc_unigram_to_unigram_path_cost_func_get_type ())
#define KKC_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC, KkcUnigramToUnigramPathCostFunc))
#define KKC_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC, KkcUnigramToUnigramPathCostFuncClass))
#define KKC_IS_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC))
#define KKC_IS_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC))
#define KKC_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC, KkcUnigramToUnigramPathCostFuncClass))

typedef struct _KkcUnigramToUnigramPathCostFunc KkcUnigramToUnigramPathCostFunc;
typedef struct _KkcUnigramToUnigramPathCostFuncClass KkcUnigramToUnigramPathCostFuncClass;
typedef struct _KkcUnigramToUnigramPathCostFuncPrivate KkcUnigramToUnigramPathCostFuncPrivate;
#define _kkc_trellis_node_unref0(var) ((var == NULL) ? NULL : (var = (kkc_trellis_node_unref (var), NULL)))

#define KKC_TYPE_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC (kkc_unigram_to_bigram_path_cost_func_get_type ())
#define KKC_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC, KkcUnigramToBigramPathCostFunc))
#define KKC_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC, KkcUnigramToBigramPathCostFuncClass))
#define KKC_IS_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC))
#define KKC_IS_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC))
#define KKC_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC, KkcUnigramToBigramPathCostFuncClass))

typedef struct _KkcUnigramToBigramPathCostFunc KkcUnigramToBigramPathCostFunc;
typedef struct _KkcUnigramToBigramPathCostFuncClass KkcUnigramToBigramPathCostFuncClass;
typedef struct _KkcUnigramToBigramPathCostFuncPrivate KkcUnigramToBigramPathCostFuncPrivate;

#define KKC_TYPE_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC (kkc_bigram_to_unigram_path_cost_func_get_type ())
#define KKC_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC, KkcBigramToUnigramPathCostFunc))
#define KKC_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC, KkcBigramToUnigramPathCostFuncClass))
#define KKC_IS_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC))
#define KKC_IS_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC))
#define KKC_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC, KkcBigramToUnigramPathCostFuncClass))

typedef struct _KkcBigramToUnigramPathCostFunc KkcBigramToUnigramPathCostFunc;
typedef struct _KkcBigramToUnigramPathCostFuncClass KkcBigramToUnigramPathCostFuncClass;
typedef struct _KkcBigramToUnigramPathCostFuncPrivate KkcBigramToUnigramPathCostFuncPrivate;

#define KKC_TYPE_BIGRAM_TO_BIGRAM_PATH_COST_FUNC (kkc_bigram_to_bigram_path_cost_func_get_type ())
#define KKC_BIGRAM_TO_BIGRAM_PATH_COST_FUNC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_BIGRAM_TO_BIGRAM_PATH_COST_FUNC, KkcBigramToBigramPathCostFunc))
#define KKC_BIGRAM_TO_BIGRAM_PATH_COST_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_BIGRAM_TO_BIGRAM_PATH_COST_FUNC, KkcBigramToBigramPathCostFuncClass))
#define KKC_IS_BIGRAM_TO_BIGRAM_PATH_COST_FUNC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_BIGRAM_TO_BIGRAM_PATH_COST_FUNC))
#define KKC_IS_BIGRAM_TO_BIGRAM_PATH_COST_FUNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_BIGRAM_TO_BIGRAM_PATH_COST_FUNC))
#define KKC_BIGRAM_TO_BIGRAM_PATH_COST_FUNC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_BIGRAM_TO_BIGRAM_PATH_COST_FUNC, KkcBigramToBigramPathCostFuncClass))

typedef struct _KkcBigramToBigramPathCostFunc KkcBigramToBigramPathCostFunc;
typedef struct _KkcBigramToBigramPathCostFuncClass KkcBigramToBigramPathCostFuncClass;
typedef struct _KkcBigramToBigramPathCostFuncPrivate KkcBigramToBigramPathCostFuncPrivate;
enum  {
	KKC_TRIGRAM_DECODER_0_PROPERTY,
	KKC_TRIGRAM_DECODER_NUM_PROPERTIES
};
static GParamSpec* kkc_trigram_decoder_properties[KKC_TRIGRAM_DECODER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _kkc_path_cost_func_unref0(var) ((var == NULL) ? NULL : (var = (kkc_path_cost_func_unref (var), NULL)))
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _KkcPathCostFunc {
	GTypeInstance parent_instance;
	volatile int ref_count;
	KkcPathCostFuncPrivate * priv;
};

struct _KkcPathCostFuncClass {
	GTypeClass parent_class;
	void (*finalize) (KkcPathCostFunc *self);
	gdouble (*path_cost) (KkcPathCostFunc* self, KkcTrigramLanguageModel* model, KkcTrellisNode* pnode, KkcTrellisNode* node);
};

struct _KkcParamSpecPathCostFunc {
	GParamSpec parent_instance;
};

struct _KkcUnigramToUnigramPathCostFunc {
	KkcPathCostFunc parent_instance;
	KkcUnigramToUnigramPathCostFuncPrivate * priv;
};

struct _KkcUnigramToUnigramPathCostFuncClass {
	KkcPathCostFuncClass parent_class;
};

struct _KkcUnigramToBigramPathCostFunc {
	KkcPathCostFunc parent_instance;
	KkcUnigramToBigramPathCostFuncPrivate * priv;
};

struct _KkcUnigramToBigramPathCostFuncClass {
	KkcPathCostFuncClass parent_class;
};

struct _KkcBigramToUnigramPathCostFunc {
	KkcPathCostFunc parent_instance;
	KkcBigramToUnigramPathCostFuncPrivate * priv;
};

struct _KkcBigramToUnigramPathCostFuncClass {
	KkcPathCostFuncClass parent_class;
};

struct _KkcBigramToBigramPathCostFunc {
	KkcPathCostFunc parent_instance;
	KkcBigramToBigramPathCostFuncPrivate * priv;
};

struct _KkcBigramToBigramPathCostFuncClass {
	KkcPathCostFuncClass parent_class;
};

struct _KkcTrigramDecoderPrivate {
	KkcPathCostFunc* path_cost_funcs[4];
};

static gpointer kkc_path_cost_func_parent_class = NULL;
static gpointer kkc_unigram_to_unigram_path_cost_func_parent_class = NULL;
static gpointer kkc_unigram_to_bigram_path_cost_func_parent_class = NULL;
static gpointer kkc_bigram_to_unigram_path_cost_func_parent_class = NULL;
static gpointer kkc_bigram_to_bigram_path_cost_func_parent_class = NULL;
static gint KkcTrigramDecoder_private_offset;
static gpointer kkc_trigram_decoder_parent_class = NULL;

VALA_EXTERN gpointer kkc_path_cost_func_ref (gpointer instance);
VALA_EXTERN void kkc_path_cost_func_unref (gpointer instance);
VALA_EXTERN GParamSpec* kkc_param_spec_path_cost_func (const gchar* name,
                                           const gchar* nick,
                                           const gchar* blurb,
                                           GType object_type,
                                           GParamFlags flags);
VALA_EXTERN void kkc_value_set_path_cost_func (GValue* value,
                                   gpointer v_object);
VALA_EXTERN void kkc_value_take_path_cost_func (GValue* value,
                                    gpointer v_object);
VALA_EXTERN gpointer kkc_value_get_path_cost_func (const GValue* value);
VALA_EXTERN GType kkc_path_cost_func_get_type (void) G_GNUC_CONST ;
VALA_EXTERN gdouble kkc_path_cost_func_path_cost (KkcPathCostFunc* self,
                                      KkcTrigramLanguageModel* model,
                                      KkcTrellisNode* pnode,
                                      KkcTrellisNode* node);
static gdouble kkc_path_cost_func_real_path_cost (KkcPathCostFunc* self,
                                           KkcTrigramLanguageModel* model,
                                           KkcTrellisNode* pnode,
                                           KkcTrellisNode* node);
VALA_EXTERN KkcPathCostFunc* kkc_path_cost_func_construct (GType object_type);
static void kkc_path_cost_func_finalize (KkcPathCostFunc * obj);
static GType kkc_path_cost_func_get_type_once (void);
VALA_EXTERN GType kkc_unigram_to_unigram_path_cost_func_get_type (void) G_GNUC_CONST ;
static gdouble kkc_unigram_to_unigram_path_cost_func_real_path_cost (KkcPathCostFunc* base,
                                                              KkcTrigramLanguageModel* model,
                                                              KkcTrellisNode* pnode,
                                                              KkcTrellisNode* node);
static gboolean _kkc_language_model_entry_equal (const KkcLanguageModelEntry * s1,
                                          const KkcLanguageModelEntry * s2);
VALA_EXTERN KkcUnigramToUnigramPathCostFunc* kkc_unigram_to_unigram_path_cost_func_new (void);
VALA_EXTERN KkcUnigramToUnigramPathCostFunc* kkc_unigram_to_unigram_path_cost_func_construct (GType object_type);
static GType kkc_unigram_to_unigram_path_cost_func_get_type_once (void);
VALA_EXTERN GType kkc_unigram_to_bigram_path_cost_func_get_type (void) G_GNUC_CONST ;
static gdouble kkc_unigram_to_bigram_path_cost_func_real_path_cost (KkcPathCostFunc* base,
                                                             KkcTrigramLanguageModel* model,
                                                             KkcTrellisNode* pnode,
                                                             KkcTrellisNode* node);
VALA_EXTERN KkcUnigramToBigramPathCostFunc* kkc_unigram_to_bigram_path_cost_func_new (void);
VALA_EXTERN KkcUnigramToBigramPathCostFunc* kkc_unigram_to_bigram_path_cost_func_construct (GType object_type);
static GType kkc_unigram_to_bigram_path_cost_func_get_type_once (void);
VALA_EXTERN GType kkc_bigram_to_unigram_path_cost_func_get_type (void) G_GNUC_CONST ;
static gdouble kkc_bigram_to_unigram_path_cost_func_real_path_cost (KkcPathCostFunc* base,
                                                             KkcTrigramLanguageModel* model,
                                                             KkcTrellisNode* pnode,
                                                             KkcTrellisNode* node);
VALA_EXTERN KkcBigramToUnigramPathCostFunc* kkc_bigram_to_unigram_path_cost_func_new (void);
VALA_EXTERN KkcBigramToUnigramPathCostFunc* kkc_bigram_to_unigram_path_cost_func_construct (GType object_type);
static GType kkc_bigram_to_unigram_path_cost_func_get_type_once (void);
VALA_EXTERN GType kkc_bigram_to_bigram_path_cost_func_get_type (void) G_GNUC_CONST ;
static gdouble kkc_bigram_to_bigram_path_cost_func_real_path_cost (KkcPathCostFunc* base,
                                                            KkcTrigramLanguageModel* model,
                                                            KkcTrellisNode* pnode,
                                                            KkcTrellisNode* node);
VALA_EXTERN KkcBigramToBigramPathCostFunc* kkc_bigram_to_bigram_path_cost_func_new (void);
VALA_EXTERN KkcBigramToBigramPathCostFunc* kkc_bigram_to_bigram_path_cost_func_construct (GType object_type);
static GType kkc_bigram_to_bigram_path_cost_func_get_type_once (void);
static KkcSegment** kkc_trigram_decoder_real_decode (KkcDecoder* base,
                                              const gchar* input,
                                              gint nbest,
                                              gint* constraint,
                                              gint constraint_length1,
                                              gint* result_length1);
static KkcSegment** kkc_trigram_decoder_real_decode_with_costs (KkcDecoder* base,
                                                         const gchar* input,
                                                         gint nbest,
                                                         gint* constraint,
                                                         gint constraint_length1,
                                                         gdouble max_distance,
                                                         gdouble min_path_cost,
                                                         gint* result_length1);
static void kkc_trigram_decoder_add_trigram_nodes (KkcTrigramDecoder* self,
                                            GeeArrayList** trellis,
                                            gint trellis_length1);
static gint kkc_trigram_decoder_path_to_func_index (KkcTrigramDecoder* self,
                                             KkcTrellisNode* pnode,
                                             KkcTrellisNode* node);
static gdouble kkc_trigram_decoder_real_path_cost (KkcBigramDecoder* base,
                                            KkcTrellisNode* pnode,
                                            KkcTrellisNode* node,
                                            gint endpos);
static void kkc_trigram_decoder_finalize (GObject * obj);
static GType kkc_trigram_decoder_get_type_once (void);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);

static gdouble
kkc_path_cost_func_real_path_cost (KkcPathCostFunc* self,
                                   KkcTrigramLanguageModel* model,
                                   KkcTrellisNode* pnode,
                                   KkcTrellisNode* node)
{
	gdouble _tmp0_ = 0.0;
	g_critical ("Type `%s' does not implement abstract method `kkc_path_cost_func_path_cost'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return _tmp0_;
}

gdouble
kkc_path_cost_func_path_cost (KkcPathCostFunc* self,
                              KkcTrigramLanguageModel* model,
                              KkcTrellisNode* pnode,
                              KkcTrellisNode* node)
{
	KkcPathCostFuncClass* _klass_;
	g_return_val_if_fail (self != NULL, -1.0);
	_klass_ = KKC_PATH_COST_FUNC_GET_CLASS (self);
	if (_klass_->path_cost) {
		return _klass_->path_cost (self, model, pnode, node);
	}
	return -1.0;
}

KkcPathCostFunc*
kkc_path_cost_func_construct (GType object_type)
{
	KkcPathCostFunc* self = NULL;
	self = (KkcPathCostFunc*) g_type_create_instance (object_type);
	return self;
}

static void
kkc_value_path_cost_func_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
kkc_value_path_cost_func_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		kkc_path_cost_func_unref (value->data[0].v_pointer);
	}
}

static void
kkc_value_path_cost_func_copy_value (const GValue* src_value,
                                     GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = kkc_path_cost_func_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
kkc_value_path_cost_func_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
kkc_value_path_cost_func_collect_value (GValue* value,
                                        guint n_collect_values,
                                        GTypeCValue* collect_values,
                                        guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		KkcPathCostFunc * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = kkc_path_cost_func_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
kkc_value_path_cost_func_lcopy_value (const GValue* value,
                                      guint n_collect_values,
                                      GTypeCValue* collect_values,
                                      guint collect_flags)
{
	KkcPathCostFunc ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = kkc_path_cost_func_ref (value->data[0].v_pointer);
	}
	return NULL;
}

GParamSpec*
kkc_param_spec_path_cost_func (const gchar* name,
                               const gchar* nick,
                               const gchar* blurb,
                               GType object_type,
                               GParamFlags flags)
{
	KkcParamSpecPathCostFunc* spec;
	g_return_val_if_fail (g_type_is_a (object_type, KKC_TYPE_PATH_COST_FUNC), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}

gpointer
kkc_value_get_path_cost_func (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, KKC_TYPE_PATH_COST_FUNC), NULL);
	return value->data[0].v_pointer;
}

void
kkc_value_set_path_cost_func (GValue* value,
                              gpointer v_object)
{
	KkcPathCostFunc * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, KKC_TYPE_PATH_COST_FUNC));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, KKC_TYPE_PATH_COST_FUNC));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		kkc_path_cost_func_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		kkc_path_cost_func_unref (old);
	}
}

void
kkc_value_take_path_cost_func (GValue* value,
                               gpointer v_object)
{
	KkcPathCostFunc * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, KKC_TYPE_PATH_COST_FUNC));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, KKC_TYPE_PATH_COST_FUNC));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		kkc_path_cost_func_unref (old);
	}
}

static void
kkc_path_cost_func_class_init (KkcPathCostFuncClass * klass,
                               gpointer klass_data)
{
	kkc_path_cost_func_parent_class = g_type_class_peek_parent (klass);
	((KkcPathCostFuncClass *) klass)->finalize = kkc_path_cost_func_finalize;
	((KkcPathCostFuncClass *) klass)->path_cost = (gdouble (*) (KkcPathCostFunc*, KkcTrigramLanguageModel*, KkcTrellisNode*, KkcTrellisNode*)) kkc_path_cost_func_real_path_cost;
}

static void
kkc_path_cost_func_instance_init (KkcPathCostFunc * self,
                                  gpointer klass)
{
	self->ref_count = 1;
}

static void
kkc_path_cost_func_finalize (KkcPathCostFunc * obj)
{
	KkcPathCostFunc * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, KKC_TYPE_PATH_COST_FUNC, KkcPathCostFunc);
	g_signal_handlers_destroy (self);
}

static GType
kkc_path_cost_func_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { kkc_value_path_cost_func_init, kkc_value_path_cost_func_free_value, kkc_value_path_cost_func_copy_value, kkc_value_path_cost_func_peek_pointer, "p", kkc_value_path_cost_func_collect_value, "p", kkc_value_path_cost_func_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (KkcPathCostFuncClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_path_cost_func_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcPathCostFunc), 0, (GInstanceInitFunc) kkc_path_cost_func_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType kkc_path_cost_func_type_id;
	kkc_path_cost_func_type_id = g_type_register_fundamental (g_type_fundamental_next (), "KkcPathCostFunc", &g_define_type_info, &g_define_type_fundamental_info, G_TYPE_FLAG_ABSTRACT);
	return kkc_path_cost_func_type_id;
}

GType
kkc_path_cost_func_get_type (void)
{
	static volatile gsize kkc_path_cost_func_type_id__once = 0;
	if (g_once_init_enter (&kkc_path_cost_func_type_id__once)) {
		GType kkc_path_cost_func_type_id;
		kkc_path_cost_func_type_id = kkc_path_cost_func_get_type_once ();
		g_once_init_leave (&kkc_path_cost_func_type_id__once, kkc_path_cost_func_type_id);
	}
	return kkc_path_cost_func_type_id__once;
}

gpointer
kkc_path_cost_func_ref (gpointer instance)
{
	KkcPathCostFunc * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

void
kkc_path_cost_func_unref (gpointer instance)
{
	KkcPathCostFunc * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		KKC_PATH_COST_FUNC_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static gpointer
_kkc_trellis_node_ref0 (gpointer self)
{
	return self ? kkc_trellis_node_ref (self) : NULL;
}

static gboolean
_kkc_language_model_entry_equal (const KkcLanguageModelEntry * s1,
                                 const KkcLanguageModelEntry * s2)
{
	if (s1 == s2) {
		return TRUE;
	}
	if (s1 == NULL) {
		return FALSE;
	}
	if (s2 == NULL) {
		return FALSE;
	}
	if (g_strcmp0 (s1->input, s2->input)) {
		return FALSE;
	}
	if (g_strcmp0 (s1->output, s2->output)) {
		return FALSE;
	}
	if (s1->id != s2->id) {
		return FALSE;
	}
	return TRUE;
}

static gdouble
kkc_unigram_to_unigram_path_cost_func_real_path_cost (KkcPathCostFunc* base,
                                                      KkcTrigramLanguageModel* model,
                                                      KkcTrellisNode* pnode,
                                                      KkcTrellisNode* node)
{
	KkcUnigramToUnigramPathCostFunc * self;
	KkcUnigramTrellisNode* upnode = NULL;
	KkcUnigramTrellisNode* _tmp0_;
	KkcUnigramTrellisNode* unode = NULL;
	KkcUnigramTrellisNode* _tmp1_;
	gdouble cost = 0.0;
	KkcUnigramTrellisNode* _tmp2_;
	KkcLanguageModelEntry _tmp3_ = {0};
	KkcLanguageModelEntry _tmp4_;
	KkcLanguageModelEntry _tmp5_ = {0};
	KkcLanguageModelEntry _tmp6_;
	gdouble result;
	self = (KkcUnigramToUnigramPathCostFunc*) base;
	g_return_val_if_fail (model != NULL, -1.0);
	g_return_val_if_fail (pnode != NULL, -1.0);
	g_return_val_if_fail (node != NULL, -1.0);
	_vala_assert (KKC_IS_UNIGRAM_TRELLIS_NODE (pnode), "pnode is UnigramTrellisNode");
	_vala_assert (KKC_IS_UNIGRAM_TRELLIS_NODE (node), "node is UnigramTrellisNode");
	_tmp0_ = _kkc_trellis_node_ref0 (G_TYPE_CHECK_INSTANCE_CAST (pnode, KKC_TYPE_UNIGRAM_TRELLIS_NODE, KkcUnigramTrellisNode));
	upnode = _tmp0_;
	_tmp1_ = _kkc_trellis_node_ref0 (G_TYPE_CHECK_INSTANCE_CAST (node, KKC_TYPE_UNIGRAM_TRELLIS_NODE, KkcUnigramTrellisNode));
	unode = _tmp1_;
	cost = 0.0;
	_tmp2_ = upnode;
	kkc_unigram_trellis_node_get_entry (_tmp2_, &_tmp3_);
	_tmp4_ = _tmp3_;
	kkc_language_model_get_bos ((KkcLanguageModel*) model, &_tmp5_);
	_tmp6_ = _tmp5_;
	if (_kkc_language_model_entry_equal (&_tmp4_, &_tmp6_) == TRUE) {
		KkcUnigramTrellisNode* _tmp7_;
		KkcLanguageModelEntry _tmp8_ = {0};
		KkcLanguageModelEntry _tmp9_;
		KkcUnigramTrellisNode* _tmp10_;
		KkcLanguageModelEntry _tmp11_ = {0};
		KkcLanguageModelEntry _tmp12_;
		_tmp7_ = upnode;
		kkc_unigram_trellis_node_get_entry (_tmp7_, &_tmp8_);
		_tmp9_ = _tmp8_;
		_tmp10_ = unode;
		kkc_unigram_trellis_node_get_entry (_tmp10_, &_tmp11_);
		_tmp12_ = _tmp11_;
		cost = kkc_bigram_language_model_bigram_backoff_cost ((KkcBigramLanguageModel*) model, &_tmp9_, &_tmp12_);
	} else {
		KkcUnigramTrellisNode* _tmp13_;
		KkcTrellisNode* _tmp14_;
		_tmp13_ = upnode;
		_tmp14_ = ((KkcTrellisNode*) _tmp13_)->previous;
		if (_tmp14_ != NULL) {
			KkcUnigramTrellisNode* _tmp15_;
			KkcTrellisNode* _tmp16_;
			_tmp15_ = upnode;
			_tmp16_ = ((KkcTrellisNode*) _tmp15_)->previous;
			if (KKC_IS_UNIGRAM_TRELLIS_NODE (_tmp16_)) {
				KkcUnigramTrellisNode* _tmp17_;
				KkcTrellisNode* _tmp18_;
				KkcLanguageModelEntry _tmp19_ = {0};
				KkcLanguageModelEntry _tmp20_;
				KkcUnigramTrellisNode* _tmp21_;
				KkcLanguageModelEntry _tmp22_ = {0};
				KkcLanguageModelEntry _tmp23_;
				KkcUnigramTrellisNode* _tmp24_;
				KkcLanguageModelEntry _tmp25_ = {0};
				KkcLanguageModelEntry _tmp26_;
				_tmp17_ = upnode;
				_tmp18_ = ((KkcTrellisNode*) _tmp17_)->previous;
				kkc_unigram_trellis_node_get_entry (G_TYPE_CHECK_INSTANCE_CAST (_tmp18_, KKC_TYPE_UNIGRAM_TRELLIS_NODE, KkcUnigramTrellisNode), &_tmp19_);
				_tmp20_ = _tmp19_;
				_tmp21_ = upnode;
				kkc_unigram_trellis_node_get_entry (_tmp21_, &_tmp22_);
				_tmp23_ = _tmp22_;
				_tmp24_ = unode;
				kkc_unigram_trellis_node_get_entry (_tmp24_, &_tmp25_);
				_tmp26_ = _tmp25_;
				cost = kkc_trigram_language_model_trigram_backoff_cost (model, &_tmp20_, &_tmp23_, &_tmp26_);
			} else {
				KkcUnigramTrellisNode* _tmp27_;
				KkcTrellisNode* _tmp28_;
				KkcUnigramTrellisNode* _tmp29_;
				KkcUnigramTrellisNode* _tmp30_;
				KkcLanguageModelEntry _tmp31_ = {0};
				KkcLanguageModelEntry _tmp32_;
				KkcUnigramTrellisNode* _tmp33_;
				KkcLanguageModelEntry _tmp34_ = {0};
				KkcLanguageModelEntry _tmp35_;
				KkcUnigramTrellisNode* _tmp36_;
				KkcLanguageModelEntry _tmp37_ = {0};
				KkcLanguageModelEntry _tmp38_;
				_tmp27_ = upnode;
				_tmp28_ = ((KkcTrellisNode*) _tmp27_)->previous;
				_tmp29_ = kkc_bigram_trellis_node_get_right_node (G_TYPE_CHECK_INSTANCE_CAST (_tmp28_, KKC_TYPE_BIGRAM_TRELLIS_NODE, KkcBigramTrellisNode));
				_tmp30_ = _tmp29_;
				kkc_unigram_trellis_node_get_entry (_tmp30_, &_tmp31_);
				_tmp32_ = _tmp31_;
				_tmp33_ = upnode;
				kkc_unigram_trellis_node_get_entry (_tmp33_, &_tmp34_);
				_tmp35_ = _tmp34_;
				_tmp36_ = unode;
				kkc_unigram_trellis_node_get_entry (_tmp36_, &_tmp37_);
				_tmp38_ = _tmp37_;
				cost = kkc_trigram_language_model_trigram_backoff_cost (model, &_tmp32_, &_tmp35_, &_tmp38_);
			}
		}
	}
	result = cost;
	_kkc_trellis_node_unref0 (unode);
	_kkc_trellis_node_unref0 (upnode);
	return result;
}

KkcUnigramToUnigramPathCostFunc*
kkc_unigram_to_unigram_path_cost_func_construct (GType object_type)
{
	KkcUnigramToUnigramPathCostFunc* self = NULL;
	self = (KkcUnigramToUnigramPathCostFunc*) kkc_path_cost_func_construct (object_type);
	return self;
}

KkcUnigramToUnigramPathCostFunc*
kkc_unigram_to_unigram_path_cost_func_new (void)
{
	return kkc_unigram_to_unigram_path_cost_func_construct (KKC_TYPE_UNIGRAM_TO_UNIGRAM_PATH_COST_FUNC);
}

static void
kkc_unigram_to_unigram_path_cost_func_class_init (KkcUnigramToUnigramPathCostFuncClass * klass,
                                                  gpointer klass_data)
{
	kkc_unigram_to_unigram_path_cost_func_parent_class = g_type_class_peek_parent (klass);
	((KkcPathCostFuncClass *) klass)->path_cost = (gdouble (*) (KkcPathCostFunc*, KkcTrigramLanguageModel*, KkcTrellisNode*, KkcTrellisNode*)) kkc_unigram_to_unigram_path_cost_func_real_path_cost;
}

static void
kkc_unigram_to_unigram_path_cost_func_instance_init (KkcUnigramToUnigramPathCostFunc * self,
                                                     gpointer klass)
{
}

static GType
kkc_unigram_to_unigram_path_cost_func_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcUnigramToUnigramPathCostFuncClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_unigram_to_unigram_path_cost_func_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcUnigramToUnigramPathCostFunc), 0, (GInstanceInitFunc) kkc_unigram_to_unigram_path_cost_func_instance_init, NULL };
	GType kkc_unigram_to_unigram_path_cost_func_type_id;
	kkc_unigram_to_unigram_path_cost_func_type_id = g_type_register_static (KKC_TYPE_PATH_COST_FUNC, "KkcUnigramToUnigramPathCostFunc", &g_define_type_info, 0);
	return kkc_unigram_to_unigram_path_cost_func_type_id;
}

GType
kkc_unigram_to_unigram_path_cost_func_get_type (void)
{
	static volatile gsize kkc_unigram_to_unigram_path_cost_func_type_id__once = 0;
	if (g_once_init_enter (&kkc_unigram_to_unigram_path_cost_func_type_id__once)) {
		GType kkc_unigram_to_unigram_path_cost_func_type_id;
		kkc_unigram_to_unigram_path_cost_func_type_id = kkc_unigram_to_unigram_path_cost_func_get_type_once ();
		g_once_init_leave (&kkc_unigram_to_unigram_path_cost_func_type_id__once, kkc_unigram_to_unigram_path_cost_func_type_id);
	}
	return kkc_unigram_to_unigram_path_cost_func_type_id__once;
}

static gdouble
kkc_unigram_to_bigram_path_cost_func_real_path_cost (KkcPathCostFunc* base,
                                                     KkcTrigramLanguageModel* model,
                                                     KkcTrellisNode* pnode,
                                                     KkcTrellisNode* node)
{
	KkcUnigramToBigramPathCostFunc * self;
	KkcUnigramTrellisNode* upnode = NULL;
	KkcUnigramTrellisNode* _tmp0_;
	KkcBigramTrellisNode* bnode = NULL;
	KkcBigramTrellisNode* _tmp1_;
	gdouble cost = 0.0;
	KkcUnigramTrellisNode* _tmp2_;
	KkcLanguageModelEntry _tmp3_ = {0};
	KkcLanguageModelEntry _tmp4_;
	KkcLanguageModelEntry _tmp5_ = {0};
	KkcLanguageModelEntry _tmp6_;
	KkcUnigramTrellisNode* _tmp15_;
	KkcLanguageModelEntry _tmp16_ = {0};
	KkcLanguageModelEntry _tmp17_;
	KkcBigramTrellisNode* _tmp18_;
	KkcUnigramTrellisNode* _tmp19_;
	KkcUnigramTrellisNode* _tmp20_;
	KkcLanguageModelEntry _tmp21_ = {0};
	KkcLanguageModelEntry _tmp22_;
	KkcBigramTrellisNode* _tmp23_;
	KkcUnigramTrellisNode* _tmp24_;
	KkcUnigramTrellisNode* _tmp25_;
	KkcLanguageModelEntry _tmp26_ = {0};
	KkcLanguageModelEntry _tmp27_;
	KkcUnigramTrellisNode* _tmp28_;
	KkcTrellisNode* _tmp29_;
	gdouble result;
	self = (KkcUnigramToBigramPathCostFunc*) base;
	g_return_val_if_fail (model != NULL, -1.0);
	g_return_val_if_fail (pnode != NULL, -1.0);
	g_return_val_if_fail (node != NULL, -1.0);
	_vala_assert (KKC_IS_UNIGRAM_TRELLIS_NODE (pnode), "pnode is UnigramTrellisNode");
	_vala_assert (KKC_IS_BIGRAM_TRELLIS_NODE (node), "node is BigramTrellisNode");
	_tmp0_ = _kkc_trellis_node_ref0 (G_TYPE_CHECK_INSTANCE_CAST (pnode, KKC_TYPE_UNIGRAM_TRELLIS_NODE, KkcUnigramTrellisNode));
	upnode = _tmp0_;
	_tmp1_ = _kkc_trellis_node_ref0 (G_TYPE_CHECK_INSTANCE_CAST (node, KKC_TYPE_BIGRAM_TRELLIS_NODE, KkcBigramTrellisNode));
	bnode = _tmp1_;
	cost = 0.0;
	_tmp2_ = upnode;
	kkc_unigram_trellis_node_get_entry (_tmp2_, &_tmp3_);
	_tmp4_ = _tmp3_;
	kkc_language_model_get_bos ((KkcLanguageModel*) model, &_tmp5_);
	_tmp6_ = _tmp5_;
	if (_kkc_language_model_entry_equal (&_tmp4_, &_tmp6_) == TRUE) {
		KkcUnigramTrellisNode* _tmp7_;
		KkcLanguageModelEntry _tmp8_ = {0};
		KkcLanguageModelEntry _tmp9_;
		KkcBigramTrellisNode* _tmp10_;
		KkcUnigramTrellisNode* _tmp11_;
		KkcUnigramTrellisNode* _tmp12_;
		KkcLanguageModelEntry _tmp13_ = {0};
		KkcLanguageModelEntry _tmp14_;
		_tmp7_ = upnode;
		kkc_unigram_trellis_node_get_entry (_tmp7_, &_tmp8_);
		_tmp9_ = _tmp8_;
		_tmp10_ = bnode;
		_tmp11_ = kkc_bigram_trellis_node_get_left_node (_tmp10_);
		_tmp12_ = _tmp11_;
		kkc_unigram_trellis_node_get_entry (_tmp12_, &_tmp13_);
		_tmp14_ = _tmp13_;
		cost += kkc_bigram_language_model_bigram_backoff_cost ((KkcBigramLanguageModel*) model, &_tmp9_, &_tmp14_);
	}
	_tmp15_ = upnode;
	kkc_unigram_trellis_node_get_entry (_tmp15_, &_tmp16_);
	_tmp17_ = _tmp16_;
	_tmp18_ = bnode;
	_tmp19_ = kkc_bigram_trellis_node_get_left_node (_tmp18_);
	_tmp20_ = _tmp19_;
	kkc_unigram_trellis_node_get_entry (_tmp20_, &_tmp21_);
	_tmp22_ = _tmp21_;
	_tmp23_ = bnode;
	_tmp24_ = kkc_bigram_trellis_node_get_right_node (_tmp23_);
	_tmp25_ = _tmp24_;
	kkc_unigram_trellis_node_get_entry (_tmp25_, &_tmp26_);
	_tmp27_ = _tmp26_;
	cost += kkc_trigram_language_model_trigram_backoff_cost (model, &_tmp17_, &_tmp22_, &_tmp27_);
	_tmp28_ = upnode;
	_tmp29_ = ((KkcTrellisNode*) _tmp28_)->previous;
	if (_tmp29_ != NULL) {
		KkcUnigramTrellisNode* _tmp30_;
		KkcTrellisNode* _tmp31_;
		_tmp30_ = upnode;
		_tmp31_ = ((KkcTrellisNode*) _tmp30_)->previous;
		if (KKC_IS_UNIGRAM_TRELLIS_NODE (_tmp31_)) {
			KkcUnigramTrellisNode* _tmp32_;
			KkcTrellisNode* _tmp33_;
			KkcLanguageModelEntry _tmp34_ = {0};
			KkcLanguageModelEntry _tmp35_;
			KkcUnigramTrellisNode* _tmp36_;
			KkcLanguageModelEntry _tmp37_ = {0};
			KkcLanguageModelEntry _tmp38_;
			KkcBigramTrellisNode* _tmp39_;
			KkcUnigramTrellisNode* _tmp40_;
			KkcUnigramTrellisNode* _tmp41_;
			KkcLanguageModelEntry _tmp42_ = {0};
			KkcLanguageModelEntry _tmp43_;
			_tmp32_ = upnode;
			_tmp33_ = ((KkcTrellisNode*) _tmp32_)->previous;
			kkc_unigram_trellis_node_get_entry (G_TYPE_CHECK_INSTANCE_CAST (_tmp33_, KKC_TYPE_UNIGRAM_TRELLIS_NODE, KkcUnigramTrellisNode), &_tmp34_);
			_tmp35_ = _tmp34_;
			_tmp36_ = upnode;
			kkc_unigram_trellis_node_get_entry (_tmp36_, &_tmp37_);
			_tmp38_ = _tmp37_;
			_tmp39_ = bnode;
			_tmp40_ = kkc_bigram_trellis_node_get_left_node (_tmp39_);
			_tmp41_ = _tmp40_;
			kkc_unigram_trellis_node_get_entry (_tmp41_, &_tmp42_);
			_tmp43_ = _tmp42_;
			cost += kkc_trigram_language_model_trigram_backoff_cost (model, &_tmp35_, &_tmp38_, &_tmp43_);
		} else {
			KkcUnigramTrellisNode* _tmp44_;
			KkcTrellisNode* _tmp45_;
			KkcUnigramTrellisNode* _tmp46_;
			KkcUnigramTrellisNode* _tmp47_;
			KkcLanguageModelEntry _tmp48_ = {0};
			KkcLanguageModelEntry _tmp49_;
			KkcUnigramTrellisNode* _tmp50_;
			KkcLanguageModelEntry _tmp51_ = {0};
			KkcLanguageModelEntry _tmp52_;
			KkcBigramTrellisNode* _tmp53_;
			KkcUnigramTrellisNode* _tmp54_;
			KkcUnigramTrellisNode* _tmp55_;
			KkcLanguageModelEntry _tmp56_ = {0};
			KkcLanguageModelEntry _tmp57_;
			_tmp44_ = upnode;
			_tmp45_ = ((KkcTrellisNode*) _tmp44_)->previous;
			_tmp46_ = kkc_bigram_trellis_node_get_right_node (G_TYPE_CHECK_INSTANCE_CAST (_tmp45_, KKC_TYPE_BIGRAM_TRELLIS_NODE, KkcBigramTrellisNode));
			_tmp47_ = _tmp46_;
			kkc_unigram_trellis_node_get_entry (_tmp47_, &_tmp48_);
			_tmp49_ = _tmp48_;
			_tmp50_ = upnode;
			kkc_unigram_trellis_node_get_entry (_tmp50_, &_tmp51_);
			_tmp52_ = _tmp51_;
			_tmp53_ = bnode;
			_tmp54_ = kkc_bigram_trellis_node_get_left_node (_tmp53_);
			_tmp55_ = _tmp54_;
			kkc_unigram_trellis_node_get_entry (_tmp55_, &_tmp56_);
			_tmp57_ = _tmp56_;
			cost += kkc_trigram_language_model_trigram_backoff_cost (model, &_tmp49_, &_tmp52_, &_tmp57_);
		}
	}
	result = cost;
	_kkc_trellis_node_unref0 (bnode);
	_kkc_trellis_node_unref0 (upnode);
	return result;
}

KkcUnigramToBigramPathCostFunc*
kkc_unigram_to_bigram_path_cost_func_construct (GType object_type)
{
	KkcUnigramToBigramPathCostFunc* self = NULL;
	self = (KkcUnigramToBigramPathCostFunc*) kkc_path_cost_func_construct (object_type);
	return self;
}

KkcUnigramToBigramPathCostFunc*
kkc_unigram_to_bigram_path_cost_func_new (void)
{
	return kkc_unigram_to_bigram_path_cost_func_construct (KKC_TYPE_UNIGRAM_TO_BIGRAM_PATH_COST_FUNC);
}

static void
kkc_unigram_to_bigram_path_cost_func_class_init (KkcUnigramToBigramPathCostFuncClass * klass,
                                                 gpointer klass_data)
{
	kkc_unigram_to_bigram_path_cost_func_parent_class = g_type_class_peek_parent (klass);
	((KkcPathCostFuncClass *) klass)->path_cost = (gdouble (*) (KkcPathCostFunc*, KkcTrigramLanguageModel*, KkcTrellisNode*, KkcTrellisNode*)) kkc_unigram_to_bigram_path_cost_func_real_path_cost;
}

static void
kkc_unigram_to_bigram_path_cost_func_instance_init (KkcUnigramToBigramPathCostFunc * self,
                                                    gpointer klass)
{
}

static GType
kkc_unigram_to_bigram_path_cost_func_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcUnigramToBigramPathCostFuncClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_unigram_to_bigram_path_cost_func_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcUnigramToBigramPathCostFunc), 0, (GInstanceInitFunc) kkc_unigram_to_bigram_path_cost_func_instance_init, NULL };
	GType kkc_unigram_to_bigram_path_cost_func_type_id;
	kkc_unigram_to_bigram_path_cost_func_type_id = g_type_register_static (KKC_TYPE_PATH_COST_FUNC, "KkcUnigramToBigramPathCostFunc", &g_define_type_info, 0);
	return kkc_unigram_to_bigram_path_cost_func_type_id;
}

GType
kkc_unigram_to_bigram_path_cost_func_get_type (void)
{
	static volatile gsize kkc_unigram_to_bigram_path_cost_func_type_id__once = 0;
	if (g_once_init_enter (&kkc_unigram_to_bigram_path_cost_func_type_id__once)) {
		GType kkc_unigram_to_bigram_path_cost_func_type_id;
		kkc_unigram_to_bigram_path_cost_func_type_id = kkc_unigram_to_bigram_path_cost_func_get_type_once ();
		g_once_init_leave (&kkc_unigram_to_bigram_path_cost_func_type_id__once, kkc_unigram_to_bigram_path_cost_func_type_id);
	}
	return kkc_unigram_to_bigram_path_cost_func_type_id__once;
}

static gdouble
kkc_bigram_to_unigram_path_cost_func_real_path_cost (KkcPathCostFunc* base,
                                                     KkcTrigramLanguageModel* model,
                                                     KkcTrellisNode* pnode,
                                                     KkcTrellisNode* node)
{
	KkcBigramToUnigramPathCostFunc * self;
	KkcBigramTrellisNode* bpnode = NULL;
	KkcBigramTrellisNode* _tmp0_;
	KkcUnigramTrellisNode* unode = NULL;
	KkcUnigramTrellisNode* _tmp1_;
	gdouble cost = 0.0;
	KkcBigramTrellisNode* _tmp2_;
	KkcUnigramTrellisNode* _tmp3_;
	KkcUnigramTrellisNode* _tmp4_;
	KkcLanguageModelEntry _tmp5_ = {0};
	KkcLanguageModelEntry _tmp6_;
	KkcLanguageModelEntry _tmp7_ = {0};
	KkcLanguageModelEntry _tmp8_;
	KkcBigramTrellisNode* _tmp19_;
	KkcUnigramTrellisNode* _tmp20_;
	KkcUnigramTrellisNode* _tmp21_;
	KkcLanguageModelEntry _tmp22_ = {0};
	KkcLanguageModelEntry _tmp23_;
	KkcBigramTrellisNode* _tmp24_;
	KkcUnigramTrellisNode* _tmp25_;
	KkcUnigramTrellisNode* _tmp26_;
	KkcLanguageModelEntry _tmp27_ = {0};
	KkcLanguageModelEntry _tmp28_;
	KkcUnigramTrellisNode* _tmp29_;
	KkcLanguageModelEntry _tmp30_ = {0};
	KkcLanguageModelEntry _tmp31_;
	gdouble result;
	self = (KkcBigramToUnigramPathCostFunc*) base;
	g_return_val_if_fail (model != NULL, -1.0);
	g_return_val_if_fail (pnode != NULL, -1.0);
	g_return_val_if_fail (node != NULL, -1.0);
	_vala_assert (KKC_IS_BIGRAM_TRELLIS_NODE (pnode), "pnode is BigramTrellisNode");
	_vala_assert (KKC_IS_UNIGRAM_TRELLIS_NODE (node), "node is UnigramTrellisNode");
	_tmp0_ = _kkc_trellis_node_ref0 (G_TYPE_CHECK_INSTANCE_CAST (pnode, KKC_TYPE_BIGRAM_TRELLIS_NODE, KkcBigramTrellisNode));
	bpnode = _tmp0_;
	_tmp1_ = _kkc_trellis_node_ref0 (G_TYPE_CHECK_INSTANCE_CAST (node, KKC_TYPE_UNIGRAM_TRELLIS_NODE, KkcUnigramTrellisNode));
	unode = _tmp1_;
	cost = 0.0;
	_tmp2_ = bpnode;
	_tmp3_ = kkc_bigram_trellis_node_get_left_node (_tmp2_);
	_tmp4_ = _tmp3_;
	kkc_unigram_trellis_node_get_entry (_tmp4_, &_tmp5_);
	_tmp6_ = _tmp5_;
	kkc_language_model_get_bos ((KkcLanguageModel*) model, &_tmp7_);
	_tmp8_ = _tmp7_;
	if (_kkc_language_model_entry_equal (&_tmp6_, &_tmp8_) == TRUE) {
		KkcBigramTrellisNode* _tmp9_;
		KkcUnigramTrellisNode* _tmp10_;
		KkcUnigramTrellisNode* _tmp11_;
		KkcLanguageModelEntry _tmp12_ = {0};
		KkcLanguageModelEntry _tmp13_;
		KkcBigramTrellisNode* _tmp14_;
		KkcUnigramTrellisNode* _tmp15_;
		KkcUnigramTrellisNode* _tmp16_;
		KkcLanguageModelEntry _tmp17_ = {0};
		KkcLanguageModelEntry _tmp18_;
		_tmp9_ = bpnode;
		_tmp10_ = kkc_bigram_trellis_node_get_left_node (_tmp9_);
		_tmp11_ = _tmp10_;
		kkc_unigram_trellis_node_get_entry (_tmp11_, &_tmp12_);
		_tmp13_ = _tmp12_;
		_tmp14_ = bpnode;
		_tmp15_ = kkc_bigram_trellis_node_get_right_node (_tmp14_);
		_tmp16_ = _tmp15_;
		kkc_unigram_trellis_node_get_entry (_tmp16_, &_tmp17_);
		_tmp18_ = _tmp17_;
		cost += kkc_bigram_language_model_bigram_backoff_cost ((KkcBigramLanguageModel*) model, &_tmp13_, &_tmp18_);
	}
	_tmp19_ = bpnode;
	_tmp20_ = kkc_bigram_trellis_node_get_left_node (_tmp19_);
	_tmp21_ = _tmp20_;
	kkc_unigram_trellis_node_get_entry (_tmp21_, &_tmp22_);
	_tmp23_ = _tmp22_;
	_tmp24_ = bpnode;
	_tmp25_ = kkc_bigram_trellis_node_get_right_node (_tmp24_);
	_tmp26_ = _tmp25_;
	kkc_unigram_trellis_node_get_entry (_tmp26_, &_tmp27_);
	_tmp28_ = _tmp27_;
	_tmp29_ = unode;
	kkc_unigram_trellis_node_get_entry (_tmp29_, &_tmp30_);
	_tmp31_ = _tmp30_;
	cost += kkc_trigram_language_model_trigram_backoff_cost (model, &_tmp23_, &_tmp28_, &_tmp31_);
	result = cost;
	_kkc_trellis_node_unref0 (unode);
	_kkc_trellis_node_unref0 (bpnode);
	return result;
}

KkcBigramToUnigramPathCostFunc*
kkc_bigram_to_unigram_path_cost_func_construct (GType object_type)
{
	KkcBigramToUnigramPathCostFunc* self = NULL;
	self = (KkcBigramToUnigramPathCostFunc*) kkc_path_cost_func_construct (object_type);
	return self;
}

KkcBigramToUnigramPathCostFunc*
kkc_bigram_to_unigram_path_cost_func_new (void)
{
	return kkc_bigram_to_unigram_path_cost_func_construct (KKC_TYPE_BIGRAM_TO_UNIGRAM_PATH_COST_FUNC);
}

static void
kkc_bigram_to_unigram_path_cost_func_class_init (KkcBigramToUnigramPathCostFuncClass * klass,
                                                 gpointer klass_data)
{
	kkc_bigram_to_unigram_path_cost_func_parent_class = g_type_class_peek_parent (klass);
	((KkcPathCostFuncClass *) klass)->path_cost = (gdouble (*) (KkcPathCostFunc*, KkcTrigramLanguageModel*, KkcTrellisNode*, KkcTrellisNode*)) kkc_bigram_to_unigram_path_cost_func_real_path_cost;
}

static void
kkc_bigram_to_unigram_path_cost_func_instance_init (KkcBigramToUnigramPathCostFunc * self,
                                                    gpointer klass)
{
}

static GType
kkc_bigram_to_unigram_path_cost_func_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcBigramToUnigramPathCostFuncClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_bigram_to_unigram_path_cost_func_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcBigramToUnigramPathCostFunc), 0, (GInstanceInitFunc) kkc_bigram_to_unigram_path_cost_func_instance_init, NULL };
	GType kkc_bigram_to_unigram_path_cost_func_type_id;
	kkc_bigram_to_unigram_path_cost_func_type_id = g_type_register_static (KKC_TYPE_PATH_COST_FUNC, "KkcBigramToUnigramPathCostFunc", &g_define_type_info, 0);
	return kkc_bigram_to_unigram_path_cost_func_type_id;
}

GType
kkc_bigram_to_unigram_path_cost_func_get_type (void)
{
	static volatile gsize kkc_bigram_to_unigram_path_cost_func_type_id__once = 0;
	if (g_once_init_enter (&kkc_bigram_to_unigram_path_cost_func_type_id__once)) {
		GType kkc_bigram_to_unigram_path_cost_func_type_id;
		kkc_bigram_to_unigram_path_cost_func_type_id = kkc_bigram_to_unigram_path_cost_func_get_type_once ();
		g_once_init_leave (&kkc_bigram_to_unigram_path_cost_func_type_id__once, kkc_bigram_to_unigram_path_cost_func_type_id);
	}
	return kkc_bigram_to_unigram_path_cost_func_type_id__once;
}

static gdouble
kkc_bigram_to_bigram_path_cost_func_real_path_cost (KkcPathCostFunc* base,
                                                    KkcTrigramLanguageModel* model,
                                                    KkcTrellisNode* pnode,
                                                    KkcTrellisNode* node)
{
	KkcBigramToBigramPathCostFunc * self;
	KkcBigramTrellisNode* bpnode = NULL;
	KkcBigramTrellisNode* _tmp0_;
	KkcBigramTrellisNode* bnode = NULL;
	KkcBigramTrellisNode* _tmp1_;
	gdouble cost = 0.0;
	KkcBigramTrellisNode* _tmp2_;
	KkcUnigramTrellisNode* _tmp3_;
	KkcUnigramTrellisNode* _tmp4_;
	KkcLanguageModelEntry _tmp5_ = {0};
	KkcLanguageModelEntry _tmp6_;
	KkcLanguageModelEntry _tmp7_ = {0};
	KkcLanguageModelEntry _tmp8_;
	KkcBigramTrellisNode* _tmp19_;
	KkcUnigramTrellisNode* _tmp20_;
	KkcUnigramTrellisNode* _tmp21_;
	KkcLanguageModelEntry _tmp22_ = {0};
	KkcLanguageModelEntry _tmp23_;
	KkcBigramTrellisNode* _tmp24_;
	KkcUnigramTrellisNode* _tmp25_;
	KkcUnigramTrellisNode* _tmp26_;
	KkcLanguageModelEntry _tmp27_ = {0};
	KkcLanguageModelEntry _tmp28_;
	KkcBigramTrellisNode* _tmp29_;
	KkcUnigramTrellisNode* _tmp30_;
	KkcUnigramTrellisNode* _tmp31_;
	KkcLanguageModelEntry _tmp32_ = {0};
	KkcLanguageModelEntry _tmp33_;
	KkcBigramTrellisNode* _tmp34_;
	KkcUnigramTrellisNode* _tmp35_;
	KkcUnigramTrellisNode* _tmp36_;
	KkcLanguageModelEntry _tmp37_ = {0};
	KkcLanguageModelEntry _tmp38_;
	KkcBigramTrellisNode* _tmp39_;
	KkcUnigramTrellisNode* _tmp40_;
	KkcUnigramTrellisNode* _tmp41_;
	KkcLanguageModelEntry _tmp42_ = {0};
	KkcLanguageModelEntry _tmp43_;
	KkcBigramTrellisNode* _tmp44_;
	KkcUnigramTrellisNode* _tmp45_;
	KkcUnigramTrellisNode* _tmp46_;
	KkcLanguageModelEntry _tmp47_ = {0};
	KkcLanguageModelEntry _tmp48_;
	gdouble result;
	self = (KkcBigramToBigramPathCostFunc*) base;
	g_return_val_if_fail (model != NULL, -1.0);
	g_return_val_if_fail (pnode != NULL, -1.0);
	g_return_val_if_fail (node != NULL, -1.0);
	_vala_assert (KKC_IS_BIGRAM_TRELLIS_NODE (pnode), "pnode is BigramTrellisNode");
	_vala_assert (KKC_IS_BIGRAM_TRELLIS_NODE (node), "node is BigramTrellisNode");
	_tmp0_ = _kkc_trellis_node_ref0 (G_TYPE_CHECK_INSTANCE_CAST (pnode, KKC_TYPE_BIGRAM_TRELLIS_NODE, KkcBigramTrellisNode));
	bpnode = _tmp0_;
	_tmp1_ = _kkc_trellis_node_ref0 (G_TYPE_CHECK_INSTANCE_CAST (node, KKC_TYPE_BIGRAM_TRELLIS_NODE, KkcBigramTrellisNode));
	bnode = _tmp1_;
	cost = 0.0;
	_tmp2_ = bpnode;
	_tmp3_ = kkc_bigram_trellis_node_get_left_node (_tmp2_);
	_tmp4_ = _tmp3_;
	kkc_unigram_trellis_node_get_entry (_tmp4_, &_tmp5_);
	_tmp6_ = _tmp5_;
	kkc_language_model_get_bos ((KkcLanguageModel*) model, &_tmp7_);
	_tmp8_ = _tmp7_;
	if (_kkc_language_model_entry_equal (&_tmp6_, &_tmp8_) == TRUE) {
		KkcBigramTrellisNode* _tmp9_;
		KkcUnigramTrellisNode* _tmp10_;
		KkcUnigramTrellisNode* _tmp11_;
		KkcLanguageModelEntry _tmp12_ = {0};
		KkcLanguageModelEntry _tmp13_;
		KkcBigramTrellisNode* _tmp14_;
		KkcUnigramTrellisNode* _tmp15_;
		KkcUnigramTrellisNode* _tmp16_;
		KkcLanguageModelEntry _tmp17_ = {0};
		KkcLanguageModelEntry _tmp18_;
		_tmp9_ = bpnode;
		_tmp10_ = kkc_bigram_trellis_node_get_left_node (_tmp9_);
		_tmp11_ = _tmp10_;
		kkc_unigram_trellis_node_get_entry (_tmp11_, &_tmp12_);
		_tmp13_ = _tmp12_;
		_tmp14_ = bpnode;
		_tmp15_ = kkc_bigram_trellis_node_get_right_node (_tmp14_);
		_tmp16_ = _tmp15_;
		kkc_unigram_trellis_node_get_entry (_tmp16_, &_tmp17_);
		_tmp18_ = _tmp17_;
		cost += kkc_bigram_language_model_bigram_backoff_cost ((KkcBigramLanguageModel*) model, &_tmp13_, &_tmp18_);
	}
	_tmp19_ = bpnode;
	_tmp20_ = kkc_bigram_trellis_node_get_left_node (_tmp19_);
	_tmp21_ = _tmp20_;
	kkc_unigram_trellis_node_get_entry (_tmp21_, &_tmp22_);
	_tmp23_ = _tmp22_;
	_tmp24_ = bpnode;
	_tmp25_ = kkc_bigram_trellis_node_get_right_node (_tmp24_);
	_tmp26_ = _tmp25_;
	kkc_unigram_trellis_node_get_entry (_tmp26_, &_tmp27_);
	_tmp28_ = _tmp27_;
	_tmp29_ = bnode;
	_tmp30_ = kkc_bigram_trellis_node_get_left_node (_tmp29_);
	_tmp31_ = _tmp30_;
	kkc_unigram_trellis_node_get_entry (_tmp31_, &_tmp32_);
	_tmp33_ = _tmp32_;
	cost += kkc_trigram_language_model_trigram_backoff_cost (model, &_tmp23_, &_tmp28_, &_tmp33_);
	_tmp34_ = bpnode;
	_tmp35_ = kkc_bigram_trellis_node_get_right_node (_tmp34_);
	_tmp36_ = _tmp35_;
	kkc_unigram_trellis_node_get_entry (_tmp36_, &_tmp37_);
	_tmp38_ = _tmp37_;
	_tmp39_ = bnode;
	_tmp40_ = kkc_bigram_trellis_node_get_left_node (_tmp39_);
	_tmp41_ = _tmp40_;
	kkc_unigram_trellis_node_get_entry (_tmp41_, &_tmp42_);
	_tmp43_ = _tmp42_;
	_tmp44_ = bnode;
	_tmp45_ = kkc_bigram_trellis_node_get_right_node (_tmp44_);
	_tmp46_ = _tmp45_;
	kkc_unigram_trellis_node_get_entry (_tmp46_, &_tmp47_);
	_tmp48_ = _tmp47_;
	cost += kkc_trigram_language_model_trigram_backoff_cost (model, &_tmp38_, &_tmp43_, &_tmp48_);
	result = cost;
	_kkc_trellis_node_unref0 (bnode);
	_kkc_trellis_node_unref0 (bpnode);
	return result;
}

KkcBigramToBigramPathCostFunc*
kkc_bigram_to_bigram_path_cost_func_construct (GType object_type)
{
	KkcBigramToBigramPathCostFunc* self = NULL;
	self = (KkcBigramToBigramPathCostFunc*) kkc_path_cost_func_construct (object_type);
	return self;
}

KkcBigramToBigramPathCostFunc*
kkc_bigram_to_bigram_path_cost_func_new (void)
{
	return kkc_bigram_to_bigram_path_cost_func_construct (KKC_TYPE_BIGRAM_TO_BIGRAM_PATH_COST_FUNC);
}

static void
kkc_bigram_to_bigram_path_cost_func_class_init (KkcBigramToBigramPathCostFuncClass * klass,
                                                gpointer klass_data)
{
	kkc_bigram_to_bigram_path_cost_func_parent_class = g_type_class_peek_parent (klass);
	((KkcPathCostFuncClass *) klass)->path_cost = (gdouble (*) (KkcPathCostFunc*, KkcTrigramLanguageModel*, KkcTrellisNode*, KkcTrellisNode*)) kkc_bigram_to_bigram_path_cost_func_real_path_cost;
}

static void
kkc_bigram_to_bigram_path_cost_func_instance_init (KkcBigramToBigramPathCostFunc * self,
                                                   gpointer klass)
{
}

static GType
kkc_bigram_to_bigram_path_cost_func_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcBigramToBigramPathCostFuncClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_bigram_to_bigram_path_cost_func_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcBigramToBigramPathCostFunc), 0, (GInstanceInitFunc) kkc_bigram_to_bigram_path_cost_func_instance_init, NULL };
	GType kkc_bigram_to_bigram_path_cost_func_type_id;
	kkc_bigram_to_bigram_path_cost_func_type_id = g_type_register_static (KKC_TYPE_PATH_COST_FUNC, "KkcBigramToBigramPathCostFunc", &g_define_type_info, 0);
	return kkc_bigram_to_bigram_path_cost_func_type_id;
}

GType
kkc_bigram_to_bigram_path_cost_func_get_type (void)
{
	static volatile gsize kkc_bigram_to_bigram_path_cost_func_type_id__once = 0;
	if (g_once_init_enter (&kkc_bigram_to_bigram_path_cost_func_type_id__once)) {
		GType kkc_bigram_to_bigram_path_cost_func_type_id;
		kkc_bigram_to_bigram_path_cost_func_type_id = kkc_bigram_to_bigram_path_cost_func_get_type_once ();
		g_once_init_leave (&kkc_bigram_to_bigram_path_cost_func_type_id__once, kkc_bigram_to_bigram_path_cost_func_type_id);
	}
	return kkc_bigram_to_bigram_path_cost_func_type_id__once;
}

static inline gpointer
kkc_trigram_decoder_get_instance_private (KkcTrigramDecoder* self)
{
	return G_STRUCT_MEMBER_P (self, KkcTrigramDecoder_private_offset);
}

static KkcSegment**
kkc_trigram_decoder_real_decode (KkcDecoder* base,
                                 const gchar* input,
                                 gint nbest,
                                 gint* constraint,
                                 gint constraint_length1,
                                 gint* result_length1)
{
	KkcTrigramDecoder * self;
	gint _tmp0_ = 0;
	KkcSegment** _tmp1_;
	KkcSegment** _tmp2_;
	gint _tmp2__length1;
	KkcSegment** result;
	self = (KkcTrigramDecoder*) base;
	g_return_val_if_fail (input != NULL, NULL);
	_tmp1_ = kkc_decoder_decode_with_costs ((KkcDecoder*) self, input, nbest, constraint, (gint) constraint_length1, DBL_MAX, -DBL_MAX, &_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp2__length1 = _tmp0_;
	if (result_length1) {
		*result_length1 = _tmp2__length1;
	}
	result = _tmp2_;
	return result;
}

static KkcSegment**
kkc_trigram_decoder_real_decode_with_costs (KkcDecoder* base,
                                            const gchar* input,
                                            gint nbest,
                                            gint* constraint,
                                            gint constraint_length1,
                                            gdouble max_distance,
                                            gdouble min_path_cost,
                                            gint* result_length1)
{
	KkcTrigramDecoder * self;
	GeeArrayList** trellis = NULL;
	gint _tmp0_ = 0;
	GeeArrayList** _tmp1_;
	gint trellis_length1;
	gint _trellis_size_;
	gint _tmp2_ = 0;
	KkcSegment** _tmp3_;
	KkcSegment** _tmp4_;
	gint _tmp4__length1;
	KkcSegment** result;
	self = (KkcTrigramDecoder*) base;
	g_return_val_if_fail (input != NULL, NULL);
	_tmp1_ = kkc_bigram_decoder_build_trellis ((KkcBigramDecoder*) self, input, constraint, (gint) constraint_length1, &_tmp0_);
	trellis = _tmp1_;
	trellis_length1 = _tmp0_;
	_trellis_size_ = trellis_length1;
	kkc_trigram_decoder_add_trigram_nodes (self, trellis, (gint) trellis_length1);
	kkc_bigram_decoder_add_unknown_nodes ((KkcBigramDecoder*) self, trellis, (gint) trellis_length1, input, constraint, (gint) constraint_length1);
	kkc_bigram_decoder_forward_search ((KkcBigramDecoder*) self, trellis, (gint) trellis_length1, input);
	_tmp3_ = kkc_bigram_decoder_backward_search ((KkcBigramDecoder*) self, trellis, (gint) trellis_length1, nbest, max_distance, min_path_cost, &_tmp2_);
	_tmp4_ = _tmp3_;
	_tmp4__length1 = _tmp2_;
	if (result_length1) {
		*result_length1 = _tmp4__length1;
	}
	result = _tmp4_;
	trellis = (_vala_array_free (trellis, trellis_length1, (GDestroyNotify) g_object_unref), NULL);
	return result;
}

static void
kkc_trigram_decoder_add_trigram_nodes (KkcTrigramDecoder* self,
                                       GeeArrayList** trellis,
                                       gint trellis_length1)
{
	GeeArrayList** trigram_trellis = NULL;
	GeeArrayList** _tmp0_;
	gint trigram_trellis_length1;
	gint _trigram_trellis_size_;
	GeeHashSet** overlapped_nodes = NULL;
	GeeHashSet** _tmp6_;
	gint overlapped_nodes_length1;
	gint _overlapped_nodes_size_;
	g_return_if_fail (self != NULL);
	_tmp0_ = g_new0 (GeeArrayList*, trellis_length1 + 1);
	trigram_trellis = _tmp0_;
	trigram_trellis_length1 = trellis_length1;
	_trigram_trellis_size_ = trigram_trellis_length1;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				GeeArrayList** _tmp3_;
				gint _tmp3__length1;
				GeeArrayList** _tmp4_;
				gint _tmp4__length1;
				GeeArrayList* _tmp5_;
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = i;
					i = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				_tmp3_ = trigram_trellis;
				_tmp3__length1 = trigram_trellis_length1;
				if (!(i < _tmp3__length1)) {
					break;
				}
				_tmp4_ = trigram_trellis;
				_tmp4__length1 = trigram_trellis_length1;
				_tmp5_ = gee_array_list_new (KKC_TYPE_TRELLIS_NODE, (GBoxedCopyFunc) kkc_trellis_node_ref, (GDestroyNotify) kkc_trellis_node_unref, NULL, NULL, NULL);
				_g_object_unref0 (_tmp4_[i]);
				_tmp4_[i] = _tmp5_;
			}
		}
	}
	_tmp6_ = g_new0 (GeeHashSet*, trellis_length1 + 1);
	overlapped_nodes = _tmp6_;
	overlapped_nodes_length1 = trellis_length1;
	_overlapped_nodes_size_ = overlapped_nodes_length1;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp7_ = FALSE;
			_tmp7_ = TRUE;
			while (TRUE) {
				GeeHashSet** _tmp9_;
				gint _tmp9__length1;
				GeeHashSet** _tmp10_;
				gint _tmp10__length1;
				GeeHashSet* _tmp11_;
				if (!_tmp7_) {
					gint _tmp8_;
					_tmp8_ = i;
					i = _tmp8_ + 1;
				}
				_tmp7_ = FALSE;
				_tmp9_ = overlapped_nodes;
				_tmp9__length1 = overlapped_nodes_length1;
				if (!(i < _tmp9__length1)) {
					break;
				}
				_tmp10_ = overlapped_nodes;
				_tmp10__length1 = overlapped_nodes_length1;
				_tmp11_ = gee_hash_set_new (KKC_TYPE_TRELLIS_NODE, (GBoxedCopyFunc) kkc_trellis_node_ref, (GDestroyNotify) kkc_trellis_node_unref, NULL, NULL, NULL, NULL, NULL, NULL);
				_g_object_unref0 (_tmp10_[i]);
				_tmp10_[i] = _tmp11_;
			}
		}
	}
	{
		gint i = 0;
		i = 1;
		{
			gboolean _tmp12_ = FALSE;
			_tmp12_ = TRUE;
			while (TRUE) {
				if (!_tmp12_) {
					gint _tmp13_;
					_tmp13_ = i;
					i = _tmp13_ + 1;
				}
				_tmp12_ = FALSE;
				if (!(i < trellis_length1)) {
					break;
				}
				{
					GeeArrayList* _node_list = NULL;
					GeeArrayList* _tmp14_;
					gint _node_size = 0;
					GeeArrayList* _tmp15_;
					gint _tmp16_;
					gint _tmp17_;
					gint _node_index = 0;
					_tmp14_ = trellis[i];
					_node_list = _tmp14_;
					_tmp15_ = _node_list;
					_tmp16_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp15_);
					_tmp17_ = _tmp16_;
					_node_size = _tmp17_;
					_node_index = -1;
					while (TRUE) {
						gint _tmp18_;
						gint _tmp19_;
						KkcTrellisNode* node = NULL;
						GeeArrayList* _tmp20_;
						gpointer _tmp21_;
						KkcUnigramTrellisNode* unode = NULL;
						KkcTrellisNode* _tmp22_;
						KkcUnigramTrellisNode* _tmp23_;
						gint j = 0;
						KkcTrellisNode* _tmp24_;
						guint _tmp25_;
						guint _tmp26_;
						_node_index = _node_index + 1;
						_tmp18_ = _node_index;
						_tmp19_ = _node_size;
						if (!(_tmp18_ < _tmp19_)) {
							break;
						}
						_tmp20_ = _node_list;
						_tmp21_ = gee_abstract_list_get ((GeeAbstractList*) _tmp20_, _node_index);
						node = (KkcTrellisNode*) _tmp21_;
						_tmp22_ = node;
						_tmp23_ = _kkc_trellis_node_ref0 (KKC_IS_UNIGRAM_TRELLIS_NODE (_tmp22_) ? ((KkcUnigramTrellisNode*) _tmp22_) : NULL);
						unode = _tmp23_;
						_tmp24_ = node;
						_tmp25_ = kkc_trellis_node_get_length (_tmp24_);
						_tmp26_ = _tmp25_;
						j = i - ((gint) _tmp26_);
						{
							GeeArrayList* _pnode_list = NULL;
							GeeArrayList* _tmp27_;
							gint _pnode_size = 0;
							GeeArrayList* _tmp28_;
							gint _tmp29_;
							gint _tmp30_;
							gint _pnode_index = 0;
							_tmp27_ = trellis[j];
							_pnode_list = _tmp27_;
							_tmp28_ = _pnode_list;
							_tmp29_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp28_);
							_tmp30_ = _tmp29_;
							_pnode_size = _tmp30_;
							_pnode_index = -1;
							while (TRUE) {
								gint _tmp31_;
								gint _tmp32_;
								KkcTrellisNode* pnode = NULL;
								GeeArrayList* _tmp33_;
								gpointer _tmp34_;
								KkcUnigramTrellisNode* upnode = NULL;
								KkcTrellisNode* _tmp35_;
								KkcUnigramTrellisNode* _tmp36_;
								KkcBigramLanguageModel* _tmp37_;
								KkcBigramLanguageModel* _tmp38_;
								KkcUnigramTrellisNode* _tmp39_;
								KkcLanguageModelEntry _tmp40_ = {0};
								KkcLanguageModelEntry _tmp41_;
								KkcUnigramTrellisNode* _tmp42_;
								KkcLanguageModelEntry _tmp43_ = {0};
								KkcLanguageModelEntry _tmp44_;
								gint k = 0;
								KkcTrellisNode* _tmp45_;
								guint _tmp46_;
								guint _tmp47_;
								_pnode_index = _pnode_index + 1;
								_tmp31_ = _pnode_index;
								_tmp32_ = _pnode_size;
								if (!(_tmp31_ < _tmp32_)) {
									break;
								}
								_tmp33_ = _pnode_list;
								_tmp34_ = gee_abstract_list_get ((GeeAbstractList*) _tmp33_, _pnode_index);
								pnode = (KkcTrellisNode*) _tmp34_;
								_tmp35_ = pnode;
								_tmp36_ = _kkc_trellis_node_ref0 (KKC_IS_UNIGRAM_TRELLIS_NODE (_tmp35_) ? ((KkcUnigramTrellisNode*) _tmp35_) : NULL);
								upnode = _tmp36_;
								_tmp37_ = kkc_bigram_decoder_get_model ((KkcBigramDecoder*) self);
								_tmp38_ = _tmp37_;
								_tmp39_ = upnode;
								kkc_unigram_trellis_node_get_entry (_tmp39_, &_tmp40_);
								_tmp41_ = _tmp40_;
								_tmp42_ = unode;
								kkc_unigram_trellis_node_get_entry (_tmp42_, &_tmp43_);
								_tmp44_ = _tmp43_;
								if (!kkc_bigram_language_model_has_bigram (_tmp38_, &_tmp41_, &_tmp44_)) {
									_kkc_trellis_node_unref0 (upnode);
									_kkc_trellis_node_unref0 (pnode);
									continue;
								}
								_tmp45_ = pnode;
								_tmp46_ = kkc_trellis_node_get_length (_tmp45_);
								_tmp47_ = _tmp46_;
								k = j - ((gint) _tmp47_);
								if (k < 0) {
									_kkc_trellis_node_unref0 (upnode);
									_kkc_trellis_node_unref0 (pnode);
									continue;
								}
								{
									GeeArrayList* _ppnode_list = NULL;
									GeeArrayList* _tmp48_;
									gint _ppnode_size = 0;
									GeeArrayList* _tmp49_;
									gint _tmp50_;
									gint _tmp51_;
									gint _ppnode_index = 0;
									_tmp48_ = trellis[k];
									_ppnode_list = _tmp48_;
									_tmp49_ = _ppnode_list;
									_tmp50_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp49_);
									_tmp51_ = _tmp50_;
									_ppnode_size = _tmp51_;
									_ppnode_index = -1;
									while (TRUE) {
										gint _tmp52_;
										gint _tmp53_;
										KkcTrellisNode* ppnode = NULL;
										GeeArrayList* _tmp54_;
										gpointer _tmp55_;
										KkcUnigramTrellisNode* uppnode = NULL;
										KkcTrellisNode* _tmp56_;
										KkcUnigramTrellisNode* _tmp57_;
										gboolean _tmp58_ = FALSE;
										GeeHashSet** _tmp59_;
										gint _tmp59__length1;
										GeeHashSet* _tmp60_;
										KkcUnigramTrellisNode* _tmp61_;
										_ppnode_index = _ppnode_index + 1;
										_tmp52_ = _ppnode_index;
										_tmp53_ = _ppnode_size;
										if (!(_tmp52_ < _tmp53_)) {
											break;
										}
										_tmp54_ = _ppnode_list;
										_tmp55_ = gee_abstract_list_get ((GeeAbstractList*) _tmp54_, _ppnode_index);
										ppnode = (KkcTrellisNode*) _tmp55_;
										_tmp56_ = ppnode;
										_tmp57_ = _kkc_trellis_node_ref0 (KKC_IS_UNIGRAM_TRELLIS_NODE (_tmp56_) ? ((KkcUnigramTrellisNode*) _tmp56_) : NULL);
										uppnode = _tmp57_;
										_tmp59_ = overlapped_nodes;
										_tmp59__length1 = overlapped_nodes_length1;
										_tmp60_ = _tmp59_[k];
										_tmp61_ = uppnode;
										if (!gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp60_, (KkcTrellisNode*) _tmp61_)) {
											KkcBigramLanguageModel* _tmp62_;
											KkcBigramLanguageModel* _tmp63_;
											KkcUnigramTrellisNode* _tmp64_;
											KkcLanguageModelEntry _tmp65_ = {0};
											KkcLanguageModelEntry _tmp66_;
											KkcUnigramTrellisNode* _tmp67_;
											KkcLanguageModelEntry _tmp68_ = {0};
											KkcLanguageModelEntry _tmp69_;
											KkcUnigramTrellisNode* _tmp70_;
											KkcLanguageModelEntry _tmp71_ = {0};
											KkcLanguageModelEntry _tmp72_;
											_tmp62_ = kkc_bigram_decoder_get_model ((KkcBigramDecoder*) self);
											_tmp63_ = _tmp62_;
											_tmp64_ = uppnode;
											kkc_unigram_trellis_node_get_entry (_tmp64_, &_tmp65_);
											_tmp66_ = _tmp65_;
											_tmp67_ = upnode;
											kkc_unigram_trellis_node_get_entry (_tmp67_, &_tmp68_);
											_tmp69_ = _tmp68_;
											_tmp70_ = unode;
											kkc_unigram_trellis_node_get_entry (_tmp70_, &_tmp71_);
											_tmp72_ = _tmp71_;
											_tmp58_ = kkc_trigram_language_model_has_trigram (G_TYPE_CHECK_INSTANCE_CAST (_tmp63_, KKC_TYPE_TRIGRAM_LANGUAGE_MODEL, KkcTrigramLanguageModel), &_tmp66_, &_tmp69_, &_tmp72_);
										} else {
											_tmp58_ = FALSE;
										}
										if (_tmp58_) {
											KkcBigramTrellisNode* bigram_node = NULL;
											KkcUnigramTrellisNode* _tmp73_;
											KkcUnigramTrellisNode* _tmp74_;
											KkcBigramTrellisNode* _tmp75_;
											GeeArrayList** _tmp76_;
											gint _tmp76__length1;
											GeeArrayList* _tmp77_;
											KkcBigramTrellisNode* _tmp78_;
											GeeHashSet** _tmp79_;
											gint _tmp79__length1;
											GeeHashSet* _tmp80_;
											KkcUnigramTrellisNode* _tmp81_;
											_tmp73_ = uppnode;
											_tmp74_ = upnode;
											_tmp75_ = kkc_bigram_trellis_node_new (_tmp73_, _tmp74_, (guint) j);
											bigram_node = _tmp75_;
											_tmp76_ = trigram_trellis;
											_tmp76__length1 = trigram_trellis_length1;
											_tmp77_ = _tmp76_[j];
											_tmp78_ = bigram_node;
											gee_abstract_collection_add ((GeeAbstractCollection*) _tmp77_, (KkcTrellisNode*) _tmp78_);
											_tmp79_ = overlapped_nodes;
											_tmp79__length1 = overlapped_nodes_length1;
											_tmp80_ = _tmp79_[j];
											_tmp81_ = upnode;
											gee_abstract_collection_add ((GeeAbstractCollection*) _tmp80_, (KkcTrellisNode*) _tmp81_);
											_kkc_trellis_node_unref0 (bigram_node);
										}
										_kkc_trellis_node_unref0 (uppnode);
										_kkc_trellis_node_unref0 (ppnode);
									}
								}
								_kkc_trellis_node_unref0 (upnode);
								_kkc_trellis_node_unref0 (pnode);
							}
						}
						_kkc_trellis_node_unref0 (unode);
						_kkc_trellis_node_unref0 (node);
					}
				}
			}
		}
	}
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp82_ = FALSE;
			_tmp82_ = TRUE;
			while (TRUE) {
				GeeArrayList* _tmp84_;
				GeeArrayList** _tmp85_;
				gint _tmp85__length1;
				GeeArrayList* _tmp86_;
				if (!_tmp82_) {
					gint _tmp83_;
					_tmp83_ = i;
					i = _tmp83_ + 1;
				}
				_tmp82_ = FALSE;
				if (!(i < trellis_length1)) {
					break;
				}
				_tmp84_ = trellis[i];
				_tmp85_ = trigram_trellis;
				_tmp85__length1 = trigram_trellis_length1;
				_tmp86_ = _tmp85_[i];
				gee_array_list_add_all (_tmp84_, (GeeCollection*) _tmp86_);
			}
		}
	}
	overlapped_nodes = (_vala_array_free (overlapped_nodes, overlapped_nodes_length1, (GDestroyNotify) g_object_unref), NULL);
	trigram_trellis = (_vala_array_free (trigram_trellis, trigram_trellis_length1, (GDestroyNotify) g_object_unref), NULL);
}

static gint
kkc_trigram_decoder_path_to_func_index (KkcTrigramDecoder* self,
                                        KkcTrellisNode* pnode,
                                        KkcTrellisNode* node)
{
	gint _tmp0_ = 0;
	gint pnode_index = 0;
	gint _tmp1_ = 0;
	gint node_index = 0;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	g_return_val_if_fail (pnode != NULL, -1);
	g_return_val_if_fail (node != NULL, -1);
	if (KKC_IS_UNIGRAM_TRELLIS_NODE (pnode)) {
		_tmp0_ = 0;
	} else {
		_tmp0_ = 1;
	}
	pnode_index = _tmp0_;
	if (KKC_IS_UNIGRAM_TRELLIS_NODE (node)) {
		_tmp1_ = 0;
	} else {
		_tmp1_ = 1;
	}
	node_index = _tmp1_;
	result = (pnode_index << 1) + node_index;
	return result;
}

static gdouble
kkc_trigram_decoder_real_path_cost (KkcBigramDecoder* base,
                                    KkcTrellisNode* pnode,
                                    KkcTrellisNode* node,
                                    gint endpos)
{
	KkcTrigramDecoder * self;
	gint index = 0;
	KkcPathCostFunc* _tmp0_;
	KkcBigramLanguageModel* _tmp1_;
	KkcBigramLanguageModel* _tmp2_;
	gdouble result;
	self = (KkcTrigramDecoder*) base;
	g_return_val_if_fail (pnode != NULL, -1.0);
	g_return_val_if_fail (node != NULL, -1.0);
	index = kkc_trigram_decoder_path_to_func_index (self, pnode, node);
	_tmp0_ = self->priv->path_cost_funcs[index];
	_tmp1_ = kkc_bigram_decoder_get_model ((KkcBigramDecoder*) self);
	_tmp2_ = _tmp1_;
	result = kkc_path_cost_func_path_cost (_tmp0_, G_TYPE_CHECK_INSTANCE_CAST (_tmp2_, KKC_TYPE_TRIGRAM_LANGUAGE_MODEL, KkcTrigramLanguageModel), pnode, node);
	return result;
}

KkcTrigramDecoder*
kkc_trigram_decoder_construct (GType object_type,
                               KkcTrigramLanguageModel* model)
{
	KkcTrigramDecoder * self = NULL;
	KkcUnigramToUnigramPathCostFunc* _tmp0_;
	KkcUnigramToBigramPathCostFunc* _tmp1_;
	KkcBigramToUnigramPathCostFunc* _tmp2_;
	KkcBigramToBigramPathCostFunc* _tmp3_;
	g_return_val_if_fail (model != NULL, NULL);
	self = (KkcTrigramDecoder*) kkc_bigram_decoder_construct (object_type, (KkcBigramLanguageModel*) model);
	_tmp0_ = kkc_unigram_to_unigram_path_cost_func_new ();
	_kkc_path_cost_func_unref0 (self->priv->path_cost_funcs[0]);
	self->priv->path_cost_funcs[0] = (KkcPathCostFunc*) _tmp0_;
	_tmp1_ = kkc_unigram_to_bigram_path_cost_func_new ();
	_kkc_path_cost_func_unref0 (self->priv->path_cost_funcs[1]);
	self->priv->path_cost_funcs[1] = (KkcPathCostFunc*) _tmp1_;
	_tmp2_ = kkc_bigram_to_unigram_path_cost_func_new ();
	_kkc_path_cost_func_unref0 (self->priv->path_cost_funcs[2]);
	self->priv->path_cost_funcs[2] = (KkcPathCostFunc*) _tmp2_;
	_tmp3_ = kkc_bigram_to_bigram_path_cost_func_new ();
	_kkc_path_cost_func_unref0 (self->priv->path_cost_funcs[3]);
	self->priv->path_cost_funcs[3] = (KkcPathCostFunc*) _tmp3_;
	return self;
}

KkcTrigramDecoder*
kkc_trigram_decoder_new (KkcTrigramLanguageModel* model)
{
	return kkc_trigram_decoder_construct (KKC_TYPE_TRIGRAM_DECODER, model);
}

static void
kkc_trigram_decoder_class_init (KkcTrigramDecoderClass * klass,
                                gpointer klass_data)
{
	kkc_trigram_decoder_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &KkcTrigramDecoder_private_offset);
	((KkcDecoderClass *) klass)->decode = (KkcSegment** (*) (KkcDecoder*, const gchar*, gint, gint*, gint, gint*)) kkc_trigram_decoder_real_decode;
	((KkcDecoderClass *) klass)->decode_with_costs = (KkcSegment** (*) (KkcDecoder*, const gchar*, gint, gint*, gint, gdouble, gdouble, gint*)) kkc_trigram_decoder_real_decode_with_costs;
	((KkcBigramDecoderClass *) klass)->path_cost = (gdouble (*) (KkcBigramDecoder*, KkcTrellisNode*, KkcTrellisNode*, gint)) kkc_trigram_decoder_real_path_cost;
	G_OBJECT_CLASS (klass)->finalize = kkc_trigram_decoder_finalize;
}

static void
kkc_trigram_decoder_instance_init (KkcTrigramDecoder * self,
                                   gpointer klass)
{
	self->priv = kkc_trigram_decoder_get_instance_private (self);
}

static void
kkc_trigram_decoder_finalize (GObject * obj)
{
	KkcTrigramDecoder * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, KKC_TYPE_TRIGRAM_DECODER, KkcTrigramDecoder);
	_vala_array_destroy (self->priv->path_cost_funcs, 4, (GDestroyNotify) kkc_path_cost_func_unref);
	G_OBJECT_CLASS (kkc_trigram_decoder_parent_class)->finalize (obj);
}

static GType
kkc_trigram_decoder_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcTrigramDecoderClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_trigram_decoder_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcTrigramDecoder), 0, (GInstanceInitFunc) kkc_trigram_decoder_instance_init, NULL };
	GType kkc_trigram_decoder_type_id;
	kkc_trigram_decoder_type_id = g_type_register_static (KKC_TYPE_BIGRAM_DECODER, "KkcTrigramDecoder", &g_define_type_info, 0);
	KkcTrigramDecoder_private_offset = g_type_add_instance_private (kkc_trigram_decoder_type_id, sizeof (KkcTrigramDecoderPrivate));
	return kkc_trigram_decoder_type_id;
}

GType
kkc_trigram_decoder_get_type (void)
{
	static volatile gsize kkc_trigram_decoder_type_id__once = 0;
	if (g_once_init_enter (&kkc_trigram_decoder_type_id__once)) {
		GType kkc_trigram_decoder_type_id;
		kkc_trigram_decoder_type_id = kkc_trigram_decoder_get_type_once ();
		g_once_init_leave (&kkc_trigram_decoder_type_id__once, kkc_trigram_decoder_type_id);
	}
	return kkc_trigram_decoder_type_id__once;
}

static void
_vala_array_destroy (gpointer array,
                     gssize array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}

static void
_vala_array_free (gpointer array,
                  gssize array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}

