:- module string.
:- use_module bool, builtin, char, float, int, list, private_builtin, require, std_util.
:- type (string:specifier)
	--->	conv((string:flags) :: (list:list(character)), (string:width) :: (std_util:maybe((list:list(character)))), (string:precision) :: (std_util:maybe((list:list(character)))), (string:spec) :: (string:spec))
	;	string((list:list(character)))
	.
:- type (string:spec)
	--->	d(int)
	;	i(int)
	;	o(int)
	;	u(int)
	;	x(int)
	;	cX(int)
	;	p(int)
	;	e(float)
	;	cE(float)
	;	f(float)
	;	cF(float)
	;	g(float)
	;	cG(float)
	;	c(character)
	;	s(string)
	;	percent
	.
:- pragma foreign_import_module("C", string).
:- pred string:foldl_substring_2(pred(character, T_1, T_1), string, int, int, T_1, T_1).
:- mode string:foldl_substring_2((pred((builtin:in), (builtin:in), (builtin:out)) is det), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)) is det.
:- mode string:foldl_substring_2((pred((builtin:in), (builtin:di), (builtin:uo)) is det), (builtin:in), (builtin:in), (builtin:in), (builtin:di), (builtin:uo)) is det.
:- mode string:foldl_substring_2((pred((builtin:in), (builtin:in), (builtin:out)) is semidet), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)) is semidet.
:- mode string:foldl_substring_2((pred((builtin:in), (builtin:in), (builtin:out)) is nondet), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)) is nondet.
:- mode string:foldl_substring_2((pred((builtin:in), (builtin:in), (builtin:out)) is multi), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)) is multi.
:- pred string:foldr_substring_2(pred(character, T_1, T_1), string, int, int, T_1, T_1).
:- mode string:foldr_substring_2((pred((builtin:in), (builtin:in), (builtin:out)) is det), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)) is det.
:- mode string:foldr_substring_2((pred((builtin:in), (builtin:di), (builtin:uo)) is det), (builtin:in), (builtin:in), (builtin:in), (builtin:di), (builtin:uo)) is det.
:- mode string:foldr_substring_2((pred((builtin:in), (builtin:in), (builtin:out)) is semidet), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)) is semidet.
:- mode string:foldr_substring_2((pred((builtin:in), (builtin:in), (builtin:out)) is nondet), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)) is nondet.
:- mode string:foldr_substring_2((pred((builtin:in), (builtin:in), (builtin:out)) is multi), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)) is multi.
:- pred string:char_list_to_upper((list:list(character)), (list:list(character))).
:- mode string:char_list_to_upper((builtin:in), (builtin:out)) is det.
:- pred string:char_list_to_lower((list:list(character)), (list:list(character))).
:- mode string:char_list_to_lower((builtin:in), (builtin:out)) is det.
:- pred string:all_match((pred character), string).
:- mode string:all_match((pred((builtin:in)) is semidet), (builtin:in)) is semidet.
:- pred string:all_match_2(int, (pred character), string).
:- mode string:all_match_2((builtin:in), (pred((builtin:in)) is semidet), (builtin:in)) is semidet.
:- func string:words_2((pred character), string, int, (list:list(string))) = (list:list(string)).
:- mode string:words_2((pred((builtin:in)) is semidet), (builtin:in), (builtin:in), (builtin:in)) = (builtin:out) is det.
:- func string:preceding_boundary((pred character), string, int) = int.
:- mode string:preceding_boundary((pred((builtin:in)) is semidet), (builtin:in), (builtin:in)) = (builtin:out) is det.
string:length(S_3) = L_4 :-
		string:length(S_3, L_4).
:- pragma promise_pure((string:length)/2).
:- pragma foreign_proc("C", string:length(Str :: (builtin:ui), Length :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	Length = strlen(Str);
").
:- pragma foreign_proc("C", string:length(Str :: (builtin:in), Length :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	Length = strlen(Str);
").
string:append(S1_4, S2_5) = S3_6 :-
		string:append(S1_4, S2_5, S3_6).
string:(S1_4 ++ S2_5) = HeadVar__3_3 :-
		HeadVar__3_3 = string:append(S1_4, S2_5).
string:remove_suffix(A_4, B_5, C_6) :-
		string:to_char_list(A_4, LA_7),
		string:to_char_list(B_5, LB_8),
		string:to_char_list(C_6, LC_9),
		list:remove_suffix(LA_7, LB_8, LC_9).
string:char_to_string(C_3) = S1_4 :-
		string:char_to_string(C_3, S1_4).
string:char_to_string(Char_3, String_4) :-
		V_5 = list:[Char_3 | V_6],
		V_6 = list:[],
		string:to_char_list(String_4, V_5).
string:int_to_string(N_3) = S1_4 :-
		string:int_to_string(N_3, S1_4).
string:int_to_string(N_3, Str_4) :-
		V_5 = 10,
		string:int_to_base_string(N_3, V_5, Str_4).
string:int_to_base_string(N1_4, N2_5) = S2_6 :-
		string:int_to_base_string(N1_4, N2_5, S2_6).
string:float_to_string(R_3) = S2_4 :-
		string:float_to_string(R_3, S2_4).
:- pragma foreign_proc("C", string:float_to_string(FloatVal :: (builtin:in), FloatString :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	char buf[500];
	sprintf(buf, \"%#.15g\", FloatVal);
	MR_allocate_aligned_string_msg(FloatString, strlen(buf), MR_PROC_LABEL);
	strcpy(FloatString, buf);
}").
:- pragma promise_pure((string:first_char)/3).
:- pragma foreign_proc("C", string:first_char(Str :: (builtin:uo), First :: (builtin:in), Rest :: (builtin:in)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	size_t len = strlen(Rest) + 1;
	MR_allocate_aligned_string_msg(Str, len, MR_PROC_LABEL);
	Str[0] = First;
	strcpy(Str + 1, Rest);
}").
:- pragma foreign_proc("C", string:first_char(Str :: (builtin:in), First :: (builtin:uo), Rest :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	First = Str[0];
	if (First == \'\\0\') {
		SUCCESS_INDICATOR = MR_FALSE;
	} else {
		Str++;
		/*
		** We need to make a copy to ensure that the pointer is
		** word-aligned.
		*/
		MR_allocate_aligned_string_msg(Rest, strlen(Str),
			MR_PROC_LABEL);
		strcpy(Rest, Str);
		SUCCESS_INDICATOR = MR_TRUE;
	}
}").
:- pragma foreign_proc("C", string:first_char(Str :: (builtin:in), First :: (builtin:in), Rest :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	if (Str[0] != First || First == \'\\0\') {
		SUCCESS_INDICATOR = MR_FALSE;
	} else {
		Str++;
		/*
		** We need to make a copy to ensure that the pointer is
		** word-aligned.
		*/
		MR_allocate_aligned_string_msg(Rest, strlen(Str),
			MR_PROC_LABEL);
		strcpy(Rest, Str);
		SUCCESS_INDICATOR = MR_TRUE;
	}
}").
:- pragma foreign_proc("C", string:first_char(Str :: (builtin:in), First :: (builtin:uo), Rest :: (builtin:in)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	First = Str[0];
	SUCCESS_INDICATOR = (First != \'\\0\' && strcmp(Str + 1, Rest) == 0);
").
:- pragma foreign_proc("C", string:first_char(Str :: (builtin:in), First :: (builtin:in), Rest :: (builtin:in)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	SUCCESS_INDICATOR = (
		Str[0] == First &&
		First != \'\\0\' &&
		strcmp(Str + 1, Rest) == 0
	);
").
string:replace_all(S1_5, S2_6, S3_7) = S4_8 :-
		string:replace_all(S1_5, S2_6, S3_7, S4_8).
string:to_lower(S1_3) = S2_4 :-
		string:to_lower(S1_3, S2_4).
string:to_lower(StrIn_3, StrOut_4) :-
		string:to_char_list(StrIn_3, List_5),
		string:char_list_to_lower(List_5, ListLow_6),
		string:from_char_list(ListLow_6, StrOut_4).
string:to_upper(S1_3) = S2_4 :-
		string:to_upper(S1_3, S2_4).
string:to_upper(StrIn_3, StrOut_4) :-
		string:to_char_list(StrIn_3, List_5),
		string:char_list_to_upper(List_5, ListUpp_6),
		string:from_char_list(ListUpp_6, StrOut_4).
string:capitalize_first(S1_3) = S2_4 :-
		string:capitalize_first(S1_3, S2_4).
string:uncapitalize_first(S1_3) = S2_4 :-
		string:uncapitalize_first(S1_3, S2_4).
string:to_char_list(S_3) = Cs_4 :-
		string:to_char_list(S_3, Cs_4).
:- pragma promise_pure((string:to_char_list)/2).
:- pragma foreign_proc("C", string:to_char_list(Str :: (builtin:uo), CharList :: (builtin:in)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
		/* mode (uo, in) is det */
	MR_Word char_list_ptr;
	size_t size;
/*
** loop to calculate list length + sizeof(MR_Word) in `size\' using list in
** `char_list_ptr\'
*/
	size = sizeof(MR_Word);
	char_list_ptr = CharList;
	while (! MR_list_is_empty(char_list_ptr)) {
		size++;
		char_list_ptr = MR_list_tail(char_list_ptr);
	}
/*
** allocate (length + 1) bytes of heap space for string
** i.e. (length + 1 + sizeof(MR_Word) - 1) / sizeof(MR_Word) words
*/
	MR_allocate_aligned_string_msg(Str, size, MR_PROC_LABEL);

/*
** loop to copy the characters from the char_list to the string
*/
	size = 0;
	char_list_ptr = CharList;
	while (! MR_list_is_empty(char_list_ptr)) {
		Str[size++] = MR_list_head(char_list_ptr);
		char_list_ptr = MR_list_tail(char_list_ptr);
	}
/*
** null terminate the string
*/
	Str[size] = \'\\0\';
}").
:- pragma foreign_proc("C", string:to_char_list(Str :: (builtin:in), CharList :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	MR_ConstString p = Str + strlen(Str);
	CharList = MR_list_empty_msg(MR_PROC_LABEL);
	while (p > Str) {
		p--;
		CharList = MR_list_cons_msg((MR_UnsignedChar) *p, CharList,
			MR_PROC_LABEL);
	}
}").
string:from_char_list(Cs_3) = S_4 :-
		string:from_char_list(Cs_3, S_4).
string:from_char_list(CharList_3, Str_4) :-
		string:to_char_list(Str_4, CharList_3).
string:from_rev_char_list(Cs_3) = S_4 :-
		string:from_rev_char_list(Cs_3, S_4).
:- pragma foreign_proc("C", string:from_rev_char_list(Chars :: (builtin:in), Str :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
{
	MR_Word list_ptr;
	MR_Word size, len;
/*
** loop to calculate list length + sizeof(MR_Word) in `size\' using list in
** `list_ptr\' and separately count the length of the string
*/
	size = sizeof(MR_Word);
	len = 1;
	list_ptr = Chars;
	while (!MR_list_is_empty(list_ptr)) {
		size++;
		len++;
		list_ptr = MR_list_tail(list_ptr);
	}
/*
** allocate (length + 1) bytes of heap space for string
** i.e. (length + 1 + sizeof(MR_Word) - 1) / sizeof(MR_Word) words
*/
	MR_allocate_aligned_string_msg(Str, size, MR_PROC_LABEL);

/*
** set size to be the offset of the end of the string
** (ie the \\0) and null terminate the string.
*/
	Str[--len] = \'\\0\';
/*
** loop to copy the characters from the list_ptr to the string
** in reverse order.
*/
	list_ptr = Chars;
	while (!MR_list_is_empty(list_ptr)) {
		Str[--len] = (MR_Char) MR_list_head(list_ptr);
		list_ptr = MR_list_tail(list_ptr);
	}
}").
string:det_to_int(S_3) = HeadVar__2_2 :-
		HeadVar__2_2 = string:det_base_string_to_int(V_4, S_3),
		V_4 = 10.
string:to_int(String_3, Int_4) :-
		V_5 = 10,
		string:base_string_to_int(V_5, String_3, Int_4).
:- pragma foreign_proc("C", string:to_float(FloatString :: (builtin:in), FloatVal :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	/*
	** Use a temporary, since we can\'t don\'t know whether FloatVal is a
	** double or float.  The %c checks for any erroneous characters
	** appearing after the float; if there are then sscanf() will
	** return 2 rather than 1.
	**
	** The logic used here is duplicated in the function MR_trace_is_float
	** in trace/mercury_trace_util.c.
	*/
	double tmpf;
	char   tmpc;
	SUCCESS_INDICATOR =
		(!MR_isspace(FloatString[0])) &&
		(sscanf(FloatString, \"%lf%c\", &tmpf, &tmpc) == 1);
		/* MR_TRUE if sscanf succeeds, MR_FALSE otherwise */
	FloatVal = tmpf;
}").
string:is_alpha(S_2) :-
		V_3 = char:is_alpha,
		string:all_match(V_3, S_2).
string:is_alpha_or_underscore(S_2) :-
		V_3 = char:is_alpha_or_underscore,
		string:all_match(V_3, S_2).
string:is_alnum_or_underscore(S_2) :-
		V_3 = char:is_alnum_or_underscore,
		string:all_match(V_3, S_2).
string:pad_left(S1_5, C_6, N_7) = S2_8 :-
		string:pad_left(S1_5, C_6, N_7, S2_8).
string:pad_right(S1_5, C_6, N_7) = S2_8 :-
		string:pad_right(S1_5, C_6, N_7, S2_8).
string:duplicate_char(C_4, N_5) = S_6 :-
		string:duplicate_char(C_4, N_5, S_6).
string:duplicate_char(Char_4, Count_5, String_6) :-
		String_6 = string:from_char_list(V_7),
		V_7 = list:duplicate(Count_5, Char_4).
:- pragma foreign_proc("C", string:contains_char(Str :: (builtin:in), Ch :: (builtin:in)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL) && Ch != \'\\0\';
").
:- pragma foreign_proc("C", string:index(Str :: (builtin:in), Index :: (builtin:in), Ch :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "

                /*
		** We do not test for negative values of Index
                ** because (a) MR_Word is unsigned and hence a
                ** negative argument will appear as a very large
                ** positive one after the cast and (b) anybody
                ** dealing with the case where strlen(Str) > MAXINT
                ** is clearly barking mad (and one may well
                ** get an integer overflow error in this case).
                */

	if ((MR_Unsigned) Index >= strlen(Str)) {
		SUCCESS_INDICATOR = MR_FALSE;
	} else {
		SUCCESS_INDICATOR = MR_TRUE;
		Ch = Str[Index];
	}
").
string:index_det(S_4, N_5) = C_6 :-
		string:index_det(S_4, N_5, C_6).
string:unsafe_index(S_4, N_5) = C_6 :-
		string:unsafe_index(S_4, N_5, C_6).
:- pragma foreign_proc("C", string:unsafe_index(Str :: (builtin:in), Index :: (builtin:in), Ch :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	Ch = Str[Index];
").
:- pragma foreign_proc("C", string:set_char(Ch :: (builtin:in), Index :: (builtin:in), Str0 :: (builtin:in), Str :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	size_t len = strlen(Str0);
	if ((MR_Unsigned) Index >= len) {
		SUCCESS_INDICATOR = MR_FALSE;
	} else {
		SUCCESS_INDICATOR = MR_TRUE;
		MR_allocate_aligned_string_msg(Str, len, MR_PROC_LABEL);
		strcpy(Str, Str0);
		MR_set_char(Str, Index, Ch);
	}
").
string:set_char_det(C_5, N_6, S0_7) = S_8 :-
		string:set_char_det(C_5, N_6, S0_7, S_8).
string:unsafe_set_char(C_5, N_6, S0_7) = S_8 :-
		string:unsafe_set_char(C_5, N_6, S0_7, S_8).
:- pragma foreign_proc("C", string:unsafe_set_char(Ch :: (builtin:in), Index :: (builtin:in), Str0 :: (builtin:in), Str :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	size_t len = strlen(Str0);
	MR_allocate_aligned_string_msg(Str, len, MR_PROC_LABEL);
	strcpy(Str, Str0);
	MR_set_char(Str, Index, Ch);
").
string:foldl(F_5, S_6, A_7) = B_8 :-
		P_9 = (pred(V_15::(builtin:in), V_14::(builtin:in), V_13::(builtin:out)) is det :-
			some [] (
				V_15 = X_16,
				V_14 = Y_17,
				V_13 = Z_18,
				Z_18 = apply(F_5, X_16, Y_17)
			)
		),
		string:foldl(P_9, S_6, A_7, B_8).
string:foldl(Closure_5, String_6, Acc0_7, Acc_8) :-
		string:length(String_6, Length_9),
		V_10 = 0,
		string:foldl_substring(Closure_5, String_6, V_10, Length_9, Acc0_7, Acc_8).
string:foldl_substring(F_7, S_8, Start_9, Count_10, A_11) = B_12 :-
		P_13 = (pred(V_19::(builtin:in), V_18::(builtin:in), V_17::(builtin:out)) is det :-
			some [] (
				V_19 = X_20,
				V_18 = Y_21,
				V_17 = Z_22,
				Z_22 = apply(F_7, X_20, Y_21)
			)
		),
		string:foldl_substring(P_13, S_8, Start_9, Count_10, A_11, B_12).
string:foldl_substring(Closure_7, String_8, Start0_9, Count0_10, Acc0_11, Acc_12) :-
		Start_13 = int:max(V_15, Start0_9),
		V_15 = 0,
		Count_14 = int:min(Count0_10, V_16),
		V_16 = int:(V_17 - Start_13),
		V_17 = string:length(String_8),
		string:foldl_substring_2(Closure_7, String_8, Start_13, Count_14, Acc0_11, Acc_12).
string:foldr(F_5, String_6, Acc0_7) = Acc_8 :-
		Closure_9 = (pred(V_15::(builtin:in), V_14::(builtin:in), V_13::(builtin:out)) is det :-
			some [] (
				V_15 = X_16,
				V_14 = Y_17,
				V_13 = Z_18,
				Z_18 = apply(F_5, X_16, Y_17)
			)
		),
		string:foldr(Closure_9, String_6, Acc0_7, Acc_8).
string:foldr(Closure_5, String_6, Acc0_7, Acc_8) :-
		V_9 = 0,
		V_10 = string:length(String_6),
		string:foldr_substring(Closure_5, String_6, V_9, V_10, Acc0_7, Acc_8).
string:foldr_substring(F_7, String_8, Start_9, Count_10, Acc0_11) = Acc_12 :-
		Closure_13 = (pred(V_19::(builtin:in), V_18::(builtin:in), V_17::(builtin:out)) is det :-
			some [] (
				V_19 = X_20,
				V_18 = Y_21,
				V_17 = Z_22,
				Z_22 = apply(F_7, X_20, Y_21)
			)
		),
		string:foldr_substring(Closure_13, String_8, Start_9, Count_10, Acc0_11, Acc_12).
string:foldr_substring(Closure_7, String_8, Start0_9, Count0_10, Acc0_11, Acc_12) :-
		Start_13 = int:max(V_15, Start0_9),
		V_15 = 0,
		Count_14 = int:min(Count0_10, V_16),
		V_16 = int:(V_17 - Start_13),
		V_17 = string:length(String_8),
		string:foldr_substring_2(Closure_7, String_8, Start_13, Count_14, Acc0_11, Acc_12).
string:words(SepP_4, String_5) = Words_6 :-
		I_7 = string:preceding_boundary(V_8, String_5, V_9),
		V_8 = std_util:isnt(SepP_4),
		V_9 = int:(V_10 - V_11),
		V_10 = string:length(String_5),
		V_11 = 1,
		Words_6 = string:words_2(SepP_4, String_5, I_7, V_12),
		V_12 = list:[].
string:words(String_3) = HeadVar__2_2 :-
		HeadVar__2_2 = string:words(V_4, String_3),
		V_4 = char:is_whitespace.
:- pragma foreign_proc("C", string:split(Str :: (builtin:in), Count :: (builtin:in), Left :: (builtin:uo), Right :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	MR_Integer len;
	MR_Word tmp;
	if (Count <= 0) {
		MR_make_aligned_string(MR_LVALUE_CAST(MR_ConstString, Left),
			\"\");
		Right = Str;
	} else {
		len = strlen(Str);
		if (Count > len) Count = len;
		MR_allocate_aligned_string_msg(Left, Count, MR_PROC_LABEL);
		memcpy(Left, Str, Count);
		Left[Count] = \'\\0\';
		/*
		** We need to make a copy to ensure that the pointer is
		** word-aligned.
		*/
		MR_allocate_aligned_string_msg(Right, len - Count,
			MR_PROC_LABEL);
		strcpy(Right, Str + Count);
	}
}").
string:left(S1_4, N_5) = S2_6 :-
		string:left(S1_4, N_5, S2_6).
string:left(String_4, Count_5, LeftString_6) :-
		string:split(String_4, Count_5, LeftString_6, _RightString_7).
string:right(S1_4, N_5) = S2_6 :-
		string:right(S1_4, N_5, S2_6).
string:right(String_4, RightCount_5, RightString_6) :-
		string:length(String_4, Length_7),
		LeftCount_8 = int:(Length_7 - RightCount_5),
		string:split(String_4, LeftCount_8, _LeftString_9, RightString_6).
string:substring(S1_5, N1_6, N2_7) = S2_8 :-
		string:substring(S1_5, N1_6, N2_7, S2_8).
:- pragma foreign_proc("C", string:substring(Str :: (builtin:in), Start :: (builtin:in), Count :: (builtin:in), SubString :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	MR_Integer len;
	MR_Word tmp;
	if (Start < 0) Start = 0;
	if (Count <= 0) {
		MR_make_aligned_string(
			MR_LVALUE_CAST(MR_ConstString, SubString),
			\"\");
	} else {
		len = strlen(Str);
		if (Start > len) Start = len;
		if (Count > len - Start) Count = len - Start;
		MR_allocate_aligned_string_msg(SubString, Count, MR_PROC_LABEL);
		memcpy(SubString, Str + Start, Count);
		SubString[Count] = \'\\0\';
	}
}").
string:unsafe_substring(S1_5, N1_6, N2_7) = S2_8 :-
		string:unsafe_substring(S1_5, N1_6, N2_7, S2_8).
:- pragma foreign_proc("C", string:unsafe_substring(Str :: (builtin:in), Start :: (builtin:in), Count :: (builtin:in), SubString :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	MR_Integer len;
	MR_allocate_aligned_string_msg(SubString, Count, MR_PROC_LABEL);
	memcpy(SubString, Str + Start, Count);
	SubString[Count] = \'\\0\';
}").
:- pragma foreign_proc("C", string:append_list(Strs :: (builtin:in)) = (Str :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	MR_Word	list = Strs;
	MR_Word	tmp;
	size_t	len;

		/* Determine the total length of all strings */
	len = 0;
	while (!MR_list_is_empty(list)) {
		len += strlen((MR_String) MR_list_head(list));
		list = MR_list_tail(list);
	}

		/* Allocate enough word aligned memory for the string */
	MR_allocate_aligned_string_msg(Str, len, MR_PROC_LABEL);

		/* Copy the strings into the new memory */
	len = 0;
	list = Strs;
	while (!MR_list_is_empty(list)) {
		strcpy((MR_String) Str + len, (MR_String) MR_list_head(list));
		len += strlen((MR_String) MR_list_head(list));
		list = MR_list_tail(list);
	}

		/* Set the last character to the null char */
	Str[len] = \'\\0\';
}").
string:append_list(Lists_3, HeadVar__2_2) :-
		HeadVar__2_2 = string:append_list(Lists_3).
:- pragma foreign_proc("C", string:join_list(Sep :: (builtin:in), Strs :: (builtin:in)) = (Str :: (builtin:uo)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	MR_Word	list = Strs;
	MR_Word	tmp;
	size_t	len = 0;
	size_t	sep_len;
	MR_bool	add_sep;

	sep_len = strlen(Sep);

		/* Determine the total length of all strings */
	len = 0;
	add_sep = MR_FALSE;
	while (!MR_list_is_empty(list)) {
		if (add_sep) {
			len += sep_len;
		}
		
		len += strlen((MR_String) MR_list_head(list));
		list = MR_list_tail(list);
		add_sep = MR_TRUE;
	}

	MR_allocate_aligned_string_msg(Str, len, MR_PROC_LABEL);

		/* Copy the strings into the new memory */
	len = 0;
	list = Strs;
	add_sep = MR_FALSE;
	while (!MR_list_is_empty(list)) {
		if (add_sep) {
			strcpy((MR_String) Str + len, Sep);
			len += sep_len;
		}

		strcpy((MR_String) Str + len, (MR_String) MR_list_head(list));
		len += strlen((MR_String) MR_list_head(list));
		list = MR_list_tail(list);
		add_sep = MR_TRUE;
	}

		/* Set the last character to the null char */
	Str[len] = \'\\0\';
}").
string:hash(S_3) = N_4 :-
		string:hash(S_3, N_4).
:- pragma foreign_proc("C", string:sub_string_search(WholeString :: (builtin:in), SubString :: (builtin:in), Index :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "{
	char *match;
	match = strstr(WholeString, SubString);
	if (match) {
		Index = match - WholeString;
		SUCCESS_INDICATOR = MR_TRUE;
	} else {
		SUCCESS_INDICATOR = MR_FALSE;
	}
}").
string:format(S1_4, PT_5) = S2_6 :-
		string:format(S1_4, PT_5, S2_6).
string:foldl_substring_2(Closure_7, String_8, I_9, Count_10, Acc0_11, Acc_12) :-
		(if
			V_14 = 0,
			int:(V_14 < Count_10)
		then
			V_15 = string:unsafe_index(String_8, I_9),
			call(Closure_7, V_15, Acc0_11, Acc1_13),
			V_16 = int:(I_9 + V_18),
			V_18 = 1,
			V_17 = int:(Count_10 - V_19),
			V_19 = 1,
			string:foldl_substring(Closure_7, String_8, V_16, V_17, Acc1_13, Acc_12)
		else
			Acc_12 = Acc0_11
		).
string:foldr_substring_2(Closure_7, String_8, I_9, Count_10, Acc0_11, Acc_12) :-
		(if
			V_14 = 0,
			int:(V_14 < Count_10)
		then
			V_15 = string:unsafe_index(String_8, V_16),
			V_16 = int:(V_17 - V_18),
			V_17 = int:(I_9 + Count_10),
			V_18 = 1,
			call(Closure_7, V_15, Acc0_11, Acc1_13),
			V_19 = int:(Count_10 - V_20),
			V_20 = 1,
			string:foldr_substring_2(Closure_7, String_8, I_9, V_19, Acc1_13, Acc_12)
		else
			Acc_12 = Acc0_11
		).
string:all_match(P_3, String_4) :-
		V_5 = int:(V_6 - V_7),
		V_6 = string:length(String_4),
		V_7 = 1,
		string:all_match_2(V_5, P_3, String_4).
string:all_match_2(I_4, P_5, String_6) :-
		(if
			V_7 = 0,
			int:(I_4 >= V_7)
		then
			V_8 = string:unsafe_index(String_6, I_4),
			call(P_5, V_8),
			V_9 = int:(I_4 - V_10),
			V_10 = 1,
			string:all_match_2(V_9, P_5, String_6)
		else
			true
		).
string:words_2(SepP_6, String_7, WordEnd_8, Words0_9) = Words_10 :-
		(if
			V_14 = 0,
			int:(WordEnd_8 < V_14)
		then
			Words_10 = Words0_9
		else
			WordPre_11 = string:preceding_boundary(SepP_6, String_7, WordEnd_8),
			Word_12 = string:unsafe_substring(String_7, V_15, V_16),
			V_15 = int:(WordPre_11 + V_17),
			V_17 = 1,
			V_16 = int:(WordEnd_8 - WordPre_11),
			PrevWordEnd_13 = string:preceding_boundary(V_18, String_7, WordPre_11),
			V_18 = std_util:isnt(SepP_6),
			Words_10 = string:words_2(SepP_6, String_7, PrevWordEnd_13, V_19),
			V_19 = list:[Word_12 | Words0_9]
		).
string:preceding_boundary(SepP_5, String_6, I_7) = HeadVar__4_4 :-
		(if
			V_8 = 0,
			int:(I_7 < V_8)
		then
			HeadVar__4_4 = I_7
		else
			(if
				V_9 = string:unsafe_index(String_6, I_7),
				call(SepP_5, V_9)
			then
				HeadVar__4_4 = I_7
			else
				HeadVar__4_4 = string:preceding_boundary(SepP_5, String_6, V_10),
				V_10 = int:(I_7 - V_11),
				V_11 = 1
			)
		).
:- pragma termination_info(string:length((builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:length((builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:length((builtin:ui), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:append((builtin:in), (builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:append((builtin:in), (builtin:in), (builtin:in)), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(string:append((builtin:in), (builtin:uo), (builtin:in)), infinite, cannot_loop).
:- pragma termination_info(string:append((builtin:in), (builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:append((builtin:out), (builtin:out), (builtin:in)), infinite, can_loop).
:- pragma termination_info(string:'++'((builtin:in), (builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:remove_suffix((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:prefix((builtin:in), (builtin:in)), finite(0, [no, no]), can_loop).
:- pragma termination_info(string:prefix((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:suffix((builtin:in), (builtin:in)), finite(0, [no, no]), can_loop).
:- pragma termination_info(string:suffix((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:char_to_string((builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:char_to_string((builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:char_to_string((builtin:out), (builtin:in)), infinite, cannot_loop).
:- pragma termination_info(string:int_to_string((builtin:in)) = (builtin:uo), infinite, can_loop).
:- pragma termination_info(string:int_to_string((builtin:in), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(string:int_to_base_string((builtin:in), (builtin:in)) = (builtin:uo), infinite, can_loop).
:- pragma termination_info(string:int_to_base_string((builtin:in), (builtin:in), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(string:float_to_string((builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:float_to_string((builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:first_char((builtin:in), (builtin:in), (builtin:in)), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(string:first_char((builtin:in), (builtin:uo), (builtin:in)), infinite, cannot_loop).
:- pragma termination_info(string:first_char((builtin:in), (builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:first_char((builtin:in), (builtin:uo), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:first_char((builtin:uo), (builtin:in), (builtin:in)), infinite, cannot_loop).
:- pragma termination_info(string:replace((builtin:in), (builtin:in), (builtin:in), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(string:replace_all((builtin:in), (builtin:in), (builtin:in)) = (builtin:uo), infinite, can_loop).
:- pragma termination_info(string:replace_all((builtin:in), (builtin:in), (builtin:in), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(string:to_lower((builtin:in)) = (builtin:uo), infinite, can_loop).
:- pragma termination_info(string:to_lower((builtin:in), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(string:to_lower((builtin:in), (builtin:in)), finite(0, [no, no]), can_loop).
:- pragma termination_info(string:to_upper((builtin:in)) = (builtin:uo), infinite, can_loop).
:- pragma termination_info(string:to_upper((builtin:in), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(string:to_upper((builtin:in), (builtin:in)), finite(0, [no, no]), can_loop).
:- pragma termination_info(string:capitalize_first((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:capitalize_first((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:uncapitalize_first((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:uncapitalize_first((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:to_char_list((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(string:to_char_list((builtin:in), (builtin:out)), infinite, cannot_loop).
:- pragma termination_info(string:to_char_list((builtin:uo), (builtin:in)), infinite, cannot_loop).
:- pragma termination_info(string:from_char_list((builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:from_char_list((builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:from_char_list((builtin:out), (builtin:in)), infinite, cannot_loop).
:- pragma termination_info(string:from_rev_char_list((builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:from_rev_char_list((builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:det_to_int((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:to_int((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:base_string_to_int((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:det_base_string_to_int((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:to_float((builtin:in), (builtin:out)), infinite, cannot_loop).
:- pragma termination_info(string:is_alpha((builtin:in)), infinite, can_loop).
:- pragma termination_info(string:is_alpha_or_underscore((builtin:in)), infinite, can_loop).
:- pragma termination_info(string:is_alnum_or_underscore((builtin:in)), infinite, can_loop).
:- pragma termination_info(string:pad_left((builtin:in), (builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:pad_left((builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:pad_right((builtin:in), (builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:pad_right((builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:duplicate_char((builtin:in), (builtin:in)) = (builtin:uo), infinite, can_loop).
:- pragma termination_info(string:duplicate_char((builtin:in), (builtin:in), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(string:contains_char((builtin:in), (builtin:in)), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(string:index((builtin:in), (builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:index_det((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:index_det((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:unsafe_index((builtin:in), (builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(string:unsafe_index((builtin:in), (builtin:in), (builtin:out)), infinite, cannot_loop).
:- pragma termination_info(string:set_char((builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, cannot_loop).
:- pragma termination_info(string:set_char_det((builtin:in), (builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:set_char_det((builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:unsafe_set_char((builtin:in), (builtin:in), (builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(string:unsafe_set_char((builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, cannot_loop).
:- pragma termination_info(string:foldl((builtin:in), (builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:foldl((pred((builtin:in), (builtin:in), (builtin:out)) is det), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldl((pred((builtin:in), (builtin:di), (builtin:uo)) is det), (builtin:in), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(string:foldl((pred((builtin:in), (builtin:in), (builtin:out)) is semidet), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldl((pred((builtin:in), (builtin:in), (builtin:out)) is nondet), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldl((pred((builtin:in), (builtin:in), (builtin:out)) is multi), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldl_substring((builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:foldl_substring((pred((builtin:in), (builtin:in), (builtin:out)) is det), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldl_substring((pred((builtin:in), (builtin:di), (builtin:uo)) is det), (builtin:in), (builtin:in), (builtin:in), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(string:foldl_substring((pred((builtin:in), (builtin:in), (builtin:out)) is semidet), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldl_substring((pred((builtin:in), (builtin:in), (builtin:out)) is nondet), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldl_substring((pred((builtin:in), (builtin:in), (builtin:out)) is multi), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldr((builtin:in), (builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:foldr((pred((builtin:in), (builtin:in), (builtin:out)) is det), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldr((pred((builtin:in), (builtin:di), (builtin:uo)) is det), (builtin:in), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(string:foldr((pred((builtin:in), (builtin:in), (builtin:out)) is semidet), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldr((pred((builtin:in), (builtin:in), (builtin:out)) is nondet), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldr((pred((builtin:in), (builtin:in), (builtin:out)) is multi), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldr_substring((builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:foldr_substring((pred((builtin:in), (builtin:in), (builtin:out)) is det), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldr_substring((pred((builtin:in), (builtin:di), (builtin:uo)) is det), (builtin:in), (builtin:in), (builtin:in), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(string:foldr_substring((pred((builtin:in), (builtin:in), (builtin:out)) is semidet), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldr_substring((pred((builtin:in), (builtin:in), (builtin:out)) is nondet), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:foldr_substring((pred((builtin:in), (builtin:in), (builtin:out)) is multi), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(string:words((pred((builtin:in)) is semidet), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:words((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:split((builtin:in), (builtin:in), (builtin:uo), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:left((builtin:in), (builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:left((builtin:in), (builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:right((builtin:in), (builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:right((builtin:in), (builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:substring((builtin:in), (builtin:in), (builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:substring((builtin:in), (builtin:in), (builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:unsafe_substring((builtin:in), (builtin:in), (builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:unsafe_substring((builtin:in), (builtin:in), (builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:append_list((builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:append_list((builtin:in), (builtin:uo)), infinite, cannot_loop).
:- pragma termination_info(string:join_list((builtin:in), (builtin:in)) = (builtin:uo), infinite, cannot_loop).
:- pragma termination_info(string:hash((builtin:in)) = (builtin:out), finite(0, [no, no]), can_loop).
:- pragma termination_info(string:hash((builtin:in), (builtin:out)), finite(0, [no, no]), can_loop).
:- pragma termination_info(string:sub_string_search((builtin:in), (builtin:in), (builtin:out)), infinite, cannot_loop).
:- pragma termination_info(string:format((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(string:format((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
