:- ensure_loaded(lojban-vocab).

anychar(C) :- vowel(C); consonant(C).

first(Elem, List) :- nth1(1, List, Elem).

nextto(X, Y, List) :- nth1(I, List, X), nth1(J, List, Y), succ(I, J).

gismu_extract_letters(String, A, B, C, D, E) :-
   nth1(1, String, A),
   nth1(2, String, B),
   nth1(3, String, C),
   nth1(4, String, D),
   nth1(5, String, E).

excise(List, Index, Rest) :-
   bagof(Elem, BeforeIndex^(nth1(BeforeIndex, List, Elem), BeforeIndex < Index), Firstpart),
   bagof(Elem, AfterIndex^(nth1(AfterIndex, List, Elem), AfterIndex > Index), Lastpart), !,
   append(Firstpart, Lastpart, Rest);
   bagof(Elem, BeforeIndex^(nth1(BeforeIndex, List, Elem), BeforeIndex < Index), Rest);
   bagof(Elem, AfterIndex^(nth1(AfterIndex, List, Elem), AfterIndex > Index), Rest).

has_double(String) :- adjacent_letters(String, Charcode1, Charcode2), Charcode1 = Charcode2.

vowelfinal(String) :- last(Last, String), vowel([Last]).

consonantinitial(String) :- string_to_list(String, List), first(First, List), atom_char(Consonant, First), consonant(Consonant).

has_initial_pair(String) :- nth1(1, String, A), nth1(2, String, B), initial_pair([A, B]).

adjacent_letters(String, Charcode1, Charcode2) :- nth1(I, String, Charcode1), nth1(J, String, Charcode2), succ(I, J).

% strcons(Part1, Part2, Whole) :- append(Part1, Part2, Whole).

lujvo2(L, G1, G2) :- rafsi(R1, G1), rafsi(R2, G2), append(R1, R2, L), vowelfinal(L), \+has_illegal_cluster(L).

has_illegal_cluster(String) :- nextto(Charcode1, Charcode2, String), once(is_illegal_cluster(Charcode1, Charcode2)).

is_illegal_cluster(Charcode1, Charcode2) :- Charcode1 = Charcode2 ;
   voiced([Charcode1]), unvoiced([Charcode2]);
   unvoiced([Charcode1]), voiced([Charcode2]);
   once(specific_forbidden([Charcode1, Charcode2])).

rmgivenchar(String, Index, Rest) :- integer(Index), string_to_list(String, List), excise(List, Index, Remainder), string_to_list(Rest, Remainder).

rmonechar(String, Rest) :- select(String, _, Rest).

addonechar(Original, Augmented) :- string_to_list(Original, OriginalL), anychar(C), select(AugmentedL, C, OriginalL), string_to_list(Augmented, AugmentedL).

possiblegismu(String) :- gismucvtemplate(String), has_initial_pair(String), \+has_illegal_cluster(String).

gismucvtemplate(String) :-
   % string_to_list(String, [A, B, C, D, E]),
   % gismu_extract_letters(String, A, B, C, D, E),
   String = [A, B, C, D, E],
   consonant([A]), consonant([B]), vowel([C]), consonant([D]), vowel([E]);
   % gismu_extract_letters(String, A, B, C, D, E),
   % string_to_list(String, [A, B, C, D, E]),
   String = [A, B, C, D, E],
   consonant([A]), vowel([B]), consonant([C]), consonant([D]), vowel([E]).

lujvo_with_two_embedded_gismu(Lujvo, Gismu1, Gismu2) :-
   lujvo2(L, _, _),
   select(L, _, G1), select(L, _, G2), G1 \== G2,
   possiblegismu(G1), gismu(G1),
   possiblegismu(G2), gismu(G2),
   % Output
   string_to_list(Lujvo, L),
   string_to_list(Gismu1, G1), string_to_list(Gismu2, G2).

print_all_gismu :-
% test predicate
   gismu(G), string_to_list(GS, G), print(GS), nl, fail.
