How can I write a program in prolog that breaks a word into syllables using predicate: First syllable is vowel-consonant-vowel .. or Second syllable: vowel-consonant-consonant-vowel. For example; abandon = aba-ndon ..
问题:
回答1:
This program will basically apply the rules you mention, but I don't think it will make a good tool for word processing.
vowel(a).
vowel(e).
vowel(i).
vowel(o).
vowel(u).
consonant(L):- not(vowel(L)).
syllable(W, S, RW):- atom_chars(W, [V1, C, V2|Tail]), vowel(V1), consonant(C), vowel(V2), !, atomic_list_concat([V1, C, V2], S), atomic_list_concat(Tail, RW).
syllable(W, S, RW):- atom_chars(W, [V1, C, C2, V2|Tail]), vowel(V1), consonant(C), consonant(C2),vowel(V2), !, atomic_list_concat([V1, C, C2, V2], S), atomic_list_concat(Tail, RW).
syllable(W, W, _).
break(W, B):- syllable(W, B, ''), !.
break(W, B):- syllable(W, S, RW), break(RW, B2), atomic_list_concat([S, '-', B2], B).
The program defines what a vowel is and what it is not. Also a syllable according to your rules, and how to break a word. Using the predicate ´break/2´ you can test it:
?- break(abaebbi, B).
B = 'aba-ebbi'
What makes me doubt about your rules, besides my poor English, is that testing with each word of my answer, returns the entire word always :)
?-break('syllable', B).
B = syllable
回答2:
There's a publically available list of words split into "syllables" (not sure exactly what the criteria is) here. Each line is a word, so you could read the words in one at time, split them into syllables, and store them in some dynamic predicate. Suppose the file is called mhypth.txt
, as it is at the link above:
go :-
%% I don't know why 65533 is the code for the separator, but it is.
string_codes(Sep, [65533]),
setup_call_cleanup(
open(<Path to mhyph.txt>>, read, St),
read_sylls(St, Sep),
close(St)
).
:- dynamic word_sylls/2.
read_sylls(Stream, Sep) :-
read_line_to_string(Stream, S),
(S == end_of_file -> true
;
split_string(S, Sep, Sep, Parts),
atomics_to_string(Parts, Word),
asserta(word_sylls(Word, Parts)),
read_sylls(Stream, Sep)
).
If you load this into your SWI Prolog interpreter, you can then do something like this:
?- go.
true.
?- word_sylls(A,B).
A = "Zurich",
B = ["Zu", "rich"] ;
A = "Zollner",
B = ["Zoll", "ner"] ;
A = "zymurgy",
B = ["zy", "mur", "gy"] ;
A = "zymosis",
B = ["zy", "mo", "sis"] ;
A = "zymoplastic",
B = ["zy", "mo", "plas", "tic"] ;
A = "zymolytic",
B = ["zy", "mo", "lyt", "ic"] ;
A = "zymologic",
B = ["zy", "mo", "log", "ic"]
?- word_sylls("abandon", Sylls).
Sylls = ["a", "ban", "don"].
?-