%Assignment 2.2

:- ['2_special_flux'].
:- ['perform1'].


init(Z0) :- Z0 = [request('ftp://photo.de', 'img1.jpg', 510000),
	          request('ftp://photo.de', 'img2.jpg', 480000),
	          request('ftp://photo.de', 'img3.jpg', 410000),
                  request('ftp://photo.de', 'img4.jpg', 370000),
	          request('ftp://photo.de', 'img5.jpg', 150000),
	          request('ftp://photo.de', 'img6.jpg', 80000)].


%Part2
state_update(Z1, ftp(Addr), Z2) :-
    update(Z1, [], [tarfile(Addr, _)], Z2).


%Part3
state_update(Z1, tar(Addr, File), Z2) :-
   holds(request(Addr, File, Size1), Z1),
   (holds(tarfile(Addr, Size2), Z1) -> 
      (Size is Size1 + Size2,
      update(Z1, [tarfile(Addr,Size)], [request(Addr, File, Size1), 
      tarfile(Addr,Size2)], Z2));
   update(Z1, [tarfile(Addr,Size1)], [request(Addr, File, Size1)], Z2)).


%Part4
main :- init(Z), main_loop(Z).

main_loop(Z) :-
   poss(tar(Addr,File), Z)	-> execute(tar(Addr,File), Z, Z1), main_loop(Z1);
   poss(ftp(Addr), Z)  		-> execute(ftp(Addr), Z, Z1),      main_loop(Z1);
   Z=[]                         -> true;
   fail.


poss(tar(Addr, File), Z) :- holds(request(Addr, File, _), Z), \+ unsafe(Addr, File, Z).

poss(ftp(Addr), Z) :- holds(tarfile(Addr, Size), Z), Size =< 1048576.


unsafe(Addr, File, Z) :- holds(tarfile(Addr, Size1), Z),
                         holds(request(Addr, File, Size2), Z),
                         Size is Size1 + Size2,
                         Size > 1048576.


consistent(Z) :- \+ (holds(request(Addr1, File, Size1), Z),
	             holds(request(Addr2, File, Size2), Z),
	             (Size1 \= Size2; Addr1 \= Addr2)),
	         \+ (holds(tarfile(Addr, Size1), Z),
	             holds(tarfile(Addr, Size2), Z),
	             Size1 \= Size2).   
