/* gebe 'help.' im interpreter ein, um eine hilfe zu bekommen. % author: christopQsmail.uni-koeln.de % date: 10.07.04 % last_update: 13.09.04 % GNU-Prolog version. Need adaption for SWI-Prolog, Sicstus and Amzi. % Das Programm ist der erste Schritt zur lautlichen Spracherkennung. % Arbeitsweise: es müssen die gemittelten (ungenauen) Formantwerte (F1 % und F2) eines Vokals übergeben werden. Dies geschieht am Besten durch % eine ASCII-Liste, deren Formatierung sich aus dem Beispiel der beiliegenden % Textdatei (data) ersehen lässt. Das Programm leistet die % wahrscheinliche Zuordnung zu den im Programm fest gespeicherten % Vokale (z.B. zahl(f1, de_con_ih, 0.26, 0.1, 0.32). % für die handhabung des Programms ist folgender Text nicht zwingend zu % lesen. % prolog implementation eines eingeschränkten fuzzy-sets. % das datenset (zahl/4) besteht aus einfachen prädikaten. % es sind fuzzy-dreieck-zahlen des typs zahl(name,wert,min,max), % die z.B. so aussehen: 1.0 | /^\ | / \ | / \ 0.5 | / \ | / \ | / \ 0.0 |____/_________________\________ 0.0 1.0 2.0 3.0 4.0 5.0 Bild zeigt spezielle 'circa 3': zahl(_, eineFuzzyDrei, 3.0, 0.75, 3.9) für 3.0 liegt der wahrheitswert (y-achse) bei 1.0. Ab einem wert von 0.75 (x-achse) ist diese 'circa 3' (mit einem niedrigen wahrheitswert) wahr und steigt linear stetig bis zum maximum des wahrheitswertes 1.0 bei einem wert von 3.0. Bis 3.9 ist der wert stetig weniger wahr, danach falsch. Funktionswert der zwei steigungsgeraden(min und max) nach dem muster: "f(x)= x/a + y" wird nicht über steigungsgraden, sondern über den dreisatz ermittelt (-> wahr(Kategorie,Name,X,Prozent) ) Nur "dreieckige" fuzzy-zahlen sind damit handelbar. Probleme des Programms: - bei sich überschneidenden armen werden die werte nicht relativ (nach ihrer ausdehnung) miteinander verglichen. so kommt es, dass ein langer (sehr unscharfer) arm , mit langsam sinkenden werten bei der überschneidung mit einem kurzen (diskreteren) arm an bedeutung stark übervorteilt wird. - viele , momentan falsch zugeordnete vokale, würden durch eine zusätzliche angabe ihrer realisationsdauer richtig diskriminiert werden (realisation von lang/kurz-Vokale). */ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %$ HEADER$ % this for loading an external database :- include(load). % makes predicates dynamical % cache/3 ist interner temporärer cache :-dynamic(cache/3). :-dynamic(zahl/5). % speichert die nicht eingeordneten. als test benutzbar: wurden alle % Vokale zugeordnet ? wenn nicht, sind entweder die externen Daten % schlecht, oder muss die interne Datenbank adaptiert werden : % nichtZuordbar(Unzuordbar). :-dynamic(nichtZuordbar/1). %%%%%%%%%% database % base from Petursson & Neppert,'Elemente einer akustischen Phonetik' % page 139. extrem = unverwechselbar, deshalb krasse Min/Max % Vorderzungenvokale zahl(f1, de_con_ih, 0.26, 0.1, 0.32). %min zahl(f2, de_con_ih, 2.4, 2.1, 2.7). %max zahl(f1, de_con_i, 0.35, 0.3, 0.4). zahl(f2, de_con_i, 2.05, 1.75, 2.1). %min zahl(f1, de_con_e, 0.35, 0.3, 0.7). %max! zahl(f2, de_con_e, 2.09, 1.95, 2.3). %max zahl(f1, de_con_ae, 0.47, 0.4, 0.7). %max zahl(f2, de_con_ae, 1.8, 1.7, 1.95). zahl(f1, de_con_yh, 0.26, 0.1, 0.39). %min zahl(f2, de_con_yh, 1.64, 1.45, 1.93).%extremst zahl(f1, de_con_y, 0.35, 0.3, 0.43). %scharf zahl(f2, de_con_y, 1.55, 1.27, 1.8). zahl(f1, de_con_oe, 0.5, 0.33, 0.55). %max scharf zahl(f2, de_con_oe, 1.47, 1.2, 1.55). zahl(f1, de_con_oeh, 0.375, 0.34, 0.41).%scharf zahl(f2, de_con_oeh, 1.563, 1.3, 1.64). %Hinterzungenvokale zahl(f1, de_con_uh, 0.25, 0.1, 0.4).%min zahl(f2, de_con_uh, 0.75, 0.3, 0.95).%extremst zahl(f1, de_con_u, 0.35, 0.3, 0.45). zahl(f2, de_con_u, 0.85, 0.7, 1.0). %leider ungenau zahl(f1, de_con_oh, 0.35, 0.3, 0.42). zahl(f2, de_con_oh, 0.8, 0.48, 0.92). %leidr ungenau zahl(f1, de_con_o, 0.48, 0.42, 0.6). %max zahl(f2, de_con_o, 0.94, 0.8, 1.13). %extremst zahl(f1, de_con_ah, 0.7, 0.64, 0.83). %extrem hoher f1, niedrigr f2 zahl(f2, de_con_ah, 1.2, 1.1, 1.35). %max zahl(f1, de_con_a, 0.68, 0.55, 0.82).%min scharf zahl(f2, de_con_a, 1.28, 1.08, 1.45).%max min %%%%%%%%%%%%%%%%%%%%% hilfe help:- write('durch eingabe im interpreter von "listing." kann sich '), write('der gesamte quellcode angeschaut werden. dies mag helfen.'), write(' Mit fileFormants(filename). kann eine liste geladen werden.'),nl, write('t_Formants(Name_original ,F1,F2,Identified_as,Prozent). testet '),nl, write('die geladenen Formanten mit den internen Formant-Definitionen'),nl, write('have fun :-)'). %%%%%%%%%%%%%%%%%%%%%%%%%%% inis fileFormants(File):- retractall(loadedValue(_,_,_)), loadFormants(File), listing(loadedValue/3). t_Formants(Name,F1,F2,Identified,Prozent):- loadedValue(Name,F1,F2), asserta(nichtZuordbar(Name)), % flag wahr(f1,Identified,F1,ProzentA), wahr(f2,Identified,F2,ProzentB), %write('ahh'), ( (Prozent is (ProzentA+ProzentB) /2); % mittel aus den Formanten ( nichtZuordbar(Name), %hilft nicht zuordbare zu finden retract(nichtZuordbar(Name)) ) ) . % flag löschen %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % rule implementation % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % wahr(_,_,X,Prozent): gibt den wahrheitswert für beliebiges X % _ /^\___ % / \ % Min Kern Max %fallunterscheidung: % Min<=X<=Kern , Max>=X>Kern , sonst X=0 % mit allg. dreisatz ermitteln wahr(Kategorie,Name,X,Prozent):- zahl(Kategorie,Name,Kern,Min,Max), ( ( % Prozent = (X-Min)/(Kern-Min) Min =< X, X =< Kern, Tmp_a is X-Min, Tmp_b is Kern-Min, Prozent is Tmp_a/Tmp_b ) ; ( % Prozent = 1- (X-Kern)/(Max-Kern) Max >= X, X > Kern, Tmp_a is X-Kern, Tmp_b is Max-Kern, Tmp_c is Tmp_a/Tmp_b, Prozent is 1-Tmp_c ) ; ( XMax, Prozent is 0) ).