:- module group.
:- use_module assoc_list, builtin, int, list, map, private_builtin, require, set, std_util.
:- type (group:key) == int.
:- type (group:group(T))
	--->	group(int, (tree234:tree234(int, (set:set(T)))), (tree234:tree234(T, int)))
	.
:- pred group:get_sets((group:group(T_1)), (tree234:tree234(int, (set:set(T_1))))).
:- mode group:get_sets((builtin:in), (builtin:out)) is det.
:- pred group:get_elements((group:group(T_1)), (tree234:tree234(T_1, int))).
:- mode group:get_elements((builtin:in), (builtin:out)) is det.
group:init(G_2) :-
		map:init(Es_3),
		map:init(Ss_4),
		G_2 = group:group(V_5, Es_3, Ss_4),
		V_5 = 0.
group:init = G_2 :-
		group:init(G_2).
group:insert(G1_4, S_5) = G2_6 :-
		group:insert(G1_4, S_5, G2_6).
group:group(G_4, E_5, S_6) :-
		group:get_elements(G_4, Es_7),
		map:lookup(Es_7, E_5, GK_8),
		group:get_sets(G_4, Ss_9),
		map:lookup(Ss_9, GK_8, S_6).
group:group(G_4, T_5) = S_6 :-
		group:group(G_4, T_5, S_6).
group:to_set(G_3, S_4) :-
		group:get_sets(G_3, SS_5),
		map:values(SS_5, S0_6),
		set:list_to_set(S0_6, S_4).
group:to_set(G_3) = SS_4 :-
		group:to_set(G_3, SS_4).
group:sets_and_keys(G_3, SKs_4) :-
		group:get_sets(G_3, SS_5),
		map:to_assoc_list(SS_5, SKs0_6),
		assoc_list:reverse_members(SKs0_6, SKs_4).
group:sets_and_keys(G_3) = AL_4 :-
		group:sets_and_keys(G_3, AL_4).
group:group_key(G_4, E_5, GK_6) :-
		group:get_elements(G_4, Es_7),
		map:lookup(Es_7, E_5, GK_6).
group:group_key(G_4, T_5) = K_6 :-
		group:group_key(G_4, T_5, K_6).
group:key_group(G_4, GK_5, S_6) :-
		group:get_sets(G_4, Ss_7),
		map:lookup(Ss_7, GK_5, S_6).
group:key_group(G_4, K_5) = S_6 :-
		group:key_group(G_4, K_5, S_6).
group:same_group(G_4, E0_5, E1_6) :-
		group:get_elements(G_4, Es_7),
		map:lookup(Es_7, E0_5, GK_8),
		map:lookup(Es_7, E1_6, GK_8).
group:largest_group_key(G_3) = K_4 :-
		group:largest_group_key(G_3, K_4).
group:group_keys(G_3, Ks_4) :-
		group:get_sets(G_3, Ss_5),
		map:keys(Ss_5, Ks_4).
group:group_keys(G_3) = Ks_4 :-
		group:group_keys(G_3, Ks_4).
group:get_sets(G_3, S_4) :-
		G_3 = group:group(V_5, S_4, V_6).
group:get_elements(G_3, E_4) :-
		G_3 = group:group(V_5, V_6, E_4).
:- pragma termination_info(group:init((builtin:out)), infinite, can_loop).
:- pragma termination_info((group:init) = (builtin:out), infinite, can_loop).
:- pragma termination_info(group:insert((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(group:insert((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(group:group((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(group:group((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(group:to_set((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(group:to_set((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(group:sets_and_keys((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(group:sets_and_keys((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(group:group_key((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(group:group_key((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(group:key_group((builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(group:key_group((builtin:in), (builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(group:remove_group((builtin:in), (builtin:in), (builtin:out), (builtin:out)), infinite, can_loop).
:- pragma termination_info(group:same_group((builtin:in), (builtin:in), (builtin:in)), finite(0, [no, no, no, no]), can_loop).
:- pragma termination_info(group:largest_group_key((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(group:largest_group_key((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(group:group_keys((builtin:in), (builtin:out)), infinite, can_loop).
:- pragma termination_info(group:group_keys((builtin:in)) = (builtin:out), infinite, can_loop).
