:- module int.
:- use_module builtin, enum, exception, math, private_builtin, std_util.
:- instance (enum:enum(int)).
:- pragma foreign_import_module("C", int).
:- pred (int:domain_checks).
:- mode (int:domain_checks) is semidet.
:- pragma inline((int:domain_checks)/0).
int:abs(Num_3) = Abs_4 :-
		int:abs(Num_3, Abs_4).
int:max(X_4, Y_5) = Max_6 :-
		int:max(X_4, Y_5, Max_6).
int:max(X_4, Y_5, Max_6) :-
		(if
			int:(X_4 > Y_5)
		then
			Max_6 = X_4
		else
			Max_6 = Y_5
		).
int:min(X_4, Y_5) = Min_6 :-
		int:min(X_4, Y_5, Min_6).
int:min(X_4, Y_5, Min_6) :-
		(if
			int:(X_4 < Y_5)
		then
			Min_6 = X_4
		else
			Min_6 = Y_5
		).
:- pragma foreign_proc("C", int:to_float(IntVal :: (builtin:in), FloatVal :: (builtin:out)), [will_not_call_mercury, not_thread_safe, not_tabled_for_io, promise_pure], "
	FloatVal = IntVal;
").
int:pow(Base_4, Exp_5) = Result_6 :-
		int:pow(Base_4, Exp_5, Result_6).
int:log2(X_3) = N_4 :-
		int:log2(X_3, N_4).
int:plus(X_4, Y_5) = HeadVar__3_3 :-
		HeadVar__3_3 = int:(X_4 + Y_5).
int:times(X_4, Y_5) = HeadVar__3_3 :-
		HeadVar__3_3 = int:(X_4 * Y_5).
int:minus(X_4, Y_5) = HeadVar__3_3 :-
		HeadVar__3_3 = int:(X_4 - Y_5).
:- pragma inline((int:(//))/2).
int:(X_4 // Y_5) = Div_6 :-
		(if
			int:domain_checks,
			Y_5 = 0
		then
			V_7 = math:domain_error(V_8),
			V_8 = "int:\'//\'",
			exception:throw(V_7)
		else
			Div_6 = int:unchecked_quotient(X_4, Y_5)
		).
:- pragma inline((int:(/))/2).
int:(X_4 / Y_5) = HeadVar__3_3 :-
		HeadVar__3_3 = int:(X_4 // Y_5).
int:(X_4 mod Y_5) = HeadVar__3_3 :-
		HeadVar__3_3 = int:(X_4 - V_6),
		V_6 = int:(V_7 * Y_5),
		V_7 = int:(X_4 div Y_5).
:- pragma inline((int:(rem))/2).
int:(X_4 rem Y_5) = Rem_6 :-
		(if
			int:domain_checks,
			Y_5 = 0
		then
			V_7 = math:domain_error(V_8),
			V_8 = "int:rem",
			exception:throw(V_7)
		else
			Rem_6 = int:unchecked_rem(X_4, Y_5)
		).
:- pragma inline((int:even)/1).
int:even(X_2) :-
		V_3 = int:(X_2 /\ V_4),
		V_4 = 1,
		V_3 = 0.
:- pragma inline((int:odd)/1).
int:odd(X_2) :-
		\+ (
			V_3 = int:(X_2 /\ V_4),
			V_4 = 1,
			V_3 = 0
		).
int:(X_3 is X_3).
int:max_int = X_2 :-
		int:max_int(X_2).
:- pragma foreign_proc("C", int:max_int(Max :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	if (sizeof(MR_Integer) == sizeof(int))
		Max = INT_MAX;
	else if (sizeof(MR_Integer) == sizeof(long))
		Max = LONG_MAX;
	else
		MR_fatal_error(\"Unable to figure out max integer size\");
").
int:min_int = X_2 :-
		int:min_int(X_2).
:- pragma foreign_proc("C", int:min_int(Min :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	if (sizeof(MR_Integer) == sizeof(int))
		Min = INT_MIN;
	else if (sizeof(MR_Integer) == sizeof(long))
		Min = LONG_MIN;
	else
		MR_fatal_error(\"Unable to figure out min integer size\");
").
int:bits_per_int = X_2 :-
		int:bits_per_int(X_2).
:- pragma foreign_proc("C", int:bits_per_int(Bits :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	Bits = ML_BITS_PER_INT;
").
:- pragma inline((int:floor_to_multiple_of_bits_per_int)/1).
int:floor_to_multiple_of_bits_per_int(X_3) = Floor_4 :-
		Trunc_5 = int:quot_bits_per_int(X_3),
		Floor0_6 = int:times_bits_per_int(Trunc_5),
		(if
			int:(Floor0_6 > X_3)
		then
			Floor_4 = int:(Floor0_6 - V_7),
			V_7 = int:bits_per_int
		else
			Floor_4 = Floor0_6
		).
:- pragma foreign_proc("C", int:quot_bits_per_int(Int :: (builtin:in)) = (Div :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	Div = Int / ML_BITS_PER_INT;
").
:- pragma foreign_proc("C", int:times_bits_per_int(Int :: (builtin:in)) = (Result :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	Result = Int * ML_BITS_PER_INT;
").
:- pragma foreign_proc("C", int:rem_bits_per_int(Int :: (builtin:in)) = (Rem :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	Rem = Int % ML_BITS_PER_INT;
").
:- pragma inline((int:domain_checks)/0).
:- pragma foreign_proc("C", int:domain_checks, [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
#ifdef ML_OMIT_MATH_DOMAIN_CHECKS
	SUCCESS_INDICATOR = MR_FALSE;
#else
	SUCCESS_INDICATOR = MR_TRUE;
#endif
").
:- promise all [A, B, C] (
	\+ (
		C = int:(B + A),
		\+ (
			C = int:(A + B)
		)
	),
	\+ (
		C = int:(A + B),
		\+ (
			C = int:(B + A)
		)
	)).
:- promise all [A, B, C, ABC] (
	\+ (
		ABC = int:(V_5 + C),
		V_5 = int:(A + B),
		\+ (
			ABC = int:(A + V_6),
			V_6 = int:(B + C)
		)
	),
	\+ (
		ABC = int:(A + V_8),
		V_8 = int:(B + C),
		\+ (
			ABC = int:(V_7 + C),
			V_7 = int:(A + B)
		)
	)).
:- promise all [A, B, C] (
	\+ (
		C = int:(B * A),
		\+ (
			C = int:(A * B)
		)
	),
	\+ (
		C = int:(A * B),
		\+ (
			C = int:(B * A)
		)
	)).
:- promise all [A, B, C, ABC] (
	\+ (
		ABC = int:(V_5 * C),
		V_5 = int:(A * B),
		\+ (
			ABC = int:(A * V_6),
			V_6 = int:(B * C)
		)
	),
	\+ (
		ABC = int:(A * V_8),
		V_8 = int:(B * C),
		\+ (
			ABC = int:(V_7 * C),
			V_7 = int:(A * B)
		)
	)).
:- pragma termination_info(int:'<'((builtin:in), (builtin:in)), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(int:'>'((builtin:in), (builtin:in)), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(int:'=<'((builtin:in), (builtin:in)), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(int:'>='((builtin:in), (builtin:in)), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(int:abs((builtin:in)) = (builtin:out), finite(0, [yes, no]), cannot_loop).
:- pragma termination_info(int:abs((builtin:in), (builtin:out)), finite(0, [yes, no]), cannot_loop).
:- pragma termination_info(int:max((builtin:in), (builtin:in)) = (builtin:out), finite(0, [yes, yes, no]), cannot_loop).
:- pragma termination_info(int:max((builtin:in), (builtin:in), (builtin:out)), finite(0, [yes, yes, no]), cannot_loop).
:- pragma termination_info(int:min((builtin:in), (builtin:in)) = (builtin:out), finite(0, [yes, yes, no]), cannot_loop).
:- pragma termination_info(int:min((builtin:in), (builtin:in), (builtin:out)), finite(0, [yes, yes, no]), cannot_loop).
:- pragma termination_info(int:to_float((builtin:in), (builtin:out)), infinite, cannot_loop).
:- pragma termination_info(int:pow((builtin:in), (builtin:in)) = (builtin:out), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(int:pow((builtin:in), (builtin:in), (builtin:out)), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(int:log2((builtin:in)) = (builtin:out), finite(0, [no, no]), can_loop).
:- pragma termination_info(int:log2((builtin:in), (builtin:out)), finite(0, [no, no]), can_loop).
:- pragma termination_info(int:'+'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:'+'((builtin:uo), (builtin:in)) = (builtin:in), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:'+'((builtin:in), (builtin:uo)) = (builtin:in), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:plus((builtin:in), (builtin:in)) = (builtin:out), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:'*'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:times((builtin:in), (builtin:in)) = (builtin:out), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:'-'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:'-'((builtin:uo), (builtin:in)) = (builtin:in), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:'-'((builtin:in), (builtin:uo)) = (builtin:in), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:minus((builtin:in), (builtin:in)) = (builtin:out), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:div((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(int:'//'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(int:'/'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(int:unchecked_quotient((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:mod((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(int:rem((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(int:unchecked_rem((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:'<<'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:unchecked_left_shift((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:'>>'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:unchecked_right_shift((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:even((builtin:in)), finite(0, [no]), cannot_loop).
:- pragma termination_info(int:odd((builtin:in)), finite(0, [no]), cannot_loop).
:- pragma termination_info(int:'/\\'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:'\\/'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:xor((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:xor((builtin:in), (builtin:uo)) = (builtin:in), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:xor((builtin:uo), (builtin:in)) = (builtin:in), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(int:'\\'((builtin:in)) = (builtin:uo), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(int:'+'((builtin:in)) = (builtin:uo), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(int:'-'((builtin:in)) = (builtin:uo), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(int:is((builtin:uo), (builtin:di)), finite(0, [no, no, yes]), cannot_loop).
:- pragma termination_info(int:is((builtin:out), (builtin:in)), finite(0, [no, no, yes]), cannot_loop).
:- pragma termination_info((int:max_int) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(int:max_int((builtin:out)), infinite, cannot_loop).
:- pragma termination_info((int:min_int) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(int:min_int((builtin:out)), infinite, cannot_loop).
:- pragma termination_info((int:bits_per_int) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(int:bits_per_int((builtin:out)), infinite, cannot_loop).
:- pragma termination_info(int:floor_to_multiple_of_bits_per_int((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(int:quot_bits_per_int((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(int:times_bits_per_int((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(int:rem_bits_per_int((builtin:in)) = (builtin:out), infinite, cannot_loop).
