:- module bag.
:- use_module assoc_list, builtin, int, list, map, private_builtin, require, std_util.
:- type (bag:bag(T)) == (tree234:tree234(T, int)).
:- pred bag:to_list_2((list:list((std_util:pair(T_1, int)))), (list:list(T_1))).
:- mode bag:to_list_2((builtin:in), (builtin:out)) is det.
:- pred bag:intersect_2((tree234:tree234(T_1, int)), (tree234:tree234(T_1, int)), (tree234:tree234(T_1, int)), (tree234:tree234(T_1, int))).
:- mode bag:intersect_2((builtin:in), (builtin:in), (builtin:in), (builtin:out)) is det.
bag:init(Bag_2) :-
		map:init(Bag_2).
bag:init = B_2 :-
		bag:init(B_2).
bag:insert(B1_4, X_5) = B2_6 :-
		bag:insert(B1_4, X_5, B2_6).
bag:insert_list(B1_4, Xs_5) = B2_6 :-
		bag:insert_list(B1_4, Xs_5, B2_6).
bag:from_list(List_3, Bag_4) :-
		bag:init(Bag0_5),
		bag:insert_list(Bag0_5, List_3, Bag_4).
bag:from_list(Xs_3) = B_4 :-
		bag:from_list(Xs_3, B_4).
bag:to_list(Bag_3, List_4) :-
		map:to_assoc_list(Bag_3, AssocList_5),
		bag:to_list_2(AssocList_5, List_4).
bag:to_list(B_3) = Xs_4 :-
		bag:to_list(B_3, Xs_4).
bag:to_assoc_list(Bag_3, AssocList_4) :-
		map:to_assoc_list(Bag_3, AssocList_4).
bag:to_assoc_list(B_3) = AL_4 :-
		bag:to_assoc_list(B_3, AL_4).
bag:to_list_without_duplicates(Bag_3, List_4) :-
		map:keys(Bag_3, List_4).
bag:to_list_without_duplicates(B_3) = Xs_4 :-
		bag:to_list_without_duplicates(B_3, Xs_4).
bag:det_remove(B1_4, X_5) = B2_6 :-
		bag:det_remove(B1_4, X_5, B2_6).
bag:det_remove_list(B1_4, Xs_5) = B2_6 :-
		bag:det_remove_list(B1_4, Xs_5, B2_6).
bag:delete(Bag0_4, Item_5, Bag_6) :-
		(if
			bag:remove(Bag0_4, Item_5, Bag1_7)
		then
			Bag_6 = Bag1_7
		else
			Bag_6 = Bag0_4
		).
bag:delete(B1_4, X_5) = B2_6 :-
		bag:delete(B1_4, X_5, B2_6).
bag:remove_all(Bag0_4, Item_5, Bag_6) :-
		map:remove(Bag0_4, Item_5, _Val_7, Bag_6).
bag:delete_all(B1_4, X_5) = B2_6 :-
		bag:delete_all(B1_4, X_5, B2_6).
bag:delete_all(Bag0_4, Item_5, Bag_6) :-
		map:delete(Bag0_4, Item_5, Bag_6).
bag:contains(Bag_3, Item_4) :-
		map:contains(Bag_3, Item_4).
bag:count_value(Bag_4, Item_5, Count_6) :-
		(if
			map:search(Bag_4, Item_5, Count0_7)
		then
			Count_6 = Count0_7
		else
			Count_6 = 0
		).
bag:count_value(B_4, X_5) = N_6 :-
		bag:count_value(B_4, X_5, N_6).
bag:subtract(B1_4, B2_5) = B3_6 :-
		bag:subtract(B1_4, B2_5, B3_6).
bag:union(B1_4, B2_5) = B3_6 :-
		bag:union(B1_4, B2_5, B3_6).
bag:intersect(A_4, B_5, Out_6) :-
		bag:init(Out0_7),
		bag:intersect_2(A_4, B_5, Out0_7, Out_6).
bag:intersect(B1_4, B2_5) = B3_6 :-
		bag:intersect(B1_4, B2_5, B3_6).
bag:intersect(A_3, B_4) :-
		map:remove_smallest(A_3, Key_5, _AVal_6, A0_7),
		(if
			map:contains(B_4, Key_5)
		then
			true
		else
			bag:intersect(A0_7, B_4)
		).
bag:least_upper_bound(B1_4, B2_5) = B3_6 :-
		bag:least_upper_bound(B1_4, B2_5, B3_6).
bag:is_subbag(SubBag_3, BigBag_4) :-
		bag:subtract(SubBag_3, BigBag_4, SubBag0_5),
		bag:is_empty(SubBag0_5).
bag:is_empty(Bag_2) :-
		map:is_empty(Bag_2).
:- pragma termination_info(bag:init((builtin:out)), infinite, can_loop).
:- pragma termination_info((bag:init) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:insert((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:insert((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:insert_list((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:insert_list((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:from_list((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:from_list((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:to_list((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:to_list((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:to_assoc_list((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:to_assoc_list((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:to_list_without_duplicates((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:to_list_without_duplicates((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:remove((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:det_remove((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:det_remove((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:remove_list((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:det_remove_list((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:det_remove_list((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:delete((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:delete((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:remove_all((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:delete_all((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:delete_all((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:contains((builtin:in), (builtin:in)), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(bag:count_value((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:count_value((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:subtract((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:subtract((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:union((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:union((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:intersect((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:intersect((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:intersect((builtin:in), (builtin:in)), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(bag:least_upper_bound((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:least_upper_bound((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(bag:is_subbag((builtin:in), (builtin:in)), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(bag:is_empty((builtin:in)), finite(0, [no, no]), can_loop).
:- pragma termination_info(bag:remove_smallest((builtin:in), (builtin:out), (builtin:out)), infinite, can_loop).
:- pragma termination_info(bag:subset_compare((builtin:out), (builtin:in), (builtin:in)), finite(0, [no, no, no, no]), can_loop).
