:- ['5_flux'].
:- chr('owncnstr').

q :- init(Z1), writeln(Z1),
     poss(call(N),Z1), state_update(Z1,call(N),Z2,[e2]), writeln(Z2),
     poss(enter(E), Z2), state_update(Z2,enter(E),Z3,[]), writeln(Z3).


init(Z) :- Z = [at(e1,1),at(e2,1),at(robot,2)|_], consistent(Z).


consistent(Z) :- domcons(Z), duplicate_free(Z).


poss(call(N),Z)  :- knows_val([M],at(robot,M),Z), N=M,
                    knows_not(at(e1,N),Z),
                    knows_not(at(e2,N),Z).

poss(enter(E),Z) :- knows_val([N],at(robot,N),Z),
                    knows_val([M],at(E,M),Z), N=M, E::[e1,e2].


state_update(Z1,call(N),Z2,[E]) :-
   knows_val([PosE],at(E,PosE),Z1),
   update(Z1,[at(E,N)],[at(E,PosE)],Z2).

state_update(Z1,enter(E),Z2,[]) :-
   knows_val([PosR],at(robot,PosR),Z1),
   knows_val([E],at(E,PosR),Z1),
   update(Z1,[in(E)],[at(robot,PosR)],Z2).


%%%% extra file owncnstr.chr %%%%%%%%%%%%%%

constraints domcons/1.

domcons([F|Z]) <=> (F=at(X,N1) -> N1::[1..10], X::[robot,e1,e2],
                                  not_holds_all(at(X,_),Z);
                    F=in(E)    -> E::[e1,e2], not_holds_all(in(_),Z)),
                   domcons(Z).
