blob: 25419cec601f67a11f977a7ddf7e5ca1ec2c39cc [file] [log] [blame]
// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef MOZC_CONVERTER_NBEST_GENERATOR_H_
#define MOZC_CONVERTER_NBEST_GENERATOR_H_
#include <string>
#include <vector>
#include "base/freelist.h"
#include "base/port.h"
#include "base/scoped_ptr.h"
#include "converter/candidate_filter.h"
#include "converter/segments.h"
#include "dictionary/suppression_dictionary.h"
#include "dictionary/pos_matcher.h"
namespace mozc {
class Connector;
class Lattice;
class Segmenter;
class SuggestionFilter;
struct Node;
class NBestGenerator {
public:
enum BoundaryCheckMode {
// Boundary check mode.
// For the case like;
// Candidate edge: | candidate |
// Nodes: |Node A|Node B|Node C|Node D|
// For normal converison.
// Candidate boundary is strictly same as inner boundary.
// A-B: Should be the boundary
// B-C: Should not be the boundary
// C-D: Should be the boundary
STRICT = 0,
// For resegmented segment.
// Check mid point only.
// A-B: Don't care
// B-C: Should not be the boundary
// C-D: Don't care
ONLY_MID,
// For Realtime conversion ("私の名前は中野です").
// Check only for candidate edge.
// A-B: Should be the boundary
// B-C: Don't care
// C-D: Should be the boundary
ONLY_EDGE,
};
// Try to enumurate N-best results between begin_node and end_node.
NBestGenerator(
const dictionary::SuppressionDictionary *suppression_dictionary,
const Segmenter *segmenter,
const Connector *connector,
const dictionary::POSMatcher *pos_matcher,
const Lattice *lattice,
const SuggestionFilter *suggestion_filter);
~NBestGenerator();
// Reset the iterator status.
void Reset(const Node *begin_node, const Node *end_node,
const BoundaryCheckMode mode);
// Iterator:
// Can obtain N-best results by calling Next() in sequence.
bool Next(const string &original_key,
Segment::Candidate *candidate,
Segments::RequestType request_type);
private:
enum BoundaryCheckResult {
VALID = 0,
VALID_WEAK_CONNECTED, // Valid but should get penalty.
INVALID,
};
typedef BoundaryCheckResult (NBestGenerator::*BoundaryChecker)(
const Node *, const Node *, bool) const;
struct QueueElement;
struct QueueElementComparator;
// This is just a priority_queue of const QueueElement*, but supports
// more operations in addition to std::priority_queue.
class Agenda {
public:
Agenda() {
}
~Agenda() {
}
const QueueElement *Top() const {
return priority_queue_.front();
}
bool IsEmpty() const {
return priority_queue_.empty();
}
void Clear() {
priority_queue_.clear();
}
void Reserve(int size) {
priority_queue_.reserve(size);
}
void Push(const QueueElement *element);
void Pop();
private:
vector<const QueueElement*> priority_queue_;
DISALLOW_COPY_AND_ASSIGN(Agenda);
};
int InsertTopResult(const string &original_key,
Segment::Candidate *candidate,
Segments::RequestType request_type);
void MakeCandidate(Segment::Candidate *candidate,
int32 cost, int32 structure_cost, int32 wcost,
const vector<const Node *> &nodes) const;
// Helper functions for Next(). Checks node boundary conditions.
BoundaryCheckResult CheckStrict(
const Node *lnode, const Node *rnode, bool is_edge) const;
BoundaryCheckResult CheckOnlyMid(
const Node *lnode, const Node *rnode, bool is_edge) const;
BoundaryCheckResult CheckOnlyEdge(
const Node *lnode, const Node *rnode, bool is_edge) const;
int GetTransitionCost(const Node *lnode, const Node *rnode) const;
// Create queue element from freelist
const QueueElement *CreateNewElement(const Node *node,
const QueueElement *next,
int32 fx,
int32 gx,
int32 structure_gx,
int32 w_gx);
// References to relevant modules.
const dictionary::SuppressionDictionary *suppression_dictionary_;
const Segmenter *segmenter_;
const Connector *connector_;
const dictionary::POSMatcher *pos_matcher_;
const Lattice *lattice_;
const Node *begin_node_;
const Node *end_node_;
Agenda agenda_;
FreeList<QueueElement> freelist_;
vector<const Node *> nodes_;
scoped_ptr<converter::CandidateFilter> filter_;
bool viterbi_result_checked_;
BoundaryCheckMode check_mode_;
BoundaryChecker boundary_checker_;
DISALLOW_COPY_AND_ASSIGN(NBestGenerator);
};
} // namespace mozc
#endif // MOZC_CONVERTER_NBEST_GENERATOR_H_