:- module exception.
:- use_module builtin, io, list, private_builtin, require, std_util, store, string.
:- type (exception:handler(T)) == pred((std_util:univ), T).
:- type (exception:determinism)
	--->	det
	;	semidet
	;	cc_multi
	;	cc_nondet
	;	multi
	;	nondet
	;	erroneous
	;	failure
	.
:- inst ((exception:handler)) = (pred((builtin:in), (builtin:out)) is det).
:- pragma foreign_import_module("C", exception).
:- pred exception:try((exception:determinism), (pred T_1), (exception:exception_result(T_1))).
:- mode exception:try(builtin:in(bound(det)), (pred((builtin:out)) is det), builtin:out((exception:cannot_fail))) is cc_multi.
:- mode exception:try(builtin:in(bound(semidet)), (pred((builtin:out)) is semidet), (builtin:out)) is cc_multi.
:- mode exception:try(builtin:in(bound(cc_multi)), (pred((builtin:out)) is cc_multi), builtin:out((exception:cannot_fail))) is cc_multi.
:- mode exception:try(builtin:in(bound(cc_nondet)), (pred((builtin:out)) is cc_nondet), (builtin:out)) is cc_multi.
:- pred exception:try_io((exception:determinism), pred(T_1, (io:state), (io:state)), (exception:exception_result(T_1)), (io:state), (io:state)).
:- mode exception:try_io(builtin:in(bound(det)), (pred((builtin:out), (builtin:di), (builtin:uo)) is det), builtin:out((exception:cannot_fail)), (builtin:di), (builtin:uo)) is cc_multi.
:- mode exception:try_io(builtin:in(bound(cc_multi)), (pred((builtin:out), (builtin:di), (builtin:uo)) is cc_multi), builtin:out((exception:cannot_fail)), (builtin:di), (builtin:uo)) is cc_multi.
:- pragma no_inline((exception:try_io)/5).
:- pred exception:try_store((exception:determinism), pred(T_1, (store:store(S_2)), (store:store(S_2))), (exception:exception_result(T_1)), (store:store(S_2)), (store:store(S_2))).
:- mode exception:try_store(builtin:in(bound(det)), (pred((builtin:out), (builtin:di), (builtin:uo)) is det), builtin:out((exception:cannot_fail)), (builtin:di), (builtin:uo)) is cc_multi.
:- mode exception:try_store(builtin:in(bound(cc_multi)), (pred((builtin:out), (builtin:di), (builtin:uo)) is cc_multi), builtin:out((exception:cannot_fail)), (builtin:di), (builtin:uo)) is cc_multi.
:- pred exception:try_all((exception:determinism), (pred T_1), (list:list((exception:exception_result(T_1))))).
:- mode exception:try_all(builtin:in(bound(det)), (pred((builtin:out)) is det), builtin:out((exception:try_all_det))) is cc_multi.
:- mode exception:try_all(builtin:in(bound(semidet)), (pred((builtin:out)) is semidet), builtin:out((exception:try_all_semidet))) is cc_multi.
:- mode exception:try_all(builtin:in(bound(multi)), (pred((builtin:out)) is multi), builtin:out((exception:try_all_multi))) is cc_multi.
:- mode exception:try_all(builtin:in(bound(nondet)), (pred((builtin:out)) is nondet), builtin:out((exception:try_all_nondet))) is cc_multi.
:- pred exception:get_determinism((pred T_1), (exception:determinism)).
:- mode exception:get_determinism((pred((builtin:out)) is det), builtin:out(bound(det))) is cc_multi.
:- mode exception:get_determinism((pred((builtin:out)) is semidet), builtin:out(bound(semidet))) is cc_multi.
:- mode exception:get_determinism((pred((builtin:out)) is multi), builtin:out(bound(multi))) is cc_multi.
:- mode exception:get_determinism((pred((builtin:out)) is nondet), builtin:out(bound(nondet))) is cc_multi.
:- mode exception:get_determinism((pred((builtin:out)) is cc_multi), builtin:out(bound(cc_multi))) is cc_multi.
:- mode exception:get_determinism((pred((builtin:out)) is cc_nondet), builtin:out(bound(cc_nondet))) is cc_multi.
:- pragma promise_pure((exception:get_determinism)/2).
:- pred exception:get_determinism_2(pred(T_1, S_2, S_2), (exception:determinism)).
:- mode exception:get_determinism_2((pred((builtin:out), (builtin:di), (builtin:uo)) is det), builtin:out(bound(det))) is cc_multi.
:- mode exception:get_determinism_2((pred((builtin:out), (builtin:di), (builtin:uo)) is cc_multi), builtin:out(bound(cc_multi))) is cc_multi.
:- pragma promise_pure((exception:get_determinism_2)/2).
:- pred exception:wrap_success((pred T_1), (exception:exception_result(T_1))).
:- mode exception:wrap_success((pred((builtin:out)) is det), (builtin:out)) is det.
:- mode exception:wrap_success((pred((builtin:out)) is semidet), (builtin:out)) is semidet.
:- mode exception:wrap_success((pred((builtin:out)) is multi), (builtin:out)) is multi.
:- mode exception:wrap_success((pred((builtin:out)) is nondet), (builtin:out)) is nondet.
:- mode exception:wrap_success((pred((builtin:out)) is cc_multi), (builtin:out)) is cc_multi.
:- mode exception:wrap_success((pred((builtin:out)) is cc_nondet), (builtin:out)) is cc_nondet.
:- pred exception:wrap_success_or_failure((pred T_1), (exception:exception_result(T_1))).
:- mode exception:wrap_success_or_failure((pred((builtin:out)) is det), (builtin:out)) is det.
:- mode exception:wrap_success_or_failure((pred((builtin:out)) is semidet), (builtin:out)) is det.
:- mode exception:wrap_success_or_failure((pred((builtin:out)) is multi), (builtin:out)) is multi.
:- mode exception:wrap_success_or_failure((pred((builtin:out)) is nondet), (builtin:out)) is multi.
:- mode exception:wrap_success_or_failure((pred((builtin:out)) is cc_multi), (builtin:out)) is cc_multi.
:- mode exception:wrap_success_or_failure((pred((builtin:out)) is cc_nondet), (builtin:out)) is cc_multi.
:- pred exception:handle_store_result((exception:exception_result({T_1, (store:store(S_2))})), (exception:exception_result(T_1)), (store:store(S_2)), (store:store(S_2))).
:- mode exception:handle_store_result(builtin:in((exception:cannot_fail)), builtin:out((exception:cannot_fail)), (builtin:in), (builtin:uo)) is det.
:- pred exception:very_unsafe_perform_io(pred(T_1, (io:state), (io:state)), T_1).
:- mode exception:very_unsafe_perform_io((pred((builtin:out), (builtin:di), (builtin:uo)) is det), (builtin:out)) is det.
:- mode exception:very_unsafe_perform_io((pred((builtin:out), (builtin:di), (builtin:uo)) is cc_multi), (builtin:out)) is cc_multi.
:- pragma promise_pure((exception:very_unsafe_perform_io)/2).
:- pred exception:wrap_exception((std_util:univ), (exception:exception_result(T_1))).
:- mode exception:wrap_exception((builtin:in), (builtin:out)) is det.
:- pred exception:catch_impl((pred T), pred((std_util:univ), T), T).
:- mode exception:catch_impl((pred((builtin:out)) is det), builtin:in((exception:handler)), (builtin:out)) is det.
:- mode exception:catch_impl((pred((builtin:out)) is semidet), builtin:in((exception:handler)), (builtin:out)) is semidet.
:- mode exception:catch_impl((pred((builtin:out)) is cc_multi), builtin:in((exception:handler)), (builtin:out)) is cc_multi.
:- mode exception:catch_impl((pred((builtin:out)) is cc_nondet), builtin:in((exception:handler)), (builtin:out)) is cc_nondet.
:- mode exception:catch_impl((pred((builtin:out)) is multi), builtin:in((exception:handler)), (builtin:out)) is multi.
:- mode exception:catch_impl((pred((builtin:out)) is nondet), builtin:in((exception:handler)), (builtin:out)) is nondet.
:- pragma promise_pure((exception:catch_impl)/3).
:- pred exception:builtin_catch((pred T_1), pred((std_util:univ), T_1), T_1).
:- mode exception:builtin_catch((pred((builtin:out)) is det), builtin:in((exception:handler)), (builtin:out)) is det.
:- mode exception:builtin_catch((pred((builtin:out)) is semidet), builtin:in((exception:handler)), (builtin:out)) is semidet.
:- mode exception:builtin_catch((pred((builtin:out)) is cc_multi), builtin:in((exception:handler)), (builtin:out)) is cc_multi.
:- mode exception:builtin_catch((pred((builtin:out)) is cc_nondet), builtin:in((exception:handler)), (builtin:out)) is cc_nondet.
:- mode exception:builtin_catch((pred((builtin:out)) is multi), builtin:in((exception:handler)), (builtin:out)) is multi.
:- mode exception:builtin_catch((pred((builtin:out)) is nondet), builtin:in((exception:handler)), (builtin:out)) is nondet.
exception:try(Goal_3, Result_4) :-
		exception:get_determinism(Goal_3, Detism_5),
		exception:try(Detism_5, Goal_3, Result_4).
exception:try_io(IO_Goal_5, Result_6, DCG_0_8, DCG_1_9) :-
		exception:get_determinism_2(IO_Goal_5, Detism_7),
		exception:try_io(Detism_7, IO_Goal_5, Result_6, DCG_0_8, DCG_1_9).
exception:try_store(StoreGoal_5, Result_6, DCG_0_8, DCG_1_9) :-
		exception:get_determinism_2(StoreGoal_5, Detism_7),
		exception:try_store(Detism_7, StoreGoal_5, Result_6, DCG_0_8, DCG_1_9).
exception:try_all(Goal_3, ResultList_4) :-
		exception:get_determinism(Goal_3, Detism_5),
		exception:try_all(Detism_5, Goal_3, ResultList_4).
exception:incremental_try_all(Goal_5, AccPred_6, Acc0_7, Acc_8) :-
		V_11 = (pred(V_12::(builtin:out)) is nondet :-
			some [] (
				V_12 = Result_17,
				V_13 = (pred(V_15::(builtin:out)) is nondet :-
					some [] (
						V_15 = R_16,
						exception:wrap_success(Goal_5, R_16)
					)
				),
				V_14 = exception:wrap_exception,
				exception:builtin_catch(V_13, V_14, Result_17)
			)
		),
		std_util:unsorted_aggregate(V_11, AccPred_6, Acc0_7, Acc_8).
exception:try((exception:det), Goal_4, Result_5) :-
		V_8 = (pred(V_10::(builtin:out)) is det :-
			some [] (
				V_10 = R_11,
				exception:wrap_success_or_failure(Goal_4, R_11)
			)
		),
		V_9 = exception:wrap_exception,
		exception:catch_impl(V_8, V_9, Result0_7),
		std_util:cc_multi_equal(Result0_7, Result_5).
exception:try((exception:semidet), Goal_12, Result_13) :-
		V_16 = (pred(V_18::(builtin:out)) is det :-
			some [] (
				V_18 = R_19,
				exception:wrap_success_or_failure(Goal_12, R_19)
			)
		),
		V_17 = exception:wrap_exception,
		exception:catch_impl(V_16, V_17, Result0_15),
		std_util:cc_multi_equal(Result0_15, Result_13).
exception:try((exception:cc_multi), Goal_20, Result_21) :-
		V_23 = (pred(V_25::(builtin:out)) is cc_multi :-
			some [] (
				V_25 = R_26,
				exception:wrap_success_or_failure(Goal_20, R_26)
			)
		),
		V_24 = exception:wrap_exception,
		exception:catch_impl(V_23, V_24, Result_21).
exception:try((exception:cc_nondet), Goal_27, Result_28) :-
		V_30 = (pred(V_32::(builtin:out)) is cc_multi :-
			some [] (
				V_32 = R_33,
				exception:wrap_success_or_failure(Goal_27, R_33)
			)
		),
		V_31 = exception:wrap_exception,
		exception:catch_impl(V_30, V_31, Result_28).
:- pragma no_inline((exception:try_io)/5).
exception:try_io((exception:det), IO_Goal_6, Result_7, DCG_0_10, DCG_0_10) :-
		Goal_8 = (pred(V_11::(builtin:out)) is det :-
			some [] (
				V_11 = R_13,
				exception:very_unsafe_perform_io(IO_Goal_6, R_13)
			)
		),
		V_12 = exception:det,
		exception:try(V_12, Goal_8, Result_7).
exception:try_io((exception:cc_multi), IO_Goal_14, Result_15, DCG_0_18, DCG_0_18) :-
		Goal_16 = (pred(V_19::(builtin:out)) is cc_multi :-
			some [] (
				V_19 = R_21,
				exception:very_unsafe_perform_io(IO_Goal_14, R_21)
			)
		),
		V_20 = exception:cc_multi,
		exception:try(V_20, Goal_16, Result_15).
exception:try_store((exception:det), StoreGoal_6, Result_7, Store0_8, Store_9) :-
		Goal_10 = (pred(V_15::(builtin:out)) is det :-
			some [] (
				V_15 = {R_17, S_18},
				builtin:unsafe_promise_unique(Store0_8, S0_13),
				call(StoreGoal_6, R_17, S0_13, S_18)
			)
		),
		V_16 = exception:det,
		exception:try(V_16, Goal_10, Result0_14),
		exception:handle_store_result(Result0_14, Result_7, Store0_8, Store_9).
exception:try_store((exception:cc_multi), StoreGoal_19, Result_20, Store0_21, Store_22) :-
		Goal_23 = (pred(V_28::(builtin:out)) is cc_multi :-
			some [] (
				V_28 = {R_30, S_31},
				builtin:unsafe_promise_unique(Store0_21, S0_26),
				call(StoreGoal_19, R_30, S0_26, S_31)
			)
		),
		V_29 = exception:cc_multi,
		exception:try(V_29, Goal_23, Result0_27),
		exception:handle_store_result(Result0_27, Result_20, Store0_21, Store_22).
exception:try_all((exception:det), Goal_4, (list:[Result_5 | V_6])) :-
		V_6 = list:[],
		V_7 = exception:det,
		exception:try(V_7, Goal_4, Result_5).
exception:try_all((exception:semidet), Goal_8, ResultList_9) :-
		V_13 = exception:semidet,
		exception:try(V_13, Goal_8, Result_10),
		( % disjunction
			Result_10 = exception:failed,
			ResultList_9 = list:[]
		;
			Result_10 = exception:succeeded(V_11),
			ResultList_9 = list:[Result_10 | V_15],
			V_15 = list:[]
		;
			Result_10 = exception:exception(V_12),
			ResultList_9 = list:[Result_10 | V_14],
			V_14 = list:[]
		).
exception:try_all((exception:multi), Goal_16, ResultList_17) :-
		V_20 = (pred(V_21::(builtin:out)) is multi :-
			some [] (
				V_21 = Result_26,
				V_22 = (pred(V_24::(builtin:out)) is multi :-
					some [] (
						V_24 = R_25,
						exception:wrap_success(Goal_16, R_25)
					)
				),
				V_23 = exception:wrap_exception,
				exception:builtin_catch(V_22, V_23, Result_26)
			)
		),
		std_util:unsorted_solutions(V_20, ResultList_17).
exception:try_all((exception:nondet), Goal_27, ResultList_28) :-
		V_31 = (pred(V_32::(builtin:out)) is nondet :-
			some [] (
				V_32 = Result_37,
				V_33 = (pred(V_35::(builtin:out)) is nondet :-
					some [] (
						V_35 = R_36,
						exception:wrap_success(Goal_27, R_36)
					)
				),
				V_34 = exception:wrap_exception,
				exception:builtin_catch(V_33, V_34, Result_37)
			)
		),
		std_util:unsorted_solutions(V_31, ResultList_28).
:- pragma promise_pure((exception:get_determinism_2)/2).
exception:get_determinism_2((_Pred_3 :: (pred((builtin:out), (builtin:di), (builtin:uo)) is det)), (Det_4 :: (builtin:out(bound(det))))) :-
		( % disjunction
			V_6 = exception:det,
			std_util:cc_multi_equal(V_6, Det_4)
		;
			V_5 = "get_determinism_2",
			require:error(V_5)
		).
exception:get_determinism_2((_Pred_7 :: (pred((builtin:out), (builtin:di), (builtin:uo)) is cc_multi)), (Det_8 :: (builtin:out(bound(cc_multi))))) :-
		( % disjunction
			V_10 = exception:cc_multi,
			std_util:cc_multi_equal(V_10, Det_8)
		;
			V_9 = "get_determinism_2",
			require:error(V_9)
		).
exception:wrap_success(Goal_3, (exception:succeeded(R_4))) :-
		call(Goal_3, R_4).
exception:wrap_success_or_failure(Goal_3, Result_4) :-
		(if
			call(Goal_3, R_5)
		then
			Result_4 = exception:succeeded(R_5)
		else
			Result_4 = exception:failed
		).
exception:wrap_exception(Exception_3, (exception:exception(Exception_3))).
:- pragma promise_pure((exception:catch_impl)/3).
exception:catch_impl((Pred_4 :: ((pred (builtin:out)) is det)), (Handler_5 :: (builtin:in((exception:handler)))), (T_6 :: (builtin:out))) :-
		exception:builtin_catch(Pred_4, Handler_5, T_6).
exception:catch_impl((Pred_7 :: ((pred (builtin:out)) is semidet)), (Handler_8 :: (builtin:in((exception:handler)))), (T_9 :: (builtin:out))) :-
		exception:builtin_catch(Pred_7, Handler_8, T_9).
exception:catch_impl((Pred_10 :: ((pred (builtin:out)) is cc_multi)), (Handler_11 :: (builtin:in((exception:handler)))), (T_12 :: (builtin:out))) :-
		exception:builtin_catch(Pred_10, Handler_11, T_12).
exception:catch_impl((Pred_13 :: ((pred (builtin:out)) is cc_nondet)), (Handler_14 :: (builtin:in((exception:handler)))), (T_15 :: (builtin:out))) :-
		exception:builtin_catch(Pred_13, Handler_14, T_15).
exception:catch_impl((Pred_16 :: ((pred (builtin:out)) is multi)), (Handler_17 :: (builtin:in((exception:handler)))), (T_18 :: (builtin:out))) :-
		exception:builtin_catch(Pred_16, Handler_17, T_18).
exception:catch_impl((Pred_19 :: ((pred (builtin:out)) is nondet)), (Handler_20 :: (builtin:in((exception:handler)))), (T_21 :: (builtin:out))) :-
		exception:builtin_catch(Pred_19, Handler_20, T_21).
:- pragma termination_info(exception:throw((builtin:in)), infinite, can_loop).
:- pragma termination_info(exception:throw((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(exception:try((pred((builtin:out)) is det), builtin:out((exception:cannot_fail))), infinite, can_loop).
:- pragma termination_info(exception:try((pred((builtin:out)) is semidet), (builtin:out)), infinite, can_loop).
:- pragma termination_info(exception:try((pred((builtin:out)) is cc_multi), builtin:out((exception:cannot_fail))), infinite, can_loop).
:- pragma termination_info(exception:try((pred((builtin:out)) is cc_nondet), (builtin:out)), infinite, can_loop).
:- pragma termination_info(exception:try_io((pred((builtin:out), (builtin:di), (builtin:uo)) is det), builtin:out((exception:cannot_fail)), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(exception:try_io((pred((builtin:out), (builtin:di), (builtin:uo)) is cc_multi), builtin:out((exception:cannot_fail)), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(exception:try_store((pred((builtin:out), (builtin:di), (builtin:uo)) is det), builtin:out((exception:cannot_fail)), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(exception:try_store((pred((builtin:out), (builtin:di), (builtin:uo)) is cc_multi), builtin:out((exception:cannot_fail)), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(exception:try_all((pred((builtin:out)) is det), builtin:out((exception:try_all_det))), infinite, can_loop).
:- pragma termination_info(exception:try_all((pred((builtin:out)) is semidet), builtin:out((exception:try_all_semidet))), infinite, can_loop).
:- pragma termination_info(exception:try_all((pred((builtin:out)) is multi), builtin:out((exception:try_all_multi))), infinite, can_loop).
:- pragma termination_info(exception:try_all((pred((builtin:out)) is nondet), builtin:out((exception:try_all_nondet))), infinite, can_loop).
:- pragma termination_info(exception:incremental_try_all((pred((builtin:out)) is nondet), (pred((builtin:in), (builtin:di), (builtin:uo)) is det), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(exception:incremental_try_all((pred((builtin:out)) is nondet), (pred((builtin:in), (builtin:in), (builtin:out)) is det), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(exception:rethrow(builtin:in(bound(exception(ground)))), infinite, can_loop).
:- pragma termination_info(exception:rethrow(builtin:in(bound(exception(ground)))) = (builtin:out), infinite, can_loop).
