/usr/share/doc/libghc-markov-chain-doc/html/src/Data-MarkovChain.html is in libghc-markov-chain-doc 0.0.3.2-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
<title>src/Data/MarkovChain.hs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
<pre><a name="line-1"></a><span class='hs-comment'>{- |
<a name="line-2"></a>Copyright : (c) Henning Thielemann 2007
<a name="line-3"></a>
<a name="line-4"></a>Maintainer : haskell@henning-thielemann.de
<a name="line-5"></a>Stability : stable
<a name="line-6"></a>Portability : Haskell 98
<a name="line-7"></a>
<a name="line-8"></a>Markov chains can be used to recompose a list of elements
<a name="line-9"></a>respecting the fact that the probability of a certain element
<a name="line-10"></a>depends on preceding elements in the list.
<a name="line-11"></a>-}</span>
<a name="line-12"></a>
<a name="line-13"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>MarkovChain</span> <span class='hs-layout'>(</span><span class='hs-varid'>run</span><span class='hs-layout'>,</span> <span class='hs-varid'>runMulti</span><span class='hs-layout'>,</span> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-14"></a>
<a name="line-15"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Map</span> <span class='hs-layout'>(</span><span class='hs-conid'>Map</span><span class='hs-layout'>)</span>
<a name="line-16"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Map</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>Map</span>
<a name="line-17"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>System</span><span class='hs-varop'>.</span><span class='hs-conid'>Random</span> <span class='hs-layout'>(</span><span class='hs-conid'>RandomGen</span><span class='hs-layout'>,</span> <span class='hs-varid'>randomR</span><span class='hs-layout'>)</span>
<a name="line-18"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-varop'>.</span><span class='hs-conid'>Trans</span><span class='hs-varop'>.</span><span class='hs-conid'>State</span> <span class='hs-layout'>(</span><span class='hs-conid'>State</span><span class='hs-layout'>,</span> <span class='hs-varid'>state</span><span class='hs-layout'>,</span> <span class='hs-varid'>evalState</span><span class='hs-layout'>)</span>
<a name="line-19"></a>
<a name="line-20"></a>
<a name="line-21"></a><a name="run"></a><span class='hs-comment'>{- |
<a name="line-22"></a>Creates a chain of elements
<a name="line-23"></a>respecting to the probabilities of possible successors.
<a name="line-24"></a>The list is considered being cyclic in order
<a name="line-25"></a>to have successors for the last elements.
<a name="line-26"></a>
<a name="line-27"></a>Example:
<a name="line-28"></a>
<a name="line-29"></a>> take 100 $ run 2 "The sad cat sat on the mat. " 0 (Random.mkStdGen 123)
<a name="line-30"></a>
<a name="line-31"></a>-}</span>
<a name="line-32"></a><span class='hs-definition'>run</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>RandomGen</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span>
<a name="line-33"></a> <span class='hs-conid'>Int</span> <span class='hs-comment'>-- ^ size of prediction context</span>
<a name="line-34"></a> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-comment'>-- ^ training sequence, the one to walk through randomly</span>
<a name="line-35"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-comment'>-- ^ index to start the random walk within the training sequence</span>
<a name="line-36"></a> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>g</span> <span class='hs-comment'>-- ^ random generator state</span>
<a name="line-37"></a> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span>
<a name="line-38"></a><span class='hs-definition'>run</span> <span class='hs-varid'>n</span> <span class='hs-varid'>dict</span> <span class='hs-varid'>start</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span>
<a name="line-39"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>keyError</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>error</span> <span class='hs-str'>"key is not contained in dictionary"</span>
<a name="line-40"></a> <span class='hs-varid'>fm</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>createMap</span> <span class='hs-varid'>n</span> <span class='hs-varid'>dict</span>
<a name="line-41"></a> <span class='hs-comment'>{- This is the main function of this program.
<a name="line-42"></a> It is quite involved.
<a name="line-43"></a> If you want to understand it,
<a name="line-44"></a> imagine that the list 'y' completely exists
<a name="line-45"></a> before the computation. -}</span>
<a name="line-46"></a> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>take</span> <span class='hs-varid'>n</span> <span class='hs-layout'>(</span><span class='hs-varid'>drop</span> <span class='hs-varid'>start</span> <span class='hs-varid'>dict</span><span class='hs-layout'>)</span> <span class='hs-varop'>++</span>
<a name="line-47"></a> <span class='hs-comment'>-- run them on the initial random generator state</span>
<a name="line-48"></a> <span class='hs-layout'>(</span><span class='hs-varid'>flip</span> <span class='hs-varid'>evalState</span> <span class='hs-varid'>g</span> <span class='hs-varop'>$</span>
<a name="line-49"></a> <span class='hs-comment'>-- this turns the list of possible successors</span>
<a name="line-50"></a> <span class='hs-comment'>-- into an action that generate a list</span>
<a name="line-51"></a> <span class='hs-comment'>-- of randomly chosen items</span>
<a name="line-52"></a> <span class='hs-varid'>mapM</span>
<a name="line-53"></a> <span class='hs-layout'>(</span><span class='hs-varid'>randomItem</span> <span class='hs-varop'>.</span>
<a name="line-54"></a> <span class='hs-comment'>-- lookup all possible successors of an infix</span>
<a name="line-55"></a> <span class='hs-varid'>flip</span> <span class='hs-layout'>(</span><span class='hs-conid'>Map</span><span class='hs-varop'>.</span><span class='hs-varid'>findWithDefault</span> <span class='hs-varid'>keyError</span><span class='hs-layout'>)</span> <span class='hs-varid'>fm</span> <span class='hs-varop'>.</span>
<a name="line-56"></a> <span class='hs-comment'>-- turn suffix into an infixes of length n</span>
<a name="line-57"></a> <span class='hs-varid'>take</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span>
<a name="line-58"></a> <span class='hs-varid'>iterate</span> <span class='hs-varid'>tail</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span>
<a name="line-59"></a> <span class='hs-keyword'>in</span> <span class='hs-varid'>y</span>
<a name="line-60"></a>
<a name="line-61"></a>
<a name="line-62"></a><a name="runMulti"></a><span class='hs-definition'>runMulti</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>RandomGen</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span>
<a name="line-63"></a> <span class='hs-conid'>Int</span> <span class='hs-comment'>-- ^ size of prediction context</span>
<a name="line-64"></a> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span><span class='hs-keyglyph'>]</span> <span class='hs-comment'>-- ^ training sequences, the order is relevant</span>
<a name="line-65"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-comment'>-- ^ index of starting training sequence</span>
<a name="line-66"></a> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>g</span> <span class='hs-comment'>-- ^ random generator state</span>
<a name="line-67"></a> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span><span class='hs-keyglyph'>]</span>
<a name="line-68"></a><span class='hs-definition'>runMulti</span> <span class='hs-varid'>n</span> <span class='hs-varid'>dicts</span> <span class='hs-varid'>i</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span>
<a name="line-69"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>wrappedDicts</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-conid'>Nothing</span> <span class='hs-conop'>:</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>map</span> <span class='hs-conid'>Just</span><span class='hs-layout'>)</span> <span class='hs-varid'>dicts</span>
<a name="line-70"></a> <span class='hs-varid'>k</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sum</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>length</span> <span class='hs-layout'>(</span><span class='hs-varid'>take</span> <span class='hs-varid'>i</span> <span class='hs-varid'>wrappedDicts</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-71"></a> <span class='hs-varid'>xs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>run</span> <span class='hs-varid'>n</span> <span class='hs-layout'>(</span><span class='hs-varid'>concat</span> <span class='hs-varid'>wrappedDicts</span><span class='hs-layout'>)</span> <span class='hs-varid'>k</span> <span class='hs-varid'>g</span>
<a name="line-72"></a> <span class='hs-layout'>(</span><span class='hs-conid'>[]</span><span class='hs-layout'>,</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>segment</span> <span class='hs-layout'>(</span><span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <span class='hs-conid'>Right</span><span class='hs-layout'>)</span> <span class='hs-varid'>xs</span>
<a name="line-73"></a> <span class='hs-keyword'>in</span> <span class='hs-varid'>map</span> <span class='hs-varid'>snd</span> <span class='hs-varid'>ys</span>
<a name="line-74"></a>
<a name="line-75"></a><span class='hs-comment'>{-
<a name="line-76"></a>runMulti :: (Ord a, RandomGen g) =>
<a name="line-77"></a> Int -- ^ size of prediction context
<a name="line-78"></a> -> [[a]] -- ^ training sequences, the order is relevant
<a name="line-79"></a> -> (Int,Int) -- ^ index to start the random walk within a training sequence
<a name="line-80"></a> -> g -- ^ random generator state
<a name="line-81"></a> -> [[a]]
<a name="line-82"></a>runMulti n dicts (i,j) g =
<a name="line-83"></a> let wrappedDicts = map ((Nothing :) . map Just) dicts
<a name="line-84"></a> k = sum (map length (take i wrappedDicts)) + j
<a name="line-85"></a> xs = run n (concat wrappedDicts) k g
<a name="line-86"></a> (y, ys) = segment (maybe (Left ()) Right) xs
<a name="line-87"></a> in y : map snd ys
<a name="line-88"></a>-}</span>
<a name="line-89"></a>
<a name="line-90"></a><a name="segment"></a><span class='hs-definition'>segment</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Either</span> <span class='hs-varid'>b</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>c</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-layout'>,</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>c</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-91"></a><span class='hs-definition'>segment</span> <span class='hs-varid'>p</span> <span class='hs-keyglyph'>=</span>
<a name="line-92"></a> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>~</span><span class='hs-layout'>(</span><span class='hs-varid'>y</span><span class='hs-layout'>,</span><span class='hs-varid'>ys</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span>
<a name="line-93"></a> <span class='hs-varid'>either</span>
<a name="line-94"></a> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>[]</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-layout'>,</span><span class='hs-varid'>y</span><span class='hs-layout'>)</span><span class='hs-conop'>:</span><span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-95"></a> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>c</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>c</span><span class='hs-conop'>:</span><span class='hs-varid'>y</span><span class='hs-layout'>,</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-96"></a> <span class='hs-layout'>(</span><span class='hs-varid'>p</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>[]</span><span class='hs-layout'>,</span> <span class='hs-conid'>[]</span><span class='hs-layout'>)</span>
<a name="line-97"></a>
<a name="line-98"></a><a name="randomItem"></a><span class='hs-comment'>{- |
<a name="line-99"></a>Choose a random item from a list.
<a name="line-100"></a>-}</span>
<a name="line-101"></a><span class='hs-definition'>randomItem</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>RandomGen</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>State</span> <span class='hs-varid'>g</span> <span class='hs-varid'>a</span>
<a name="line-102"></a><span class='hs-definition'>randomItem</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fmap</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-varop'>!!</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>randomRState</span> <span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>,</span> <span class='hs-varid'>length</span> <span class='hs-varid'>x</span> <span class='hs-comment'>-</span> <span class='hs-num'>1</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-103"></a>
<a name="line-104"></a><a name="randomRState"></a><span class='hs-comment'>{- |
<a name="line-105"></a>'System.Random.randomR' wrapped in a State monad.
<a name="line-106"></a>-}</span>
<a name="line-107"></a><span class='hs-definition'>randomRState</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>RandomGen</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span><span class='hs-conid'>Int</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>State</span> <span class='hs-varid'>g</span> <span class='hs-conid'>Int</span>
<a name="line-108"></a><span class='hs-definition'>randomRState</span> <span class='hs-varid'>bnds</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>state</span> <span class='hs-layout'>(</span><span class='hs-varid'>randomR</span> <span class='hs-varid'>bnds</span><span class='hs-layout'>)</span>
<a name="line-109"></a>
<a name="line-110"></a><a name="createMap"></a><span class='hs-comment'>{- |
<a name="line-111"></a>Create a map that lists for each string all possible successors.
<a name="line-112"></a>-}</span>
<a name="line-113"></a><span class='hs-definition'>createMap</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Map</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span>
<a name="line-114"></a><span class='hs-definition'>createMap</span> <span class='hs-varid'>n</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span>
<a name="line-115"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>xc</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cycle</span> <span class='hs-varid'>x</span>
<a name="line-116"></a> <span class='hs-comment'>-- list of the map keys</span>
<a name="line-117"></a> <span class='hs-varid'>sufxs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-varid'>take</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>iterate</span> <span class='hs-varid'>tail</span> <span class='hs-varid'>xc</span><span class='hs-layout'>)</span>
<a name="line-118"></a> <span class='hs-comment'>-- list of the map images, i.e. single element lists</span>
<a name="line-119"></a> <span class='hs-varid'>imgxs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-conop'>:</span><span class='hs-conid'>[]</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>drop</span> <span class='hs-varid'>n</span> <span class='hs-varid'>xc</span><span class='hs-layout'>)</span>
<a name="line-120"></a> <span class='hs-varid'>mapList</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>takeMatch</span> <span class='hs-varid'>x</span> <span class='hs-layout'>(</span><span class='hs-varid'>zip</span> <span class='hs-varid'>sufxs</span> <span class='hs-varid'>imgxs</span><span class='hs-layout'>)</span>
<a name="line-121"></a> <span class='hs-keyword'>in</span> <span class='hs-conid'>Map</span><span class='hs-varop'>.</span><span class='hs-varid'>fromListWith</span> <span class='hs-layout'>(</span><span class='hs-varop'>++</span><span class='hs-layout'>)</span> <span class='hs-varid'>mapList</span>
<a name="line-122"></a>
<a name="line-123"></a><a name="takeMatch"></a><span class='hs-comment'>{- |
<a name="line-124"></a>Lazy variant of 'take'.
<a name="line-125"></a>-}</span>
<a name="line-126"></a><span class='hs-definition'>takeMatch</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span>
<a name="line-127"></a><span class='hs-definition'>takeMatch</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>zipWith</span> <span class='hs-layout'>(</span><span class='hs-varid'>flip</span> <span class='hs-varid'>const</span><span class='hs-layout'>)</span>
</pre></body>
</html>
|