diff options
Diffstat (limited to 'lib/voices/finnish/hy_fi_mv_diphone/festvox/finnish_lts.scm')
-rw-r--r-- | lib/voices/finnish/hy_fi_mv_diphone/festvox/finnish_lts.scm | 829 |
1 files changed, 829 insertions, 0 deletions
diff --git a/lib/voices/finnish/hy_fi_mv_diphone/festvox/finnish_lts.scm b/lib/voices/finnish/hy_fi_mv_diphone/festvox/finnish_lts.scm new file mode 100644 index 0000000..a9e88b9 --- /dev/null +++ b/lib/voices/finnish/hy_fi_mv_diphone/festvox/finnish_lts.scm @@ -0,0 +1,829 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; ;; +;;; Department of General Linguistics / Suopuhe project ;; +;;; University of Helsinki, FI ;; +;;; Copyright (c) 2000-2003 ;; +;;; All Rights Reserved. ;; +;;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; ;;; +;;; ;;; +;;; Author: Nicholas Volk ;;; +;;; e-mail: nvolk@ling.helsinki.fi ;;; +;;; address: Department of General Linguistics ;;; +;;; PL 9 (Siltavuorenpenger 20A) ;;; +;;; 00014 University of Helsinki ;;; +;;; FINLAND ;;; +;;; ;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; Finnish LTS-rules, which fake the lexicon +;;; (somewhat similar to the Festival Spanish) +;;; +;;; This file contains the LTS rules for Finnish. +;;; The LTS rules also syllabify and mark the stressed syllables + +; This program is distributed under Gnu Lesser General Public License (cf. the +; file LICENSE in distribution). + +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU Lesser General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. + +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU Lesser General Public License for more details. + +(require 'finnish_lex) ;; POS (content vs. function) information is in lex + + +(define (finnish_lts word) + "(finnish_lts WORD) +Creates the lexical entry for the given WORD." + (if hy_debug (format stderr "Creating the lexical entry for %s.\n" word)) + + ;; in suopuhe-mode: + ;; reverse the stacks, if that has not been done yet... + (if (and suopuhe + (not pos_reversed)) + (begin + (set! suopuhe_accent_stack (reverse suopuhe_accent_stack)) + (set! suopuhe_pos_stack (reverse suopuhe_pos_stack)) + (set! pos_reversed t))) + + + ;; check the string + ;; if there are unknown characters, replace them with "tuntematonmerkki" + ;; ("unknowncharacter") + (set! word + (let ((new "") + (state 0) ;; 0: initial state 1: prev is ordinary 2: unknown prev + char) + (while (> (string-length word) 0) + (begin + (set! char (substring word 0 1)) + (set! word (substring word 1 (- (string-length word) 1))) + (cond + ;; ad hoc: LTS can't replace right bracket \] "]" + ((string-equal "\]" char) + (set! new + (string-append + (if new new "") + (if (> state 0) "-" "") + "oikeahakasulku")) + (set! state 2)) + ((string-matches char "^[ a-zA-Z0-9\"\'\`\$%&\(\)\*\+\-~_\^/\\\?\}\{\@\.:!àáâãäöæçèéêëìíîïðñòóôõöøùúûüýþÀÁÂÃÄÅÆÇÐÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝÞ]$" ) + (set! new + (string-append + (if new new "") + (if (= state 2) "-" "") + char)) + (set! state 1)) + (t + (set! new + (string-append + (if new new "") + (if (> state 0) "-" "") + "tuntematonmerkki")) + (set! state 2))))) + new)) + + + (cond + ;; suopuhe mode gets hopefully the pos from a stack + (suopuhe + (let ((pos (pop_pos)) + (acc (pop_accent))) + (set! pos (if (string-equal "unknown" pos) + (cond + ((word_list_entry? word finnish_guess_coord) + "COORD") + ((word_list_entry? word finnish_guess_cop) + "COP") + ((word_list_entry? word finnish_guess_pron) + "PRON") + ((word_list_entry? word finnish_guess_pos) + "function") + (t + "content")))) + ;; anyway... if word is defined as accentless we change + ;; the POS in the lexical entry to FUNCTION overriding the + ;; defined POS! + ;; accented words get POS CONTENT on the same basis... + (if (string-equal acc "no") + (set! pos "function") + (if (string-equal acc "yes") + (set! pos "content"))) + + (let ((x (list word (pop_pos) (compound_stress word)))) + x))) + ;; non-suopuhe mode + ((word_list_entry? word finnish_guess_coord) + (list word "COORD" (compound_stress word))) + ((word_list_entry? word finnish_guess_cop) + (list word "COP" (compound_stress word))) + ((word_list_entry? word finnish_guess_pron) + (list word "PRON" (compound_stress word))) + ((word_list_entry? word finnish_guess_pos) + (list word "function" (compound_stress word))) + (t + (list word "content" (compound_stress word))))) + +(define (finnish_token_to_words token name) + "(finnish_token_to_words token name) +A few simple ad hoc solutions for the most common simple T2W-problems. +It was much nicer to use an external Perl text normalizer than scheme." + (cond + ;; NAN: begins with a 0, thsus sequence of digit + ((string-matches name "^0[0-9]*$") + (symbolexplode name)) + ;; hundereds of millions are read as digits + ((string-matches name "^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]+$") + (symbolexplode name)) + ;; ordinary number (no inflections in scheme, use perl) + ((string-matches name "^[1-9][0-9]*$") + (list (finnish_number name))) + ;; Too many initial consonants + ((string-matches name "^[BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz][BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz][BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz][BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz].*$") + (symbolexplode name)) + ;; separate consonant sequence from each other : "KGB" => "K G B" + ((string-matches name "^\\(.*\-\\)?[BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz]+\\(\-.*\\)?$") + (symbolexplode name)) + ;; do nothing + (t + (list name)))) + +(define (finnish_number int) + "(finnish_number INT) +Converts the INT into a corresponding string. +Very simple. Does not handle cases." + (remove_head_and_tail_spaces (make_number int))) + +(define (remove_head_and_tail_spaces text) + "(remove_head_and_tail_spaces string) +Removes unspoken space sequences from the beginning and end of a give string." + (if (not (string-equal (typeof text) "string")) + (begin + (set! text "The input was not a string!"))) + + ;; remove the initial whitespaces + (while (and (> (string-length text) 0) + (string-matches (substring text 0 1) "^[ \t\n\015]$")) + ;; \015 = CTRL-M = carriage return + (set! text (substring text 1 (- (string-length text) 1)))) + ;; remove the final whitespaces + (while (and (> (string-length text) 0) + (string-matches + (substring text (- (string-length text) 1) 1) + "^[ \t\n\015]$")) + (set! text (substring text 0 (- (string-length text) 1)))) + text) + + +(define (make_number int) + "(make_number INT) +Splits numbers into 3-letter chunks, which are converted into a number. +Also adds an appropriate quantifier (like thousands) to each triplet, +thus producing any int between 1 - 999999999." + (let (head) + (cond + ((> (string-length int) 6) + (set! head (substring int 0 (- (string-length int) 6))) + (set! int (substring int (string-length head) 6)) + (if (string-equal head "1") + (string-append + "miljoona " + (make_number int)) + (string-append + (make_number2 head) + "miljoonaa " + (make_number int)))) + ((> (string-length int) 3) + (set! head (substring int 0 (- (string-length int) 3))) + (set! int (substring int (string-length head) 3)) + (cond + ((string-equal head "000") + (make_number int)) + ((or (string-equal head "1") + (string-equal head "001")) + (string-append + "tuhat " + (make_number int))) + (t + (string-append + (make_number2 head) + "tuhatta " + (make_number int))))) + (t + (make_number2 int))))) + +(define (make_number2 int) + "(make_number2 INT) +Converts an up-to-three digit sequence into a number." + + (let (ones dozens hundreds output) + (cond + ((= (string-length int) 3) + (set! hundreds (substring int 0 1)) + (set! dozens (substring int 1 1)) + (set! ones (substring int 2 1))) + ((= (string-length int) 2) + (set! hundreds "0") + (set! dozens (substring int 0 1)) + (set! ones (substring int 1 1))) + (t + (set! hundreds "0") + (set! dozens "0") + (set! ones (substring int 0 1)))) + ;; HUNDREDS + (cond + ((string-equal hundreds "0") + (set! output "")) + ((string-equal hundreds "1") + (set! output "sata")) + (t + (set! output (string-append (number_list hundreds) "sataa")))) + ;; DOZENS & ONES + (cond + ((string-equal dozens "0") + (set! output (string-append output (number_list ones)))) + ((string-equal dozens "1") + (if (string-equal ones "0") + (set! output (string-append output "kymmenen")) + (set! output (string-append output (number_list ones) "toista")))) + (t + (set! output (string-append output + (number_list dozens) "kymmentä" + (number_list ones))))) + output)) + + + +(define (number_list digit) + "(number_list DIGIT) +Returns the corresponding string for a given DIGIT" + (cond + ((string-equal digit "9") "yhdeksän") + ((string-equal digit "8") "kahdeksan") + ((string-equal digit "7") "seitsemän") + ((string-equal digit "6") "kuusi") + ((string-equal digit "5") "viisi") + ((string-equal digit "4") "neljä") + ((string-equal digit "3") "kolme") + ((string-equal digit "2") "kaksi") + ((string-equal digit "1") "yksi") + (t + ""))) + + +(define (finnish_tosyl_brackets phones accent) + "(finnish_tosyl_brackets phones) +Takes a list of phones containing - as syllable boundary. +Should we add a compound boundary? Probably... +Construct the Festival bracket structure. +Used by finnish_lts-function." + (let ((tavu nil) (syls nil) (p phones) (stress 0) (syltotal 1) + (cvcvcvcv nil) + (which 1) (secondary_stress 0)) + ;; lasketaan tavujen määrä + (while p + (if (eq? '- (car p)) + (begin + (set! tavu (reverse tavu)) + ;; if the 3rd syllable has 1 "mora" + ;; the secondary stress goes to the 4th syllable + (if (and (= syltotal 3) + (= (mora2 tavu) 1) + (or (string-matches (cadr p) + "^[abdefghijklmnoprstuvy@7NT]$") + (string-matches (cadr p) "^[aeiouy@7]:?$" ))) + ;; had but 1 mora + (begin + ;; cvcvcvcv takes care of 4-syl words + ;; with a short 3rd syl + (set! cvcvcvcv t) + (set! secondary_stress 4))) + (if (and (= secondary_stress 4) + (= syltotal 4) + (= (mora2 tavu) 1) + (or (string-matches ;; short + (cadr p) + "^[abdefghijklmnoprstuvy@7NT]$" ) + (string-matches (cadr p) "^[aeiouy@7]:?$" ))) + (set! secondary_stress 3)) + + + + (set! syltotal (+ syltotal 1)) ;; N:s tavu alkaa + + (set! tavu nil)) + ;; muuten lisää tavu + (set! tavu (cons (car p) tavu))) + (set! p (cdr p))) + + + (set! p phones) + (if (and (> syltotal 3) ;; secondary_stress is possible + (> accent 0)) ;; the word is stressed + ;; ON SECONDARY_STRESS + (begin + ;; 4-tavuinen, jossa 3:s oli lyhyt omaa väärän arvon, korjataan: + (if (and (= syltotal 4) + cvcvcvcv) + (set! secondary_stress 3)) + ;; tarpeeksi pitkä secondary_stresslliselle, mutta secondary_stress ei päällä: + (if (= secondary_stress 0) + (set! secondary_stress 3)));; nyt aina kolmannelle tavulle + (set! secondary_stress 0)) + + (set! which 1) + (while p + (set! tavu nil) + (set! stress accent) + ;; asetetaan secondary_stress, jos on tarvis + + (if (and (= which secondary_stress) + (> syltotal secondary_stress)) + (begin + (set! secondary_stress (+ secondary_stress 2)) + (set! stress 1))) + + (while (and p + (not (eq? '- (car p)))) + ;;;(set! name (list2string (cons (car p) syl))) + (set! tavu (cons (car p) tavu)) + ;;;(item.set_name syl name) + (set! p (cdr p))) + (set! which (+ which 1)) + (set! p (cdr p)) ;; hyppää '-':n yli + (set! accent 0) ;; jälkitavuille + (set! syls (cons (list (reverse tavu) stress) syls))) + (reverse syls))) + +(define (mora2 list_of_phones) +"(mora2 list_of_phones) +Counts the moras (morae?) in a given list of phones. +Does not support ambisyllabic long consonants." +(let ((onset t) + (total 0) + phone) + + (while list_of_phones + (set! phone (car list_of_phones)) + ;; as long as we get Cs we're in the onset + (if (not (and onset + (string-matches phone "^[bdfghjklmnprstvNT]:?$" ))) + (begin + (set! onset nil) + (if (string-matches phone "^[abdefghijklmnoprstuvy@7NT]:$" ) + (set! total (+ total 2)) ;; long + (set! total (+ total 1))))) ;; short + (set! list_of_phones (cdr list_of_phones))) + total)) + + + +(define (compound_stress compound) + "(compound_stress WORD) +Handles the exception stress placement in compounds. +The few compounds supported are recognized by the '-' separator. +However secondary word stress did not show up in duration and intonation +models... We could also add boundary detection based on vowel positions +in neighboring syllables." + + (let ((suitable (string-matches compound "^\\([A-ZÅÄÖa-zåäö][A-ZÅÄÖa-zåäö]+\-\\)+[A-ZÅÄÖa-zåäö][A-ZÅÄÖa-zåäö]+$")) + (word1 "") + (word2 nil)) ;; word2 will be a list + (if (not suitable) (set! word1 compound)) + (while (and (> (string-length compound) 0) + suitable) + ;; compound marker has been found yet + (if (string-equal (substring compound 0 1) "-") + (begin + ;; behead the compound + (if (= (string-length compound) 1) + (set! compound "") + (set! compound (substring compound 1 (- (string-length compound) 1)))) + (if (not (string-equal word1 "")) + (set! word2 + (append word2 (finnish_tosyl_brackets + (lts.apply + (lts.apply + (lts.apply word1 'normalize) + 'finnish_cv) + 'remove_unneeded) 2)))) + + (set! word1 "")) + ;; else + (begin + (set! word1 (string-append word1 (substring compound 0 1))) + (if (= (string-length compound) 1) + (set! compound "") + (set! compound (substring compound 1 (- (string-length compound) 1))))))) ;; end of while + + (if word2 + (set! word2 (append word2 + (finnish_tosyl_brackets + (lts.apply + (lts.apply + (lts.apply word1 'normalize) + 'finnish_cv) + 'remove_unneeded) 2))) + (set! word2 (finnish_tosyl_brackets + (lts.apply + (lts.apply + (lts.apply word1 'normalize) + 'finnish_cv) + 'remove_unneeded) 2))) + word2)) + +;;;======================================================================= + +(lts.ruleset + normalize + ; sets + ( ( NUMERO 0 1 2 3 4 5 6 7 8 9 ) + ( POIS "\"" "\'" "\`" ) + + ( CON b c d f g h j k l m n p q r s t v w x z + B C D F G H J K L M N P Q R S T V W X Z) + ( VOW a e i o u y ä ö + A E I O U Y Ä Ö) + ( LET A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Å Ä Ö + a b c d e f g h i j k l m n o p q r s t u v w x y z å ä ö ) + ) +; +; ;rules + ( + + ;; a lone " + ( # [ "\"" ] # = l a i n a u s m e r k k i ) + ( # [ POIS ] # = h e i t t o m e r k k i ) + ; seuraavat pois: + ( [ POIS ] = ) + ( [ " " ] = ) ;; tokenisoija ei vielä jaa merkkijonoa wordlistaksi... + + ( [ 1 ] = y k s i ) + ( [ 2 ] = k a k s i ) + ( [ 3 ] = k o l m e ) + ( [ 4 ] = n e l j @ ) + ( [ 5 ] = v i i s i ) + ( [ 6 ] = k u u s i ) + ( [ 7 ] = s e i t s e m @ n ) + ( [ 8 ] = k a h d e k s a n ) + ( [ 9 ] = y h d e k s @ n ) + ( [ 0 ] = n o l l a ) + + ( [ "#" ] = r i s u a i t a ) + ( [ "$" ] = d o l l a r i ) + ( [ "%" ] = p r o s e n t t i ) + ( [ "&" ] = e t ) + + ;; should these be spoken (SayText "(word)") + ( [ "(" ] = v a s e n s u l k u ) + ( [ ")" ] = o i k e a s u l k u ) + + ( [ * ] = a s t e r i s k i ) + ( [ + ] = p l u s ) + ;( [ "\/" = j a k o v i i v a ) + + + ( # [ - ] # = v i i v a ) + ( LET [ - ] LET = ) ;; morphemeboundary + ( LET [ - ] # = ) ;; word- => word + ( # [ - ] LET = ) ;; -word => word + ( [ - ] NUMERO = m i i n u s - ) + +;; ( # [ - ] = ) +;; ( [ " " - " " ] = ) +;; ( " " [ - ] = ) +;; ( [ - ] # = ) +;; ( [ - ] " " = ) + + ( [ - ] = v i i v a ) + + ( [ "~" ] = a a l t o v i i v a ) + ( [ _ ] = a l a v i i v a ) + ( [ "^" ] = h a t t u ) + ( [ "!" ] = h u u t o m e r k k i ) + ( [ "/" ] = k a u t t a ) + ( [ "\\" ] = k e n o v i i v a ) ;; kenoviiva kannattaa laventaa etukäteen.. + ( [ "?" ] = k y s y m y s m e r k k i ) + ( [ \] ] = o i k e a h a k a s u l k u ) ;; finnish_lts ongelma + ( [ "}" ] = o i k e a k a a r i s u l k u ) + ( [ "=" ] = o n y h t a k u i n ) + ( [ "<" ] = p i e n e m p i k u i n ) + ( [ "," ] = p i l k k u ) + ( [ "£" ] = p u n t a ) + ( [ ";" ] = p u o l i p i s t e ) + ( [ "|" ] = p y s t y v i i v a ) + ( [ ">" ] = s u u r e m p i k u i n ) + ( [ "[" ] = v a s e n h a k a s u l k u ) ;; finnish_lts ongelma + ( [ "{" ] = v a s e n k a a r i s u l k u ) ;; "{}" toimii oudosti... + ( [ "@" ] = @ t ) + + ( [ "." ] = p i s t e ) ;; token2words temppuilee + ( [ ":" ] i n # = ) + ( [ ":" ] = k a k s o i s p i s t e ) + ( [ " " ] = " " ) ;; separeted chars use this + + + + ; # SH-äänne + ( [ s c h ] = S ) ; schubert + ( [ S c h ] = S ) + ( t [ s h ] = s ) ; tshetsheeni + ( T [ s h ] = s ) + ( [ s h ] CON = S ) ; pushkin + ( [ S h ] = S ) + ( VOW VOW [ s h ] = s h ) ; talOUSHallinto + ( [ s h ] y = s h ) ; + ( [ s h ] ä = s h ) ; mieshän + ( [ s h ] ö = s h ) ; ykköshörhö + ( i l a [ s h ] = s h ) ; sotilashenkilö + ( l l i [ s h ] = s h ) ; paikallishallinto + ( s k u [ s h ] = s h ) ; keskushallinto + ( n n u [ s h ] = s h ) ; + ( t u [ s h ] = s h ) ; opetushallitus + ( y [ s h ] = s h ) ; yrityshautomo + ( ä [ s h ] = s h ) ; seiväshyppy + ( ö [ s h ] = s h ) ; ykköshenkilö + ( # [ s h ] = S ) ; shakki + ( [ s h ] # = S ) ; bush + ( e i [ s h ] = s h ) ; yhteishenki + ( [ s h ] i # = S ) ; takeshi + ( w a [ s h ] i n g t = S S ) ; washington + ( [ s h ] o w = S ) + ( m u [ s h ] = S ) ; kokoomushan + ( i h m i [ s h ] = s h ) ; ihmishenki + ( [ s h ] = S ) + +;; ( [ a h l ] = a a l ) + ( [ t z ] = t s ) + + + + + ( [ à ] = a ) ( [ À ] = a ) + ( [ á ] = a ) ( [ Á ] = a ) + ( [ â ] = a ) ( [ "Â" ] = a ) + ( [ ã ] = a ) ( [ Ã ] = a ) + ( [ æ ] = @ ) ( [ Æ ] = @ ) + ( [ ç ] = s ) ( [ Ç ] = s ) + ( [ ð ] = t h ) ( [ Ð ] = t h ) + ( [ è ] = e ) ( [ È ] = e ) + ( [ é ] = e ) ( [ É ] = e ) + ( [ ê ] = e ) ( [ Ê ] = e ) + ( [ ë ] = e ) ( [ Ë ] = e ) + ( [ ì ] = i ) ( [ Ì ] = i ) + ( [ í ] = i ) ( [ Í ] = i ) + ( [ ï ] = i ) ( [ Ï ] = i ) + ( [ î ] = i ) ( [ Î ] = i ) + ( [ ñ ] = n j ) ( [ Ñ ] = n j ) + ( [ ø ] = 7 ) ( [ Ø ] = 7 ) + ( [ ò ] = o ) ( [ Ò ] = o ) + ( [ ó ] = o ) ( [ ó ] = o ) + ( [ ô ] = o ) ( [ Ô ] = o ) + ( [ õ ] = o ) ( [ Õ ] = o ) + ( [ ß ] = s s ) + ( [ þ ] = t h ) ( [ Þ ] = t h ) + ( [ ù ] = u ) ( [ Ù ] = u ) + ( [ ú ] = u ) ( [ Ù ] = u ) + ( [ û ] = u ) ( [ Û ] = u ) + ( [ ü ] = y ) ( [ Ü ] = y ) + ( [ ý ] = y ) ( [ Ý ] = y ) + ( [ ÿ ] = y ) + + ; "lowercase" + ( [ a ] = a ) ( [ b ] = b ) + ( [ A ] = a ) ( [ B ] = b ) + + ( [ c ] = c ) + ( [ C ] = c ) + + ( [ d ] = d ) ( [ e ] = e ) + ( [ D ] = d ) ( [ E ] = e ) + ( [ f ] = f ) ( [ g ] = g ) ( [ h ] = h ) ( [ i ] = i ) ( [ j ] = j ) + ( [ F ] = f ) ( [ G ] = g ) ( [ H ] = h ) ( [ I ] = i ) ( [ J ] = j ) + + ( [ K ] = k ) ( [ L ] = l ) ( [ M ] = m ) + ( [ N ] = n ) + ( [ k ] = k ) ( [ l ] = l ) ( [ m ] = m ) + + ( [ n ] = n ) + + ( [ O ] = o ) ( [ P ] = p ) ( [ Q ] = q ) ( [ R ] = r ) ( [ S ] = s ) + ( [ o ] = o ) ( [ p ] = p ) ( [ q ] = q ) ( [ r ] = r ) ( [ s ] = s ) + ( [ T ] = t ) ( [ U ] = u ) ( [ V ] = v ) ( [ W ] = w ) ( [ X ] = x ) + ( [ t ] = t ) ( [ u ] = u ) ( [ v ] = v ) ( [ w ] = w ) ( [ x ] = x ) + ( [ Y ] = y ) ( [ Z ] = z ) ( [ Å ] = å ) ( [ Ä ] = @ ) ( [ Ö ] = 7 ) + ( [ y ] = y ) ( [ z ] = z ) ( [ å ] = å ) ( [ ä ] = @ ) ( [ ö ] = 7 ) + + )) + +(lts.ruleset + finnish_cv + ; sets + (( LAITONA e o y @ 7 ) + ( LAITONEI a o y @ 7 ) + ( LAITONOU a e y @ 7 ) + ( LAITONY7 a e o u @ ) + ( LAITON@ a e u o 7 ) + ( VOW a e i o u y @ 7 ö å ) + ( CON b c d f g h j k l m n p q r s t v w x z ) + ) + ;rules + ( +; ( # [ s h ] = __ S ) +; ( # [ s c h ] = __ S ) + ( # [ t h ] = __ T ) + ( [ t h ] # = __ T ) ;; cheat + ( [ t h ] CON = __ T ) + + ( [ a - a ] = _ a - a ) + ( [ e - e ] = _ e - e ) + ( [ i - i ] = _ i - i ) + ( [ o - o ] = _ o - o ) + ( [ u - u ] = _ u - u ) + ( [ y - i ] = _ y - y ) + ( [ @ - @ ] = _ @ - @ ) + ( [ 7 - 7 ] = _ 7 - 7 ) + + + ( [ a ] LAITONA = _ a - ) + ;; ( [ e ] a # = _ e ) + ( [ e ] LAITONEI = _ e - ) + ;; ( [ i ] a # = _ i ) + ( [ i ] LAITONEI = _ i - ) + ;;( [ o ] a # = _ o ) + ( [ o ] LAITONOU = _ o - ) + ( [ u ] LAITONOU = _ u - ) + ( [ y ] LAITONY7 = _ y - ) + ;; ( [ 7 ] ä # _ 7 ) + ( [ 7 ] LAITONY7 = _ 7 - ) + ( [ @ ] LAITON@ = _ @ - ) + + ;; some assimilations + ( VOW [ n m ] VOW = __ m: ) + ( VOW [ n ] p VOW = m ) + ( [ n g ] VOW = __ N: ) + ( [ n g ] = __ N ) + ( [ n ] k = __ N ) + + + + ( [ a a ] = _ a: ) + ( [ b b ] = "__" b: ) + ( [ c c ] = "__" k: ) ( [ c k ] = k: ) + ( [ d d ] = "__" d: ) + ( [ e e ] = _ e: ) + ( [ f f ] = "__" f: ) + ( [ g g ] = "__" g: ) + ( [ h h ] = "__" h: ) + ( [ i i ] = _ i: ) + ( [ j j ] = "__" j: ) + ( [ k k ] = "__" k: ) + ( [ l l ] = "__" l: ) + ( [ m m ] = "__" m: ) + ( [ n n ] = "__" n: ) + ( [ o o ] = _ o: ) + ( [ p p ] = "__" p: ) + ( [ r r ] = "__" r: ) + ( [ s s ] = "__" s: ) + ( [ S S ] = "__" S: ) + ( [ t t ] = "__" t: ) + ( [ u u ] = _ u: ) + ( [ v v ] = "__" v: ) + ( [ y y ] = _ y: ) + ( [ @ @ ] = _ @: ) + ( [ 7 7 ] = _ 7: ) + + ( [ a ] = _ a ) + ( [ b ] = __ b ) + ( [ c ] e = __ s ) + ( [ c ] = __ k ) + ( [ d ] = __ d ) + ( [ e ] = _ e ) + ( [ f ] = __ f ) + ( [ g ] = __ g ) + ( [ h ] = __ h ) + + ( [ i ] = _ i ) + ( [ j ] = __ j ) + ( [ k ] = __ k ) + ( [ l ] = __ l ) + ( [ m ] = __ m ) + ( [ n ] = __ n ) + ( [ o ] = _ o ) + ( [ p ] = __ p ) + ( # [ q u ] = k v ) + ( [ q u ] = - k v ) + ( # [ q ] = k v ) + ( [ q ] = - k v ) ; frek-venssi + ( [ r ] = __ r ) + ( [ s ] = __ s ) + ( [ t ] = __ t ) + ( [ u ] = _ u ) + ( [ v ] = __ v ) + ( [ w ] = __ v ) + ( [ x ] = __ k __ s ) ; tak-si + ( [ y ] = _ y ) + ( # [ z ] = t s ) + ( [ z ] = - t s ) + ( [ å ] = _ o ) + ( [ @ ] = _ @ ) + ( [ 7 ] = _ 7 ) + ( [ - ] = - ) + ( [ L ] = __ L ) ;; this is our light /l/ + ( [ S ] = __ S ) ;; this is our palatal /s/ + ( [ " "+ ] = " " ) +)) + +(lts.ruleset remove_unneeded + ( ; sets + ( CON b d f g h j k l m n p r s t v N T S L + b: d: f: g: h: j: k: l: m: n: p: r: s: t: v: N: T: S: L:) + ( VOW a e i o u y @ 7 a: e: i: o: u: y: @: 7: ) + ( LONG a: e: i: o: u: y: @: 7: ) + ( EOS # " " ) + ) + ( ; rules + ( [ - _ ] = - ) + ( [ - __ ] = - ) + + ( EOS __ CON __ CON __ CON [ __ ] = ) + ( EOS __ CON __ CON [ __ ] = ) + ( EOS __ CON [ __ ] = ) + ( EOS [ __ ] = ) + ( [ __ ] CON _ VOW = - ) + ( [ __ ] = ) + + ( EOS [ _ ] = ) + ( CON [ _ ] = ) + ( - [ _ ] = ) + ( LONG [ _ ] = - ) + ( [ _ a _ ] = a - ) + ( [ _ e _ ] = e - ) + ( [ _ i _ ] = i - ) + ( [ _ o _ ] = o - ) + ( [ _ u _ ] = u - ) + ( [ _ y _ ] = y - ) + ( [ _ @ _ ] = @ - ) + ( [ _ 7 _ ] = 7 - ) + ( [ _ ] = ) + + ( [ a: ] = a: ) + ( [ b: ] __ CON = b ) ( [ b: ] # = b ) ( # __ [ b: ] = b ) ( [ b: ] = b: ) + ( [ d: ] __ CON = d ) ( [ d: ] # = d ) ( # __ [ d: ] = d ) ( [ d: ] = d: ) + ( [ e: ] = e: ) + ( [ f: ] __ CON = f ) ( [ f: ] # = f ) ( # __ [ f: ] = f ) ( [ f: ] = f: ) + ( [ g: ] __ CON = g ) ( [ g: ] # = g ) ( # __ [ g: ] = g ) ( [ g: ] = g: ) + ( [ h: ] __ CON = h ) ( [ h: ] # = h ) ( # __ [ h: ] = h ) ( [ h: ] = h: ) + ( [ i: ] = i: ) + ( [ j: ] __ CON = j ) ( [ j: ] # = j ) ( # __ [ j: ] = j ) ( [ j: ] = j: ) + ( [ k: ] __ CON = k ) ( [ k: ] # = k ) ( # __ [ k: ] = k ) ( [ k: ] = k: ) + ( [ l: ] __ CON = l ) ( [ l: ] # = l ) ( # __ [ l: ] = l ) ( [ l: ] = l: ) + ( [ m: ] __ CON = m ) ( [ m: ] # = m ) ( # __ [ m: ] = m ) ( [ m: ] = m: ) + ( [ n: ] __ CON = n ) ( [ n: ] # = n ) ( # __ [ n: ] = n ) ( [ n: ] = n: ) + ( [ N: ] __ CON = N ) ( [ N: ] # = N ) ( # __ [ N: ] = N ) ( [ N: ] = N: ) + ( [ o: ] = o: ) + ( [ p: ] __ CON = p ) ( [ p: ] # = p ) ( # __ [ p: ] = p ) ( [ p: ] = p: ) + ( [ r: ] __ CON = r ) ( [ r: ] # = r ) ( # __ [ r: ] = r ) ( [ r: ] = r: ) + ( [ s: ] __ CON = s ) ( [ s: ] # = s ) ( # __ [ s: ] = s ) ( [ s: ] = s: ) + ( [ t: ] __ CON = t ) ( [ t: ] # = t ) ( # __ [ t: ] = t ) ( [ t: ] = t: ) + ( [ u: ] = u: ) + ( [ v: ] __ CON = v ) ( [ v: ] # = v ) ( # __ [ v: ] = v ) ( [ v: ] = v: ) + ( [ y: ] = y: ) + ( [ @: ] = @: ) + ( [ 7: ] = 7: ) + ( [ L: ] __ CON = L ) ( [ L: ] # = L ) ( # __ [ L: ] = L ) ( [ L: ] = L: ) ;; our light /l/ + ( [ S: ] __ CON = S ) ( [ S: ] # = S ) ( # __ [ S: ] = S ) ( [ S: ] = S: ) ;; our palatal /s/ + ( [ T: ] __ CON = T ) ( [ T: ] # = T ) ( # __ [ T: ] = T ) ( [ T: ] = T: ) + ( [ D: ] __ CON = D ) ( [ D: ] # = D ) ( # __ [ D: ] = D ) ( [ D: ] = D: ) + + ;;; short (these are the original rules) + ( [ a ] = a ) ( [ b ] = b ) ( [ d ] = d ) ( [ e ] = e ) + ( [ f ] = f ) ( [ g ] = g ) ( [ h ] = h ) ( [ i ] = i ) ( [ j ] = j ) + ( [ k ] = k ) ( [ l ] = l ) ( [ m ] = m ) ( [ n ] = n ) ( [ o ] = o ) + ( [ p ] = p ) ( [ q ] = q ) ( [ r ] = r ) ( [ s ] = s ) ( [ t ] = t ) + ( [ u ] = u ) ( [ v ] = v ) ( [ y ] = y ) + ( [ @ ] = @ ) ( [ ö ] = ö ) ( [ 7 ] = 7 ) ( [ z ] = z ) + ( [ - ] = - ) + ( [ L ] = L ) ;; this is our light /l/ + ( [ S ] = S ) ;; this is our palatal /s/ + ( [ T ] = T ) + ( [ D ] = D ) + ( [ N ] = N ) + ( [ _ ] = _ ) ( [ __ ] = __ ) + ( [ " " ] = "" ) ;; cheat for LSEQs + )) + + +(provide 'finnish_lts) + + + |