- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
buildTree sentence graph =
(M.lookup (0, length sentence - 1, DirLeft) finalGraph, finalGraph)
where finalGraph = execState runEisner (M.fromList elementaryPathes)
elementaryPathes =
map (\(i, word) -> ((i, i, DirLeft), elementaryPath DirLeft word)) indexed ++
map (\(i, word) -> ((i, i, DirRight), elementaryPath DirRight word)) indexed
indexed = zip [0..] sentence
runEisner = do
let len = length sentence
forM_ [1 .. len - 1] $ \l -> do
forM [0 .. len - 1 - l] $ \i -> do
matrix <- get
let j = i + l
let w1 = sentence !! i
let w2 = sentence !! j
let buildConcat dir = (catMaybes $ (zipWith (\p1 p2 -> join $ (liftM2 concatenatePath) p1 p2)
[M.lookup (i, k, dir) matrix | k <- [i + 1 .. j - 1]]
[M.lookup (k, j, dir) matrix | k <- [i + 1 .. j - 1]])) :: [Path]
let buildJoin dir key = fromMaybe [] $ M.lookup key graph >>= \link ->
return (catMaybes (zipWith (\p1 p2 -> join $ (liftM2 (\f c -> joinPath f c link)) p1 p2)
[M.lookup (i, k, dir) matrix | k <- [i .. j - 1]]
[M.lookup (k, j, rev dir) matrix | k <- [i + 1 .. j]]))
let posR = (buildConcat DirRight ++ buildJoin DirRight (w1, w2)) :: [Path]
let newMatrix = if (not . null) posR
then M.insert (i, j, DirRight) (minimumBy compWeight posR) matrix
else matrix
let posL = buildConcat DirLeft ++ buildJoin DirRight (w2, w1)
let newMatrix' = if (not . null) posL
then M.insert (i, j, DirLeft) (minimumBy compWeight posL) matrix
else newMatrix
put newMatrix'
Кусок из диплома по NLP. Yuuri неделю как познал монаду State и сделал двумерный императивный цыкл.