diff --git a/Data/CRF/Chain1/Constrained.hs b/Data/CRF/Chain1/Constrained.hs
--- a/Data/CRF/Chain1/Constrained.hs
+++ b/Data/CRF/Chain1/Constrained.hs
@@ -9,10 +9,9 @@
   Word (..)
 , unknown
 , Sent
-, Dist (unDist)
-, mkDist
+, Prob (unProb)
+, mkProb
 , WordL
-, annotate
 , SentL
 
 -- * CRF
diff --git a/Data/CRF/Chain1/Constrained/Dataset/Codec.hs b/Data/CRF/Chain1/Constrained/Dataset/Codec.hs
--- a/Data/CRF/Chain1/Constrained/Dataset/Codec.hs
+++ b/Data/CRF/Chain1/Constrained/Dataset/Codec.hs
@@ -98,7 +98,7 @@
     let x = mkX x' r'
     y  <- mkY <$> sequence
     	[ (,) <$> encodeLbU lb <*> pure pr
-	| (lb, pr) <- (M.toList . unDist) choice ]
+	| (lb, pr) <- (M.toList . unProb) choice ]
     return (x, y)
 
 -- | Encodec the labeled word and do *not* update the codec.
@@ -109,7 +109,7 @@
     let x = mkX x' r'
     y  <- mkY <$> sequence
     	[ (,) <$> encodeLbN lb <*> pure pr
-	| (lb, pr) <- (M.toList . unDist) choice ]
+	| (lb, pr) <- (M.toList . unProb) choice ]
     return (x, y)
 
 -- | Encode the word and update the codec.
diff --git a/Data/CRF/Chain1/Constrained/Dataset/External.hs b/Data/CRF/Chain1/Constrained/Dataset/External.hs
--- a/Data/CRF/Chain1/Constrained/Dataset/External.hs
+++ b/Data/CRF/Chain1/Constrained/Dataset/External.hs
@@ -2,10 +2,9 @@
 ( Word (..)
 , unknown
 , Sent
-, Dist (unDist)
-, mkDist
+, Prob (unProb)
+, mkProb
 , WordL
-, annotate
 , SentL
 ) where
 
@@ -34,29 +33,26 @@
 -- | A probability distribution defined over elements of type a.
 -- All elements not included in the map have probability equal
 -- to 0.
-newtype Dist a = Dist { unDist :: M.Map a Double }
+newtype Prob a = Prob { unProb :: M.Map a Double }
+    deriving (Show, Eq, Ord)
 
 -- | Construct the probability distribution.
-mkDist :: Ord a => [(a, Double)] -> Dist a
-mkDist =
-    Dist . normalize . M.fromListWith (+)
+mkProb :: Ord a => [(a, Double)] -> Prob a
+mkProb =
+    Prob . normalize . M.fromListWith (+) . filter ((>0).snd)
   where
-    normalize dist =
-        let z = sum (M.elems dist)
-        in  fmap (/z) dist
+    normalize dist 
+        | M.null dist  =
+            error "mkProb: no elements with positive probability"
+        | otherwise     =
+            let z = sum (M.elems dist)
+            in  fmap (/z) dist
 
 -- | A WordL is a labeled word, i.e. a word with probability distribution
 -- defined over labels.  We assume that every label from the distribution
 -- domain is a member of the set of potential labels corresponding to the
 -- word.  TODO: Ensure the assumption using the smart constructor.
-type WordL a b = (Word a b, Dist b)
-
--- | Annotate the word with the label.
-annotate :: Ord b => Word a b -> b -> WordL a b
-annotate w x
-    | x `S.member` lbs w    = (w, Dist (M.singleton x 1))
-    | otherwise             =
-        error "annotate: label not in the set of potential interpretations"
+type WordL a b = (Word a b, Prob b)
 
 -- | A sentence of labeled words.
 type SentL a b = [WordL a b]
diff --git a/Data/CRF/Chain1/Constrained/Train.hs b/Data/CRF/Chain1/Constrained/Train.hs
--- a/Data/CRF/Chain1/Constrained/Train.hs
+++ b/Data/CRF/Chain1/Constrained/Train.hs
@@ -16,7 +16,7 @@
 import qualified Numeric.SGD.LogSigned as L
 
 import Data.CRF.Chain1.Constrained.Dataset.Internal
-import Data.CRF.Chain1.Constrained.Dataset.External (SentL, unknown, unDist)
+import Data.CRF.Chain1.Constrained.Dataset.External (SentL, unknown, unProb)
 import Data.CRF.Chain1.Constrained.Dataset.Codec
     (mkCodec, Codec, obMax, lbMax, encodeDataL, encodeLabels)
 import Data.CRF.Chain1.Constrained.Feature (Feature, featuresIn)
@@ -76,7 +76,7 @@
   where
     onSent = concatMap onWord
     onWord word
-        | unknown (fst word)    = M.keys . unDist . snd $ word
+        | unknown (fst word)    = M.keys . unProb . snd $ word
         | otherwise             = []
 
 gradOn :: Model -> SGD.Para -> (Xs, Ys) -> SGD.Grad
diff --git a/crf-chain1-constrained.cabal b/crf-chain1-constrained.cabal
--- a/crf-chain1-constrained.cabal
+++ b/crf-chain1-constrained.cabal
@@ -1,5 +1,5 @@
 name:               crf-chain1-constrained
-version:            0.1.1
+version:            0.1.2
 synopsis:           First-order, constrained, linear-chain conditional random fields
 description:
     The library provides efficient implementation of the first-order,
