1:- module(pstring, [
    2   pstr_upper/2,
    3   pstr_lower/2,
    4   pstr_split/3,
    5   pstr_join/3,
    6   pstr_contains/2,
    7   pstr_contains_t/3,
    8   pstr_prefix/2,
    9   pstr_prefix_t/3,
   10   pstr_trim/2,
   11   pstr_replace/4
   12]).   13
   14:- use_module(purity).   15:- use_module(pchar).   16:- use_module(plist).   17
   18% pstr_upper(String, Upper).
   19pstr_upper([], []).
   20pstr_upper([C|T], [U|R]) :-
   21    pchar:ch_map(C, _, U),
   22    pstr_upper(T, R).
   23
   24% pstr_lower(String, Lower).
   25pstr_lower([], []).
   26pstr_lower([C|T], [L|R]) :-
   27    pchar:ch_map(C, L, _),
   28    pstr_lower(T, R).
   29
   30% pstr_replace(String, Find, Replace, Replaced).
   31pstr_replace([], _, _, []).
   32pstr_replace([A|T], F, R, Rp) :-
   33    pstr_prefix_t(F, [A|T], IsPrefix),
   34    pstr_replace_(IsPrefix, [A|T], F, R, Rp).
   35
   36pstr_replace_(true, Orig, F, R, Rp) :-
   37    append(F, Remaining, Orig),
   38    append(R, Remaining, Rp).
   39pstr_replace_(false, [A|T], F, R, [A|Rpt]) :-
   40    pstr_replace(T, F, R, Rpt).
   41
   42% pstr_trim(UnTrimmed, Trimmed).
   43pstr_trim([A|T], Out) :-
   44    pchar_type(A, Type),
   45    pstr_trim_start(Type, A, T, Out).
   46
   47pstr_trim_start(whitespace, _, T, Out) :-  pstr_trim(T, Out).
   48pstr_trim_start(alpha, A, T, [A|Out]) :- pstr_trim_end(T, Out).
   49pstr_trim_start(digit, A, T, [A|Out]) :- pstr_trim_end(T, Out).
   50pstr_trim_start(symbol, A, T, [A|Out]) :- pstr_trim_end(T, Out).
   51
   52pstr_trim_end([], []).
   53pstr_trim_end([A|T], Trimmed) :-
   54    pstr_all_whitespace([A|T], R),
   55    pstr_trim_end_(R, A, T, Trimmed).
   56
   57pstr_trim_end_(true, _, _, []).
   58pstr_trim_end_(false, A, T, [A|End]) :- pstr_trim_end(T, End).
   59
   60pstr_all_whitespace([], true).
   61pstr_all_whitespace([A|T], R) :-
   62    pchar_type(A, Type),
   63    pstr_all_whitespace_(Type, T, R).
   64
   65pstr_all_whitespace_(whitespace, T, R) :- pstr_all_whitespace(T, R).
   66pstr_all_whitespace_(alpha, _, false).
   67pstr_all_whitespace_(digit, _, false).
   68pstr_all_whitespace_(symbol, _, false).
   69
   70% pstr_split(StrToSplit, DelimiterChar, Split).
   71pstr_split(A, D, B) :-
   72    ptype(D, pchar),
   73    pstr_split_(A, D, B).
   74
   75pstr_split_([], _, []).
   76pstr_split_([A|T], D, Split) :-
   77    pdif_t(A,D,B),
   78    pstr_split(B,A,T,D,Split).
   79
   80pstr_split(false, D, T, D, Split) :-
   81    pstr_split_(T,D,Split).
   82pstr_split(true, A, T, D, [S|Rest]) :-
   83    find_split([A|T], D, Rem, S),
   84    pstr_split_(Rem, D, Rest). 
   85
   86find_split([], _, [], []).
   87find_split([A|T], D, Rem, Split) :-
   88    pdif_t(A,D,B),
   89    find_split(B, A, T, D, Rem, Split).
   90
   91find_split(false, D, T, D, T, []).
   92find_split(true, A, T, D, Rem, [A|Rest]) :-
   93    find_split(T, D, Rem, Rest).
   94
   95% pstr_join(ListOfStrings, Delimiter, Joined).
   96pstr_join(A, D, B) :-
   97    ptype(D, pchar),
   98    pstr_join_(A, D, B).
   99
  100pstr_join_([], _, []).
  101pstr_join_([A|T], D, S) :-
  102    pstr_join(A, T, D, S).
  103
  104pstr_join([], T, D, R) :-
  105    pstr_join2(T, D, R).
  106pstr_join([A|At], T, D, [A|R]) :-
  107    pstr_join(At, T, D, R).
  108
  109pstr_join2([], _, []).
  110pstr_join2([N|T], D, [D|R]) :-
  111    pstr_join_([N|T], D, R).
  112
  113% pstr_contains(String, SubString).
  114pstr_contains(String, SubString) :-
  115    pstr_contains_t(String, SubString, true).
  116
  117% pstr_contains(String, SubString, Contains).
  118pstr_contains_t([], _, false). 
  119pstr_contains_t([A|T], B, C) :-
  120    pstr_prefix_t(B, [A|T], Prefix),
  121    pstr_contains_(Prefix, [A|T], B, C).
  122
  123pstr_contains_(true, _, _, true).
  124pstr_contains_(false, [_|At], B, C) :-
  125    pstr_contains_t(At, B, C).
  126
  127% pstr_prefix(Prefix, String).
  128pstr_prefix(Prefix, String) :-
  129    pstr_prefix_t(Prefix, String, true).
  130
  131% pstr_prefix(Prefix, String, IsPrefix).
  132pstr_prefix_t([], _, true).
  133pstr_prefix_t([A|At], [B|Bt], IsPrefix) :-
  134    pcompare(A, B, C),
  135    pstr_prefix(C, At, Bt, IsPrefix).
  136
  137pstr_prefix(=, At, Bt, B) :- 
  138    pstr_prefix_t(At, Bt, B).
  139pstr_prefix(<, _, _, false).
  140pstr_prefix(>, _, _, false)