:- use_module(activation, [check_activation/0, check_activation/1]).
:- use_module(history, [not_in_history/3, add_to_history/3]).
:- use_module(lock, [lock/1, unlock/1]).
:- use_module(priority_queue, [insert/2]).
:- use_module(store,
	      [ make_ground/3,
		new_store/1,
		insert_in_store/4,
		store_lookup/3,
		delete_key/2,
		delete_first/2,
		select_by_id/4
	      ]).
:- use_module(id, [gen_id/1]).
:- use_module(library(lists)).

:- style_check(-singleton).

:- initialization 
	nb_setval('index(leq/2, [])', ht(4, 0, t(_, _, _, _))),
	nb_setval('index(leq/2, [2])', ht(4, 0, t(_, _, _, _))),
	nb_setval('index(leq/2, [1])', ht(4, 0, t(_, _, _, _))),
	nb_setval('index(leq/2, [1, 2])', ht(4, 0, t(_, _, _, _))).

leq(B, C) :-
	gen_id(A),
	E=suspension(A, state(alive), ht(1, 0, t(_)), B, C, _, _, _, _),
	term_variables([B, C], D),
	'attach(leq/2)'(D, E),
	E=suspension(_, F, _, H, I, G, _, _, _),
	(   arg(1, F, alive),
	    var(G)
	->  make_ground(H, user, Q),
	    make_ground(I, user, M),
	    nb_getval('index(leq/2, [])', J),
	    insert_in_store(E, a, J, K),
	    setarg(6, E, key(a)),
	    (   K=[_, L|_]
	    ->  setarg(6, L, K)
	    ;   true
	    ),
	    nb_getval('index(leq/2, [2])', N),
	    insert_in_store(E, a(M), N, O),
	    setarg(7, E, key(a(M))),
	    (   O=[_, P|_]
	    ->  setarg(7, P, O)
	    ;   true
	    ),
	    nb_getval('index(leq/2, [1])', R),
	    insert_in_store(E, a(Q), R, S),
	    setarg(8, E, key(a(Q))),
	    (   S=[_, T|_]
	    ->  setarg(8, T, S)
	    ;   true
	    ),
	    nb_getval('index(leq/2, [1, 2])', U),
	    insert_in_store(E, a(Q, M), U, V),
	    setarg(9, E, key(a(Q, M))),
	    (   V=[_, W|_]
	    ->  setarg(9, W, V)
	    ;   true
	    )
	;   true
	),
	insert(1, 'occurrence(leq/2, 1, 1)'(E)).

user:attr_unify_hook(attr(H, B), A) :-
	(   var(A)
	->  (   get_attr(A, user, attr(F, C))
	    ->  sort(B, D),
		sort(C, E),
		merge_set(D, E, G),
		put_attr(A, user, attr(F, G)),
		'update_index(leq/2)'(B),
		'schedule(leq/2)'(B)
	    ;   put_attr(A, user, attr(H, B)),
		'schedule(leq/2)'(B)
	    )
	;   throw(unsupported)
	).

'schedule(leq/2)'([A|B]) :-
	insert(1, 'occurrence(leq/2, 1, 1)'(A)),
	'schedule(leq/2)'(B).
'schedule(leq/2)'([]).

'update_index(leq/2)'([A|Q1]) :-
	A=suspension(_, _, _, B, C, D, _, _, _),
	make_ground(B, user, J1),
	make_ground(C, user, F1),
	(   nonvar(D)
	->  arg(6, A, E),
	    (   E=key(F)
	    ->  nb_getval('index(leq/2, [])', G),
		store_lookup(F, G, [_|H]),
		(   H=[]
		->  delete_key(F, G)
		;   H=[I|_],
		    setarg(6, I, key(F)),
		    delete_first(F, G)
		)
	    ;   E=[_, _|J],
		setarg(2, E, J),
		(   J=[I|_]
		->  setarg(6, I, E)
		;   true
		)
	    ),
	    arg(7, A, K),
	    (   K=key(L)
	    ->  nb_getval('index(leq/2, [2])', M),
		store_lookup(L, M, [_|N]),
		(   N=[]
		->  delete_key(L, M)
		;   N=[O|_],
		    setarg(7, O, key(L)),
		    delete_first(L, M)
		)
	    ;   K=[_, _|P],
		setarg(2, K, P),
		(   P=[O|_]
		->  setarg(7, O, K)
		;   true
		)
	    ),
	    arg(8, A, Q),
	    (   Q=key(R)
	    ->  nb_getval('index(leq/2, [1])', S),
		store_lookup(R, S, [_|T]),
		(   T=[]
		->  delete_key(R, S)
		;   T=[U|_],
		    setarg(8, U, key(R)),
		    delete_first(R, S)
		)
	    ;   Q=[_, _|V],
		setarg(2, Q, V),
		(   V=[U|_]
		->  setarg(8, U, Q)
		;   true
		)
	    ),
	    arg(9, A, W),
	    (   W=key(X)
	    ->  nb_getval('index(leq/2, [1, 2])', Y),
		store_lookup(X, Y, [_|Z]),
		(   Z=[]
		->  delete_key(X, Y)
		;   Z=[A1|_],
		    setarg(9, A1, key(X)),
		    delete_first(X, Y)
		)
	    ;   W=[_, _|B1],
		setarg(2, W, B1),
		(   B1=[A1|_]
		->  setarg(9, A1, W)
		;   true
		)
	    ),
	    nb_getval('index(leq/2, [])', C1),
	    insert_in_store(A, a, C1, D1),
	    setarg(6, A, key(a)),
	    (   D1=[_, E1|_]
	    ->  setarg(6, E1, D1)
	    ;   true
	    ),
	    nb_getval('index(leq/2, [2])', G1),
	    insert_in_store(A, a(F1), G1, H1),
	    setarg(7, A, key(a(F1))),
	    (   H1=[_, I1|_]
	    ->  setarg(7, I1, H1)
	    ;   true
	    ),
	    nb_getval('index(leq/2, [1])', K1),
	    insert_in_store(A, a(J1), K1, L1),
	    setarg(8, A, key(a(J1))),
	    (   L1=[_, M1|_]
	    ->  setarg(8, M1, L1)
	    ;   true
	    ),
	    nb_getval('index(leq/2, [1, 2])', N1),
	    insert_in_store(A, a(J1, F1), N1, O1),
	    setarg(9, A, key(a(J1, F1))),
	    (   O1=[_, P1|_]
	    ->  setarg(9, P1, O1)
	    ;   true
	    )
	;   true
	),
	'update_index(leq/2)'(Q1).
'update_index(leq/2)'([]).

'occurrence(leq/2, 2, 2)'(A) :-
	A=suspension(G, B, _, C, H, _, _, _, _),
	arg(1, B, alive),
	nb_getval('index(leq/2, [2])', E),
	make_ground(a(C), user, D),
	store_lookup(D, E, F),
	!,
	'occurrence(leq/2, 2, 2, 1)'(F, B, G, A, C, H).
'occurrence(leq/2, 2, 2)'(_).

'occurrence(leq/2, 2, 2, 1)'([A|O], N, D, H, E, M) :-
	(   A=suspension(C, B, K, L, F, _, _, _, _),
	    arg(1, B, alive),
	    C\==D,
	    E==F,
	    G=t(4, C, D),
	    term_hash(G, J),
	    arg(3, H, I),
	    not_in_history(I, J, G),
	    not_in_history(K, J, G)
	->  add_to_history(K, J, G),
	    leq(L, M),
	    check_activation(2),
	    (   arg(1, N, alive)
	    ->  'occurrence(leq/2, 2, 2, 1)'(O, N, D, H, E, M)
	    ;   true
	    )
	;   'occurrence(leq/2, 2, 2, 1)'(O, N, D, H, E, M)
	).
'occurrence(leq/2, 2, 2, 1)'([], _, _, _, _, _).

'occurrence(leq/2, 2, 1)'(A) :-
	A=suspension(G, B, _, H, C, _, _, _, _),
	arg(1, B, alive),
	nb_getval('index(leq/2, [1])', E),
	make_ground(a(C), user, D),
	store_lookup(D, E, F),
	!,
	'occurrence(leq/2, 2, 1, 1)'(F, B, G, A, H, C).
'occurrence(leq/2, 2, 1)'(A) :-
	'occurrence(leq/2, 2, 2)'(A).

'occurrence(leq/2, 2, 1, 1)'([A|O], N, D, H, L, E) :-
	(   A=suspension(C, B, K, F, M, _, _, _, _),
	    arg(1, B, alive),
	    C\==D,
	    E==F,
	    G=t(4, D, C),
	    term_hash(G, J),
	    arg(3, H, I),
	    not_in_history(I, J, G),
	    not_in_history(K, J, G)
	->  add_to_history(K, J, G),
	    leq(L, M),
	    check_activation(2),
	    (   arg(1, N, alive)
	    ->  'occurrence(leq/2, 2, 1, 1)'(O, N, D, H, L, E)
	    ;   true
	    )
	;   'occurrence(leq/2, 2, 1, 1)'(O, N, D, H, L, E)
	).
'occurrence(leq/2, 2, 1, 1)'([], _, _, A, _, _) :-
	'occurrence(leq/2, 2, 2)'(A).

'occurrence(leq/2, 1, 5)'(A) :-
	A=suspension(H, B, _, C, D, _, _, _, _),
	arg(1, B, alive),
	nb_getval('index(leq/2, [1, 2])', F),
	make_ground(a(C, D), user, E),
	store_lookup(E, F, G),
	!,
	'occurrence(leq/2, 1, 5, 1)'(G, B, H, A, C, D).
'occurrence(leq/2, 1, 5)'(A) :-
	insert(2, 'occurrence(leq/2, 2, 1)'(A)).

'occurrence(leq/2, 1, 5, 1)'([A|J1], I1, D, K1, E, G) :-
	(   A=suspension(C, B, _, F, H, _, _, _, _),
	    arg(1, B, alive),
	    C\==D,
	    E==F,
	    G==H
	->  setarg(1, B, dead),
	    (   arg(6, A, I),
		nonvar(I)
	    ->  arg(6, A, J),
		(   J=key(K)
		->  nb_getval('index(leq/2, [])', L),
		    store_lookup(K, L, [_|M]),
		    (   M=[]
		    ->  delete_key(K, L)
		    ;   M=[N|_],
			setarg(6, N, key(K)),
			delete_first(K, L)
		    )
		;   J=[_, _|O],
		    setarg(2, J, O),
		    (   O=[N|_]
		    ->  setarg(6, N, J)
		    ;   true
		    )
		),
		arg(7, A, P),
		(   P=key(Q)
		->  nb_getval('index(leq/2, [2])', R),
		    store_lookup(Q, R, [_|S]),
		    (   S=[]
		    ->  delete_key(Q, R)
		    ;   S=[T|_],
			setarg(7, T, key(Q)),
			delete_first(Q, R)
		    )
		;   P=[_, _|U],
		    setarg(2, P, U),
		    (   U=[T|_]
		    ->  setarg(7, T, P)
		    ;   true
		    )
		),
		arg(8, A, V),
		(   V=key(W)
		->  nb_getval('index(leq/2, [1])', X),
		    store_lookup(W, X, [_|Y]),
		    (   Y=[]
		    ->  delete_key(W, X)
		    ;   Y=[Z|_],
			setarg(8, Z, key(W)),
			delete_first(W, X)
		    )
		;   V=[_, _|A1],
		    setarg(2, V, A1),
		    (   A1=[Z|_]
		    ->  setarg(8, Z, V)
		    ;   true
		    )
		),
		arg(9, A, B1),
		(   B1=key(C1)
		->  nb_getval('index(leq/2, [1, 2])', D1),
		    store_lookup(C1, D1, [_|E1]),
		    (   E1=[]
		    ->  delete_key(C1, D1)
		    ;   E1=[F1|_],
			setarg(9, F1, key(C1)),
			delete_first(C1, D1)
		    )
		;   B1=[_, _|G1],
		    setarg(2, B1, G1),
		    (   G1=[F1|_]
		    ->  setarg(9, F1, B1)
		    ;   true
		    )
		)
	    ;   true
	    ),
	    term_variables([E, G], H1),
	    'detach(leq/2)'(H1, A),
	    check_activation(1),
	    (   arg(1, I1, alive)
	    ->  'occurrence(leq/2, 1, 5, 1)'(J1, I1, D, K1, E, G)
	    ;   true
	    )
	;   'occurrence(leq/2, 1, 5, 1)'(J1, I1, D, K1, E, G)
	).
'occurrence(leq/2, 1, 5, 1)'([], _, _, A, _, _) :-
	insert(2, 'occurrence(leq/2, 2, 1)'(A)).

'occurrence(leq/2, 1, 4)'(A) :-
	A=suspension(H, B, _, C, D, _, _, _, _),
	arg(1, B, alive),
	nb_getval('index(leq/2, [1, 2])', F),
	make_ground(a(C, D), user, E),
	store_lookup(E, F, G),
	!,
	'occurrence(leq/2, 1, 4, 1)'(G, B, H, A, C, D).
'occurrence(leq/2, 1, 4)'(A) :-
	'occurrence(leq/2, 1, 5)'(A).

'occurrence(leq/2, 1, 4, 1)'([A|K1], I, D, J, E, G) :-
	(   A=suspension(C, B, _, F, H, _, _, _, _),
	    arg(1, B, alive),
	    C\==D,
	    E==F,
	    G==H
	->  setarg(1, I, dead),
	    (   arg(6, J, K),
		nonvar(K)
	    ->  arg(6, J, L),
		(   L=key(M)
		->  nb_getval('index(leq/2, [])', N),
		    store_lookup(M, N, [_|O]),
		    (   O=[]
		    ->  delete_key(M, N)
		    ;   O=[P|_],
			setarg(6, P, key(M)),
			delete_first(M, N)
		    )
		;   L=[_, _|Q],
		    setarg(2, L, Q),
		    (   Q=[P|_]
		    ->  setarg(6, P, L)
		    ;   true
		    )
		),
		arg(7, J, R),
		(   R=key(S)
		->  nb_getval('index(leq/2, [2])', T),
		    store_lookup(S, T, [_|U]),
		    (   U=[]
		    ->  delete_key(S, T)
		    ;   U=[V|_],
			setarg(7, V, key(S)),
			delete_first(S, T)
		    )
		;   R=[_, _|W],
		    setarg(2, R, W),
		    (   W=[V|_]
		    ->  setarg(7, V, R)
		    ;   true
		    )
		),
		arg(8, J, X),
		(   X=key(Y)
		->  nb_getval('index(leq/2, [1])', Z),
		    store_lookup(Y, Z, [_|A1]),
		    (   A1=[]
		    ->  delete_key(Y, Z)
		    ;   A1=[B1|_],
			setarg(8, B1, key(Y)),
			delete_first(Y, Z)
		    )
		;   X=[_, _|C1],
		    setarg(2, X, C1),
		    (   C1=[B1|_]
		    ->  setarg(8, B1, X)
		    ;   true
		    )
		),
		arg(9, J, D1),
		(   D1=key(E1)
		->  nb_getval('index(leq/2, [1, 2])', F1),
		    store_lookup(E1, F1, [_|G1]),
		    (   G1=[]
		    ->  delete_key(E1, F1)
		    ;   G1=[H1|_],
			setarg(9, H1, key(E1)),
			delete_first(E1, F1)
		    )
		;   D1=[_, _|I1],
		    setarg(2, D1, I1),
		    (   I1=[H1|_]
		    ->  setarg(9, H1, D1)
		    ;   true
		    )
		)
	    ;   true
	    ),
	    term_variables([E, G], J1),
	    'detach(leq/2)'(J1, J),
	    check_activation(1)
	;   'occurrence(leq/2, 1, 4, 1)'(K1, I, D, J, E, G)
	).
'occurrence(leq/2, 1, 4, 1)'([], _, _, A, _, _) :-
	'occurrence(leq/2, 1, 5)'(A).

'occurrence(leq/2, 1, 3)'(A) :-
	A=suspension(H, B, _, D, C, _, _, _, _),
	arg(1, B, alive),
	nb_getval('index(leq/2, [1, 2])', F),
	make_ground(a(C, D), user, E),
	store_lookup(E, F, G),
	!,
	'occurrence(leq/2, 1, 3, 1)'(G, B, H, A, D, C).
'occurrence(leq/2, 1, 3)'(A) :-
	'occurrence(leq/2, 1, 4)'(A).

'occurrence(leq/2, 1, 3, 1)'([A|K2], I, D, J, G, E) :-
	(   A=suspension(C, B, _, F, H, _, _, _, _),
	    arg(1, B, alive),
	    C\==D,
	    E==F,
	    G==H
	->  setarg(1, I, dead),
	    (   arg(6, J, K),
		nonvar(K)
	    ->  arg(6, J, L),
		(   L=key(M)
		->  nb_getval('index(leq/2, [])', N),
		    store_lookup(M, N, [_|O]),
		    (   O=[]
		    ->  delete_key(M, N)
		    ;   O=[P|_],
			setarg(6, P, key(M)),
			delete_first(M, N)
		    )
		;   L=[_, _|Q],
		    setarg(2, L, Q),
		    (   Q=[P|_]
		    ->  setarg(6, P, L)
		    ;   true
		    )
		),
		arg(7, J, R),
		(   R=key(S)
		->  nb_getval('index(leq/2, [2])', T),
		    store_lookup(S, T, [_|U]),
		    (   U=[]
		    ->  delete_key(S, T)
		    ;   U=[V|_],
			setarg(7, V, key(S)),
			delete_first(S, T)
		    )
		;   R=[_, _|W],
		    setarg(2, R, W),
		    (   W=[V|_]
		    ->  setarg(7, V, R)
		    ;   true
		    )
		),
		arg(8, J, X),
		(   X=key(Y)
		->  nb_getval('index(leq/2, [1])', Z),
		    store_lookup(Y, Z, [_|A1]),
		    (   A1=[]
		    ->  delete_key(Y, Z)
		    ;   A1=[B1|_],
			setarg(8, B1, key(Y)),
			delete_first(Y, Z)
		    )
		;   X=[_, _|C1],
		    setarg(2, X, C1),
		    (   C1=[B1|_]
		    ->  setarg(8, B1, X)
		    ;   true
		    )
		),
		arg(9, J, D1),
		(   D1=key(E1)
		->  nb_getval('index(leq/2, [1, 2])', F1),
		    store_lookup(E1, F1, [_|G1]),
		    (   G1=[]
		    ->  delete_key(E1, F1)
		    ;   G1=[H1|_],
			setarg(9, H1, key(E1)),
			delete_first(E1, F1)
		    )
		;   D1=[_, _|I1],
		    setarg(2, D1, I1),
		    (   I1=[H1|_]
		    ->  setarg(9, H1, D1)
		    ;   true
		    )
		)
	    ;   true
	    ),
	    term_variables([G, E], J1),
	    'detach(leq/2)'(J1, J),
	    setarg(1, B, dead),
	    (   arg(6, A, K1),
		nonvar(K1)
	    ->  arg(6, A, L1),
		(   L1=key(M1)
		->  nb_getval('index(leq/2, [])', N1),
		    store_lookup(M1, N1, [_|O1]),
		    (   O1=[]
		    ->  delete_key(M1, N1)
		    ;   O1=[P1|_],
			setarg(6, P1, key(M1)),
			delete_first(M1, N1)
		    )
		;   L1=[_, _|Q1],
		    setarg(2, L1, Q1),
		    (   Q1=[P1|_]
		    ->  setarg(6, P1, L1)
		    ;   true
		    )
		),
		arg(7, A, R1),
		(   R1=key(S1)
		->  nb_getval('index(leq/2, [2])', T1),
		    store_lookup(S1, T1, [_|U1]),
		    (   U1=[]
		    ->  delete_key(S1, T1)
		    ;   U1=[V1|_],
			setarg(7, V1, key(S1)),
			delete_first(S1, T1)
		    )
		;   R1=[_, _|W1],
		    setarg(2, R1, W1),
		    (   W1=[V1|_]
		    ->  setarg(7, V1, R1)
		    ;   true
		    )
		),
		arg(8, A, X1),
		(   X1=key(Y1)
		->  nb_getval('index(leq/2, [1])', Z1),
		    store_lookup(Y1, Z1, [_|A2]),
		    (   A2=[]
		    ->  delete_key(Y1, Z1)
		    ;   A2=[B2|_],
			setarg(8, B2, key(Y1)),
			delete_first(Y1, Z1)
		    )
		;   X1=[_, _|C2],
		    setarg(2, X1, C2),
		    (   C2=[B2|_]
		    ->  setarg(8, B2, X1)
		    ;   true
		    )
		),
		arg(9, A, D2),
		(   D2=key(E2)
		->  nb_getval('index(leq/2, [1, 2])', F2),
		    store_lookup(E2, F2, [_|G2]),
		    (   G2=[]
		    ->  delete_key(E2, F2)
		    ;   G2=[H2|_],
			setarg(9, H2, key(E2)),
			delete_first(E2, F2)
		    )
		;   D2=[_, _|I2],
		    setarg(2, D2, I2),
		    (   I2=[H2|_]
		    ->  setarg(9, H2, D2)
		    ;   true
		    )
		)
	    ;   true
	    ),
	    term_variables([E, G], J2),
	    'detach(leq/2)'(J2, A),
	    E=G,
	    check_activation(1)
	;   'occurrence(leq/2, 1, 3, 1)'(K2, I, D, J, G, E)
	).
'occurrence(leq/2, 1, 3, 1)'([], _, _, A, _, _) :-
	'occurrence(leq/2, 1, 4)'(A).

'occurrence(leq/2, 1, 2)'(A) :-
	A=suspension(H, B, _, D, C, _, _, _, _),
	arg(1, B, alive),
	nb_getval('index(leq/2, [1, 2])', F),
	make_ground(a(C, D), user, E),
	store_lookup(E, F, G),
	!,
	'occurrence(leq/2, 1, 2, 1)'(G, B, H, A, D, C).
'occurrence(leq/2, 1, 2)'(A) :-
	'occurrence(leq/2, 1, 3)'(A).

'occurrence(leq/2, 1, 2, 1)'([A|K2], I, D, J, G, E) :-
	(   A=suspension(C, B, _, F, H, _, _, _, _),
	    arg(1, B, alive),
	    C\==D,
	    E==F,
	    G==H
	->  setarg(1, I, dead),
	    (   arg(6, J, K),
		nonvar(K)
	    ->  arg(6, J, L),
		(   L=key(M)
		->  nb_getval('index(leq/2, [])', N),
		    store_lookup(M, N, [_|O]),
		    (   O=[]
		    ->  delete_key(M, N)
		    ;   O=[P|_],
			setarg(6, P, key(M)),
			delete_first(M, N)
		    )
		;   L=[_, _|Q],
		    setarg(2, L, Q),
		    (   Q=[P|_]
		    ->  setarg(6, P, L)
		    ;   true
		    )
		),
		arg(7, J, R),
		(   R=key(S)
		->  nb_getval('index(leq/2, [2])', T),
		    store_lookup(S, T, [_|U]),
		    (   U=[]
		    ->  delete_key(S, T)
		    ;   U=[V|_],
			setarg(7, V, key(S)),
			delete_first(S, T)
		    )
		;   R=[_, _|W],
		    setarg(2, R, W),
		    (   W=[V|_]
		    ->  setarg(7, V, R)
		    ;   true
		    )
		),
		arg(8, J, X),
		(   X=key(Y)
		->  nb_getval('index(leq/2, [1])', Z),
		    store_lookup(Y, Z, [_|A1]),
		    (   A1=[]
		    ->  delete_key(Y, Z)
		    ;   A1=[B1|_],
			setarg(8, B1, key(Y)),
			delete_first(Y, Z)
		    )
		;   X=[_, _|C1],
		    setarg(2, X, C1),
		    (   C1=[B1|_]
		    ->  setarg(8, B1, X)
		    ;   true
		    )
		),
		arg(9, J, D1),
		(   D1=key(E1)
		->  nb_getval('index(leq/2, [1, 2])', F1),
		    store_lookup(E1, F1, [_|G1]),
		    (   G1=[]
		    ->  delete_key(E1, F1)
		    ;   G1=[H1|_],
			setarg(9, H1, key(E1)),
			delete_first(E1, F1)
		    )
		;   D1=[_, _|I1],
		    setarg(2, D1, I1),
		    (   I1=[H1|_]
		    ->  setarg(9, H1, D1)
		    ;   true
		    )
		)
	    ;   true
	    ),
	    term_variables([G, E], J1),
	    'detach(leq/2)'(J1, J),
	    setarg(1, B, dead),
	    (   arg(6, A, K1),
		nonvar(K1)
	    ->  arg(6, A, L1),
		(   L1=key(M1)
		->  nb_getval('index(leq/2, [])', N1),
		    store_lookup(M1, N1, [_|O1]),
		    (   O1=[]
		    ->  delete_key(M1, N1)
		    ;   O1=[P1|_],
			setarg(6, P1, key(M1)),
			delete_first(M1, N1)
		    )
		;   L1=[_, _|Q1],
		    setarg(2, L1, Q1),
		    (   Q1=[P1|_]
		    ->  setarg(6, P1, L1)
		    ;   true
		    )
		),
		arg(7, A, R1),
		(   R1=key(S1)
		->  nb_getval('index(leq/2, [2])', T1),
		    store_lookup(S1, T1, [_|U1]),
		    (   U1=[]
		    ->  delete_key(S1, T1)
		    ;   U1=[V1|_],
			setarg(7, V1, key(S1)),
			delete_first(S1, T1)
		    )
		;   R1=[_, _|W1],
		    setarg(2, R1, W1),
		    (   W1=[V1|_]
		    ->  setarg(7, V1, R1)
		    ;   true
		    )
		),
		arg(8, A, X1),
		(   X1=key(Y1)
		->  nb_getval('index(leq/2, [1])', Z1),
		    store_lookup(Y1, Z1, [_|A2]),
		    (   A2=[]
		    ->  delete_key(Y1, Z1)
		    ;   A2=[B2|_],
			setarg(8, B2, key(Y1)),
			delete_first(Y1, Z1)
		    )
		;   X1=[_, _|C2],
		    setarg(2, X1, C2),
		    (   C2=[B2|_]
		    ->  setarg(8, B2, X1)
		    ;   true
		    )
		),
		arg(9, A, D2),
		(   D2=key(E2)
		->  nb_getval('index(leq/2, [1, 2])', F2),
		    store_lookup(E2, F2, [_|G2]),
		    (   G2=[]
		    ->  delete_key(E2, F2)
		    ;   G2=[H2|_],
			setarg(9, H2, key(E2)),
			delete_first(E2, F2)
		    )
		;   D2=[_, _|I2],
		    setarg(2, D2, I2),
		    (   I2=[H2|_]
		    ->  setarg(9, H2, D2)
		    ;   true
		    )
		)
	    ;   true
	    ),
	    term_variables([E, G], J2),
	    'detach(leq/2)'(J2, A),
	    G=E,
	    check_activation(1)
	;   'occurrence(leq/2, 1, 2, 1)'(K2, I, D, J, G, E)
	).
'occurrence(leq/2, 1, 2, 1)'([], _, _, A, _, _) :-
	'occurrence(leq/2, 1, 3)'(A).

'occurrence(leq/2, 1, 1)'(A) :-
	A=suspension(_, B, _, C, D, _, _, _, _),
	arg(1, B, alive),
	C==D,
	!,
	setarg(1, B, dead),
	(   arg(6, A, E),
	    nonvar(E)
	->  arg(6, A, F),
	    (   F=key(G)
	    ->  nb_getval('index(leq/2, [])', H),
		store_lookup(G, H, [_|I]),
		(   I=[]
		->  delete_key(G, H)
		;   I=[J|_],
		    setarg(6, J, key(G)),
		    delete_first(G, H)
		)
	    ;   F=[_, _|K],
		setarg(2, F, K),
		(   K=[J|_]
		->  setarg(6, J, F)
		;   true
		)
	    ),
	    arg(7, A, L),
	    (   L=key(M)
	    ->  nb_getval('index(leq/2, [2])', N),
		store_lookup(M, N, [_|O]),
		(   O=[]
		->  delete_key(M, N)
		;   O=[P|_],
		    setarg(7, P, key(M)),
		    delete_first(M, N)
		)
	    ;   L=[_, _|Q],
		setarg(2, L, Q),
		(   Q=[P|_]
		->  setarg(7, P, L)
		;   true
		)
	    ),
	    arg(8, A, R),
	    (   R=key(S)
	    ->  nb_getval('index(leq/2, [1])', T),
		store_lookup(S, T, [_|U]),
		(   U=[]
		->  delete_key(S, T)
		;   U=[V|_],
		    setarg(8, V, key(S)),
		    delete_first(S, T)
		)
	    ;   R=[_, _|W],
		setarg(2, R, W),
		(   W=[V|_]
		->  setarg(8, V, R)
		;   true
		)
	    ),
	    arg(9, A, X),
	    (   X=key(Y)
	    ->  nb_getval('index(leq/2, [1, 2])', Z),
		store_lookup(Y, Z, [_|A1]),
		(   A1=[]
		->  delete_key(Y, Z)
		;   A1=[B1|_],
		    setarg(9, B1, key(Y)),
		    delete_first(Y, Z)
		)
	    ;   X=[_, _|C1],
		setarg(2, X, C1),
		(   C1=[B1|_]
		->  setarg(9, B1, X)
		;   true
		)
	    )
	;   true
	),
	term_variables([C, C], D1),
	'detach(leq/2)'(D1, A),
	check_activation(1).
'occurrence(leq/2, 1, 1)'(A) :-
	'occurrence(leq/2, 1, 2)'(A).

'attach(leq/2)'([A|F], C) :-
	(   get_attr(A, user, B)
	->  arg(2, B, D),
	    setarg(2, B, [C|D])
	;   gen_id(E),
	    put_attr(A, user, attr(E, [C]))
	),
	'attach(leq/2)'(F, C).
'attach(leq/2)'([], _).

'detach(leq/2)'([A|G], C) :-
	get_attr(A, user, B),
	arg(2, B, D),
	arg(1, C, E),
	select_by_id(D, E, 1, F),
	setarg(2, B, F),
	'detach(leq/2)'(G, C).
'detach(leq/2)'([], _).

show_store :-
	nb_getval('index(leq/2, [])', A),
	(   store_lookup(a, A, B)
	->  forall(member(suspension(_, _, _, C, D, _, _, _, _), B), writeln(leq(C, D)))
	;   true
	).
