lj(Agent, Ans) :- lj(Agent, 1, X-X, Ans, deadlock).

lj(1, Store, Queue, Ans, Flag) :- check(Flag, Store, Queue, Ans).

lj(X:T, Store, Hd-1, Ans, _Flag) :- lj(Hd, (X:T,Store), Q-Q, deadlock).

lj((A,B), Store, Hd-(B,Tail), Ans, Flag) :-
   lj(A, Store, Hd-Tail, Ans, nodeadlock).

lj(X^A, Store, Queue, Ans, Flag) :-
   new(X, _NewX, A, A1), 
   lj(A1, Store, Queue, Ans, Flag).

lj((C -> A), Store, Queue, Ans, Flag) :-
   ask(C) -> lj(A, Store, Queue, Ans, nodeadlock) 
            ; check(Flag, Store, Queue, Ans).

lj((X:M '-o' A), Store, Queue, Ans, Flag) :-
   match(X, M, Store, Store1)
    -> lj(A, Store1, Queue, Ans, nodeadlock) 
      ; (Queue = Head - ((X:M '-o' A), Tail), 
         check(Flag, Store, Head-Tail,Ans)). 

lj(! (X:M '-o' A), Store, Head - (! (X:M '-o' A), Tail), Ans, Flag) :-
   match(X, M, Store, Store1)
    -> lj(A, Store1, Head-Tail, Ans, nodeadlock) 
      ; check(Flag, Store, Head-Tail,Ans).


check(nodeadlock, Store, Head-1, Ans) :- !, lj(Head, Store, X-X, Ans, _Flag).
check(deadlock, Store, Head-Store, Head).

ask(C):- call(C).

