word processing in prolog

2019-07-23 05:59发布

问题:

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"].

?- 


标签: prolog