Home | History | Annotate | Download | only in src
      1 /*
      2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
      3  *
      4  * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
      5  *
      6  * The contents of this file are subject to the terms of either the GNU Lesser
      7  * General Public License Version 2.1 only ("LGPL") or the Common Development and
      8  * Distribution License ("CDDL")(collectively, the "License"). You may not use this
      9  * file except in compliance with the License. You can obtain a copy of the CDDL at
     10  * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at
     11  * http://www.opensource.org/licenses/lgpl-license.php. See the License for the
     12  * specific language governing permissions and limitations under the License. When
     13  * distributing the software, include this License Header Notice in each file and
     14  * include the full text of the License in the License file as well as the
     15  * following notice:
     16  *
     17  * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
     18  * (CDDL)
     19  * For Covered Software in this distribution, this License shall be governed by the
     20  * laws of the State of California (excluding conflict-of-law provisions).
     21  * Any litigation relating to this License shall be subject to the jurisdiction of
     22  * the Federal Courts of the Northern District of California and the state courts
     23  * of the State of California, with venue lying in Santa Clara County, California.
     24  *
     25  * Contributor(s):
     26  *
     27  * If you wish your version of this file to be governed by only the CDDL or only
     28  * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to
     29  * include this software in this distribution under the [CDDL or LGPL Version 2.1]
     30  * license." If you don't indicate a single choice of license, a recipient has the
     31  * option to distribute your version of this file under either the CDDL or the LGPL
     32  * Version 2.1, or to extend the choice of license to its licensees as provided
     33  * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL
     34  * Version 2 license, then the option applies only if the new code is made subject
     35  * to such option by the copyright holder.
     36  */
     37 
     38 #ifndef SUNPY_LATTICE_STATES_H
     39 #define SUNPY_LATTICE_STATES_H
     40 
     41 #include "portability.h"
     42 
     43 #include "imi_context.h"
     44 
     45 /**
     46  * CStateKey represent the history. In real implementation, it's a
     47  * node pointer to a state in the language model. But to save the
     48  * language model size, the state node in language model do not
     49  * thread the back-off pointer. Now, we just use the Word Id for
     50  * the node in the language model. Later we should abstract the
     51  * StateNode from language model implemetation to replace this
     52  * definition.
     53  */
     54 typedef CThreadSlm::TState          CStateKey;
     55 
     56 /**
     57  * A WordKey could represent a word. Define this use the unsigned int
     58  * directly. Because in the future, we may adopt word class, such as
     59  * Digital Word Class.
     60  */
     61 typedef unsigned                    CWordKey;
     62 
     63 /**
     64  * This class is used to record lexicon state (pinyin trie nodes)
     65  * just before a bone. From the bone, it could see when arriving
     66  * it, how many valid Pinyin Trie Node still could be used to search
     67  * more words further, and what bone is its starting bone.
     68  */
     69 struct CLexiconState {
     70 public:
     71     /**
     72      * The bone where m_pPYNode starts
     73      */
     74     CSkeletonIter                   m_BoneStart;
     75 
     76     /**
     77      * PinYin trie node, from which we could get its corresponding
     78      * words (if it contains some), and search further for longer
     79      * words.
     80      */
     81     const CPinyinTrie::TNode       *m_pPYNode;
     82 
     83     /**
     84      * If is not a PINYIN state, we should use the m_WordId directly.
     85      */
     86     bool                            m_bPinyin;
     87 
     88     /**
     89      * the word id for normal string, like english string, punc, etc.
     90      */
     91     unsigned int                    m_WordId;
     92 
     93 public:
     94     CLexiconState(const CLexiconState& b)
     95         : m_BoneStart(b.m_BoneStart), m_pPYNode(b.m_pPYNode),
     96           m_bPinyin(b.m_bPinyin), m_WordId(b.m_WordId) { }
     97 
     98     CLexiconState(CSkeletonIter boneStart = CSkeletonIter(),
     99                   const CPinyinTrie::TNode *pynptr = NULL)
    100         : m_BoneStart(boneStart), m_pPYNode(pynptr),
    101           m_bPinyin(true), m_WordId(0) { }
    102 
    103     CLexiconState(CSkeletonIter boneStart, unsigned int wid)
    104         : m_BoneStart(boneStart), m_pPYNode(NULL),
    105           m_bPinyin(false), m_WordId(wid) { }
    106 };
    107 
    108 /**
    109  * A list of Lexicon State. Every state may from different
    110  * starting position. Later, when Fuzzy PinYin are added,
    111  * more than one state may comes from one starting bone.
    112  */
    113 typedef std::vector<CLexiconState>    CLexiconStates;
    114 
    115 
    116 /**
    117  * The basic static unit used in the lattice searching
    118  */
    119 struct TLatticeState {
    120 public:
    121 
    122     /**
    123      * The score from the beginning of the sentence to here
    124      * pr(w1)*pr(w2|w1)*... or its log format
    125      */
    126     TSentenceScore                  m_Score;
    127 
    128     /**
    129      * The bone right after this lattice node.
    130      */
    131     CSkeletonIter                   m_BoneAfter;
    132 
    133     /**
    134      * The history key
    135      */
    136     CStateKey                       m_State;
    137 
    138     /**
    139      * prevState --- word ---> thisState
    140      * BackTraceNode record the best prevState that make thisState
    141      * best score.
    142      */
    143     TLatticeState                  *m_pBackTraceNode;
    144 
    145     /**
    146      * BackTraceWordId record the best word's id that make thisState
    147      * best score
    148      */
    149     CWordKey                        m_BackTraceWordId;
    150 
    151     /** for debug printing... */
    152     void
    153     print(std::string& prefix);
    154 
    155 public:
    156     /**
    157      * Default constructor
    158      */
    159     #ifdef _USE_RAW_PROBABILITY
    160     TLatticeState(double score = -1.0,
    161     #else
    162     TLatticeState(double score = 0.0,
    163     #endif
    164                   CSkeletonIter bone=CSkeletonIter(),
    165                   TLatticeState* btNodePtr = NULL,
    166                   CStateKey sk= CStateKey(),
    167                   CWordKey wk = CWordKey())
    168         : m_Score(score), m_BoneAfter(bone), m_State(sk),
    169           m_pBackTraceNode(btNodePtr), m_BackTraceWordId(wk) { }
    170 
    171 };
    172 
    173 typedef std::vector<TLatticeState>  CLatticeStateVec;
    174 
    175 
    176 /**
    177  * All lattice node before a single bone. This class provide beam pruning
    178  * while push_back, which means at most the best MAX states are reserved,
    179  * ie, weak state will may be discard while new better state are inserted,
    180  * and the number MAX is arrived.
    181  */
    182 class CLatticeStates {
    183 private:
    184     static const unsigned beam_width = 32;
    185 
    186 public:
    187     /** just use the CLatticeStateVec's iterator */
    188     typedef CLatticeStateVec::iterator        iterator;
    189 
    190     /** just use the CLatticeStateVec's iterator */
    191     typedef CLatticeStateVec::const_iterator  const_iterator;
    192 
    193 public:
    194     void
    195     clear();
    196 
    197     void
    198     push_back(const TLatticeState& node);
    199 
    200     //@{
    201     /** return the first iterator of m_Vec. */
    202     size_t
    203     size()
    204         { return m_Vec.size(); }
    205 
    206     iterator
    207     begin()
    208         { return m_Vec.begin(); }
    209 
    210     /** return the first iterator of m_Vec. */
    211     const_iterator
    212     begin() const
    213         { return m_Vec.begin(); }
    214     //@}
    215 
    216 
    217     //@{
    218     /** return the last iterator of m_Vec. */
    219     iterator
    220     end()
    221         { return m_Vec.end(); }
    222 
    223     /** return the last iterator of m_Vec. */
    224     const_iterator
    225     end() const
    226         { return m_Vec.end(); }
    227     //@}
    228 
    229 
    230 protected:
    231     void
    232     bubbleUp(int idxInHeap);
    233 
    234     void
    235     ironDown(int idxInHeap);
    236 
    237 protected:
    238     std::vector<TLatticeState>      m_Vec;
    239     std::vector<int>                m_VecIdxInHeap;
    240     std::map<CStateKey, int>        m_Map;
    241     std::vector<int>                m_Heap;
    242 };
    243 
    244 
    245 /**
    246  * Bone Inner Data is used to construct the search lattice. Logically,
    247  * each bone just like the time fram as in the speech recoginition.
    248  * Many information when searching arrived right before the bone are needed.
    249  *    - The Pinyin Trie States start from previous bones, and not terminated
    250  *      yet. From these states, we could look further to find longer words.
    251  *    - All Lattice State (which is already after beam-pruning). They are
    252  *      basic units of the Lattice.
    253  * Any other information also needed to help the interaction with user:
    254  *    - Best word start righ from the bone. A best word in the best
    255  *      sentence is an edge of the best path.
    256  *    - Best word type.
    257  *       -# Whether there is a best word start right before the bone? Best
    258  *          words are not overlaped and many bones may contains no best word.
    259  *       -# Whether the best word is user-selected. Some best word is user
    260  *          selected, and may be really diffirent with what we found according
    261  *          to Language Model.
    262  */
    263 class CBoneInnerData {
    264 public:
    265     /** values used by m_BWType to reflect the m_BestWord status */
    266     enum {
    267         NoBestWordStartHere, /**< best word not start here. m_bestWod invalid.*/
    268         BestWordStartHere, /**< m_BestWord is valid, but not user selected.*/
    269         UserSelectedBestWord /**< m_BestWord is the user selected best word.*/
    270     };
    271 
    272     /**
    273      * The best word start from here. A best word in the best sentence is
    274      * an edge of the best path.
    275      */
    276     CCandidate                      m_BestWord;
    277 
    278     /**
    279      * m_BWType reflects the m_BestWord status:
    280      *    -# Is there a best word start here?
    281      *    -# Whether or not it is user selected?
    282      */
    283     int                             m_BWType;
    284 
    285     /**
    286      * Lexicon status list just before this bone.
    287      */
    288     CLexiconStates                  m_LexiconStates;
    289 
    290     /**
    291      * Lattice status list just before this bone.
    292      */
    293     CLatticeStates                  m_LatticeNodes;
    294 
    295 public:
    296     CBoneInnerData()
    297         : m_BestWord(), m_BWType(NoBestWordStartHere),
    298           m_LexiconStates(), m_LatticeNodes() { }
    299     /**
    300      * clear LatticeNodes and LexiconStates,
    301      * set the BWType to NoBestWordStartHere.
    302      */
    303     void
    304     clear()
    305         {
    306             m_BWType = NoBestWordStartHere;
    307             m_LatticeNodes.clear();
    308             m_LexiconStates.clear();
    309         }
    310 
    311     void
    312     print(std::string& prefix);
    313 };
    314 
    315 
    316 #endif
    317