Przykład programu wyznaczającego najczęściej występujące słowa w łańcuchu
{-
Konstrukcja funkcji wyznaczającej najczęściej występujące
słowa w tekście
--}
import Data.List(group, sort, sortBy)
import Data.Char(toLower)
dopuszczalne = [' ']++['a'..'z']
stopWords = ["a","an","and","are", "at", "as","all",
"be", "by", "do", "it", "in", "no", "ll",
"so", "s", "o", "or", "t", "th", "this","that","the","thy",
"i", "it", "he", "his", "me",
"is","to","thou","tis",
"you","your","our",
"we","will","was"] -- dosyć przypadkowe
txt2Lower = map toLower
oczyscZnaki = map (\c -> if elem c dopuszczalne then c else ' ')
oczyscSlowa = filter (\slowo -> not(elem slowo stopWords))
zlicz = map (\l -> (head l, length l))
posortuj = sortBy (\x y -> compare (snd y) (snd x))
przeksztalc = posortuj
. zlicz
. group -- grupuje sąsiednie elementy :: [a] -> [[a]]
. sort -- aby poprawnie móc zastosować group
. oczyscSlowa
. words
. oczyscZnaki
. txt2Lower
mostFrequent n xs = map fst (take n ( przeksztalc xs))
{-
Po raz pierwszy na wykładzie komunikujemy się ze światem zewnętrznym.
Omówimy to w przyszłości dokładniej
-}
main = do
txt <- readFile "hamlet.txt"
putStrLn (show (mostFrequent 50 txt))
Link do pliku hamlet.txt
Modelowanie skończonego automatu niedeterministycznego
Taka niezbyt uniwersalna realizacja:
{-
Automat niedeterministyczny rozpoznając język {a,b}^*a{a,b}{a,b}{a,b},
czyli "a" ma być na czwartym miejscu od końca
-}
import Data.List
{- funkcja przejścia -}
δ :: Int -> Char -> [Int]
δ 'a' 0 = [0,1]
δ 'b' 0 = [0]
δ _ 1 = [2]
δ _ 2 = [3]
δ _ 3 = [4] -- stan końcowy
δ _ 4 = [5] -- błąd
δ _ _ = [5]
{-- podniesienie funkcji przejscia na zbiory stanów -}
δS :: [Int] -> Char -> [Int]
δS ss c = nub $ concat $ map (\x -> δ c x) ss
{-- symulacja obliczeń --}
oblicz :: String -> [Int]
oblicz cs = foldl δS [0] cs
{-- funkcja akceptująca -}
accept cs = elem 4 (oblicz cs)
-- przekształcenie w DFA
{-
accessibleFrom stany :
input: lista list stanów [[Init]]
output: input ++ lista list stanów do których można dojść ze stanów z listy input
ważna własność: stany są sublistą (accessibleFrom stany), czyli, mniej więcej,
xs subseteq aF(xs)
Uwaga 1. aby ograniczyć eksplozję liczby stanów stosujemy funkcję nub
Uwaga 2. nakładamy funkcję sort aby można było zastosować metodę fix punktu w następnej funkcji
-}
accessibleFrom stany = sort $ nub $ map (\st -> δS st 'a') stany ++ map (\st -> δS st 'b') stany ++ stany
{-
wyznaczStany x === najmniejszy punkt stały odwzorowania y --> accessibleFrom y
większy lub równy x
-}
wyznaczStany x | x == fx = x
| otherwise = wyznaczStany fx
where fx = accessibleFrom x
wyznaczPrzejscia xs = [(x,a,y) | x <- xs, y <- xs , a <- ['a','b'], δS x a == y]
dFA = wyznaczPrzejscia $ wyznaczStany [[0]]