packages feed

FM-SBLEX-3.0: src/dalin/GenRulesSw.hs

module GenRulesSw where

import General
import List
import qualified Data.Set as Set

type Suffixes = [((String -> String), String)]

e :: String -> ((String -> String),String)
e s = (id,s) 

apply_suffixes :: String -> Suffixes -> [String]
apply_suffixes stem xs = [f stem ++ suff | (f,suff) <- xs]

lift :: [a] -> [[a]]
lift  [] = []
lift   s = [s]

keep :: Int -> (String -> String) -> String -> String
keep n f s = f pre ++ suf
 where
  (pre,suf) = case splitAt n (reverse s) of
               (rs,rp) -> (reverse rp, reverse rs)

drop_last_vowel = dv

dsuff :: String -> String -> String
dsuff suff s 
 | isPrefixOf (reverse suff) (reverse s) = tk (length suff) s
 | otherwise = s

dv :: String -> String
dv w = case find_stem_vowel w of
        (seg,e,l) -> seg ++ l


dvu :: String -> String
dvu w = case find_stem_vowel w of
          (seg,e,l) -> (ungeminate_m_n seg) ++ l

fr :: String -> String
fr s = case reverse s of
         ('f':v:_) -> s ++ "v"
         _ -> s

fv s = if (dp 2 s == "fv") then tk 1 s else s

dpe :: String -> String
dpe w = case find_stem_vowel w of
         (seg,e,l) | slast e == 'e' && length l < 2 -> seg ++ init e ++ l
         _ -> w

slast x@(_:_) = last x
slast _ = '_'

dpeu :: String -> String
dpeu w = case find_stem_vowel w of
           (seg,e,l) | slast e == 'e' && length l < 2 -> ungeminate_m_n seg ++ init e ++ l
           _ -> ungeminate_m_n w

dpl :: Char -> String -> String
dpl c s = case span (/= c) (reverse s) of
           (b,_:r) -> reverse (b ++ r)
           (b,[])  -> reverse b

drop_second_last :: String -> String
drop_second_last s = (tk 2 s) ++ (dp 1 s)

is_vowel :: Char -> Bool
is_vowel c = Set.member c vowel 

vowel = Set.fromList "aeiouyåäöAEIOUYÅÄÖ"

is_consonant :: Char -> Bool
is_consonant c = Set.member c consonant

consonant = Set.fromList "bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ"

is_voiced :: Char -> Bool
is_voiced c = Set.member c voiced

voiced = Set.fromList "bdglmnrvjBDGLMNRVJ"

if_vowel :: Char -> String -> String -> String
if_vowel c d e = if is_vowel c then d else e

drop_final_e :: String -> String
drop_final_e = dropEndIf (=='e')

ds :: String -> String
ds s =  case reverse s of
        (x:y:_) | ((is_consonant x) && y == 's') || ((is_consonant x) && y == 'x') || [y,x] == "ch" || x=='x' || x =='z' || x =='s' -> s
        [] -> []
        _   -> s +? "s"

ds_drop :: String -> String
ds_drop s = ds $ if iw s then safe_init s else s
  where iw [] = False
        iw str = is_vowel (last str)

fl :: String -> String
fl s = case words s of
         [x,y] -> y +? x
         _     -> error "Unable to flip in \"" ++ s ++ "\""

-- dropEndIf (=='s')

compound_s :: String -> [String]
compound_s s = case reverse s of
                 (x:y:_) | ((is_consonant x) && y == 's') || ((is_consonant x) && y == 'x') || [y,x] == "ch" || x=='x' || x =='z' || x=='s' -> [s]
                 [] -> []
                 _   -> [s +? "s"]

insert_second_last :: String -> Char -> String
insert_second_last s c = safe_init s ++ [c] ++ (f s)
  where f [] = []
        f str = [last str]

geminate :: String -> String
geminate s = s ++ dp 1 s

ungeminate :: String -> String
ungeminate s = case reverse s of
  'm':'m':_ -> safe_init s
  _         -> s

ungeminate_m_n :: String -> String
ungeminate_m_n s = case reverse s of
  n:m:_ | n == m && elem n "nm" -> safe_init s
  _ -> s

safe_init :: String -> String
safe_init [] = []
safe_init xs = init xs

mmn :: String -> String
mmn s = case reverse s of
         ('n':'m':'m':xs)  -> (reverse ('n':'m':xs))
         _                 -> s

--3 Umlaut
--
-- Let's conclude with something that is not easy to do on this level of generality
-- with regular expressions: 
-- define first the *stem vowel* as the last vowel (or diphtong) in the stem:

find_stem_vowel :: String -> (String, String, String)
find_stem_vowel sprick = (reverse rps, reverse i, reverse kc) where
  (kc, irps) = break is_vowel $ reverse sprick
  (i,   rps) = span  is_vowel $ irps

-- vowel change
vc :: String -> String -> String
vc v sprick = 
  case find_stem_vowel sprick of
    (spr,i,ck) -> spr ++ v ++ ck

vct :: [(String,String)] -> String -> String
vct xs sprick =   case find_stem_vowel sprick of
                    (spr,i,ck) -> spr ++ (v i) ++ ck
 where v i = case lookup i xs of
               Just x -> x
               Nothing -> i



triplecons :: String -> Char -> String
triplecons s c = case reverse s of
                   (c1:c2:_) | c1 == c && c1 == c2 -> safe_init s
                   _  -> s

-- Although *umlaut* is not very very useful in Swedish, we are glad to
-- present a general rule for it:

umlaut :: String -> String
umlaut man = m ++ mkUm a ++ n where
  (m,a,n) = find_stem_vowel man
  mkUm v = case v of
    "a" -> "ä"
    "o" -> "ö"
    "å" -> "ä"
    "u" -> "y"
    _   -> v