%--------------------------- PRAKTIKUM 3 ------------------------------
% EESMÄRK: Rekursiooni ja listi kasutamine sügavuti otsingul
%
% Ülesanne1: Koostada rekursiivne otsingureegel odavaima lennumarsruudi leidmiseks 2 punkti vahel
%		Lennuühendused moodustavad suunatud graafi, mille kaartel on kaalud
% 		Graaf on esitatud faktidega lend/3
% 		Faktimall: lend(Place_Departure, Place_Arrival,Cost).
% Ülesanne 2: Täiendada fakte lend ja otsingureeglit nii, et leitakse ajaliselt lühim marsruut
%	Soovitus 1: kasutada fakti malle lend/5, kus 
% 		lend( Place_Departure, Place_Arrival, Departure_time, Arrival_time, Duration).
%	Soovitus 2: Võtta arvesse lisakitsendus: Lendu saab jätkata transiitpunktist ainult niisuguse lennuga, 
%		mis väljub mitte varem kui 1 tund peale sellesse punkti saabumist.
% ------------------------------------------------------------------------------------

% ---------------------------------- FAKTID ---------------------------------------
lend('Moskva','Tallinn', 3000).
lend('Petseri','Tallinn', 150).
lend('Tallinn', 'Riia', 1000).
lend('Riia','Wroclaw', 2000).

% -- ------------------------------ REEGLID ----------------------------------------
% Sügavuti otsing suunatud graafil rekursiivse reegliga otsi/4
% Otsingu sügavus on piiratud parameetriga "marsruudi_hind"
%----------------------------------------------------------------------------
:- dynamic marsruudi_hind/1.

%--------------------------Peaprotseduur------------------------------------
% TESTPÄRING1:  leia_teekond('Moskva','Riia'). 
% TESTPÄRING2:  leia_teekond('Moskva','Wroclaw'). 
%----------------------------------------------------------------------------
leia_teekond(A,B):-  
    	write(A),	assert(marsruudi_hind(999999999)),
    	otsi(A,B,[],0), 			% rekursiooni poole p””rdumine 
   	 fail.
leia_teekond(_,_):-
    	marsruudi_hind(H_parim), 
    	nl,write(' Parima marsruudi hind = '), write(H_parim), 
   	 retract(marsruudi_hind(_)).
%---------------------------Otsingureegel-----------------------------------
otsi(X,B,List,Hind):-       			% rekursiooni peatumistingimus
    lend(X,B,H), 
    H1 is Hind + H,
    marsruudi_hind(H_parim),
    H1 < H_parim,
    retract(marsruudi_hind(_)), assert(marsruudi_hind(H1)),
    reverse(List,R1),    write(R1),     write(B), write('           Hind =  '), write(H1),nl.
otsi(Y,B,List,Hind):-       			% rekursiooni samm
    lend(Y,C,H),
    not(member(C,List)),
    Hind1 is Hind + H,
    otsi(C,B,[C|List],Hind1).
%------------------------------------------------------------------------------
