/*

Peter Thim
dat00pet
peter.thim@swipnet.se
*/


:- ensure_loaded(library('system')).
:- ensure_loaded(library('listing')).
:- set_prolog_flag(unknown,fail).

/*
	mitt program kräver att man har en fil som heter 
	på PC pl.ini eller på unix .plcr med följande 3 rader i,

		:- ensure_loaded(library('system')).
		:- ensure_loaded(library('listing')).


 	och i prolog filen 
	    :- set_prolog_flag(unknown,fail).


detta för att jag inte har provat utan därför så har jag hittat på en alternativ lösning
det är att includera dom raderna i db filen det gör att man automatiskt laddar dom.

*/



/* 
  Predikatet vid('Plats') anger start position 
	predikatet har 3 fall ,
	    1) när där redan finns en startnod,tar den bort den gamla och sätter in en ny.
	    2) när där inte finns en startnod,lägger den bara till den nya starpunkten.
	    3) när starnoden inte finns i grafen, skriver den ut det och gör inget mer.

*/



vid(Plats):-
	vari(_),
	plats(_,Plats,_,_),
	retract(vari(_)),
	assertz(vari(Plats)).

vid(Plats):-
	\+(plats(_,Plats,_,_)),
	write('Noden finns inte i grafen, har du stavat rätt ?'),nl.

vid(Plats):-
	\+(vari(_)),
	plats(_,Plats,_,_),
	assertz(vari(Plats)).


/*
Predikat för var. funktionen 

Predikatet kontrolerar om där finns någon start nod om så skriver ut den,
om den inte finns så skriver den ut att ingen start nod är angiven.
*/


var :- \+(vari(_)),write('Ingen start nod angiven'),nl.
var :- vari(Plats),write('Du befinner dig vid  '),write(Plats),nl.


/* 
	Prediatat till(Plats).  har 5 olika funktioner
	1) Du har inte någon start punkt angiven före.
	2) Du har samma start som mål punk.
	3) målpunkten finns inte i grafen
	4) Om grafen har några återvändsgränder så stannar sökningen.
	5) Söker i grafen--tills den finner en lösning.
*/


till(_):-
	\+vari(_),nl,
	write('Tyvärr så kan man inte söka generellt man måste ange en startnod'),nl.

till(Start):-
	vari(Start),
	write('Man kan inte resa till den punkt man är på, har du tänkt helt rätt nu? ').

till(Start):-
	vari(_),
	\+(plats(_,Start,_,_)),
	write('Noden finns inte i grafen, har du stavat rätt? '),nl.

till(Slut):-
	vari(_),
	återvänd(Slut),
	write('Det går inte att komma till en återvändsgränd').

till(Slut):-
	vari(_),
	\+(återvänd(Slut)),
	repeat,
	granne(Slut).

	
/* 
	Predikatet granne(Mål)
	har 2 funktioner
	1) om där finns en väg från Start till Mål ,Skrivut den.
	2) annars ta Startplatsen  och en plats X och se om där finns en billed mellan dom,
		om där finns det så lägg till den nya vägen i listan, och sök djupare.
*/



granne(Mål):-
	vari(Start),
	väg(Start,Mål,Väg,L),
	skrivut(Väg,L).

granne(Mål):-
	vari(Start),
	plats(N1,Start,_,_),
	plats(N2,Y,_,_),
	billed(N1,N2,_,M,Lista),
	assertz(väg(Start,Y,[Start,Lista,Y],M)),
	vägar(Mål,vari).


/* 
	Predikatet vägar söker på följande sätt 
	Funktionen använder sök funktionen för att skapa en ny väg mellan punkten Start
	  & den väg som funktionen sök returnerar.
	detta läggs till i väg databasen och sedan så kontrolerar den om där går en väg mellan start & slut
	om inte så backtrackar den och lägger till mer data tills det stämmer.
*/


vägar(Slut,vari):-
	vari(Start),
	väg(Start,Y,Väg1,M1),
	sök(Y,Z,[Y|Väg2],M2),
	M is M1+M2,
	\+(väg(Start,Z,_,_)),
	\+(member(Start,Väg2)),
	assertz(väg(Start,Z,[Väg1|Väg2],M)),
	väg(Start,Slut,Väg,L),
	skrivut(Väg,L).


/*
	Predikatet sök(Start,Slut,Lista,Meter)

	Predikatet söker 1 djup bort och ser där går vägar mellan dom.
	i så fall så så returnerar dom den detta predikat skapar även en
	lista med följande denotation
	[Starpunkt,Väg,Slut] vilket används senare.
*/


sök(Start,Slut,[Start,Väg,Slut],M):-
	plats(X,Start,_,_),
	plats(Y,Slut,_,_),
	billed(X,Y,_,M,Väg).

sök(Start,Slut,[Start,Väg,Slut],M):-
	plats(X,Start,_,_),
	plats(Y,Slut,_,_),
	billed(Y,X,dubbel,M,Väg).


/* 
 Predikatet återvänd(Slut) som är en kortform av ordet återvändsgränd

 Predikatet lyckas när man inte kan komma till punkten Slut.
 Annars så misslyckas det.
*/


återvänd(Slut):-
	plats(N,Slut,_,_),
	not(billed(M,N,_,_,_)),
	not(billed(N,M,dubbel,_,_)).


/* 
	Predikatet skrivut(Lista,Längd)
	predikatet har 4 funktioner.
	1) när du nått slutet gör radmatning och omvandla 10tal meter till meter och skriv ut 
		resanslängd
	2) I listan om noden är en plats och är startnoden så ska den skriva anorlunda , 
		(här omvandlar den listan också till en enkel lista)
	3) Om Listans object är en plats men inte startnoden så ska den skriva passerar följt av objectet
	4) Om Listans object inte är en plats, då är det en väg och då skriver den 'kör längs med'
		följt av objectet.

*/



skrivut([Slut],M):-
	nl,
	write('Du är nu vid '),
	write(Slut),nl,
	Meter is M*10,
	write(Meter),
	write(' meter'),
	vid(Slut).


skrivut(Väg,M):-
	flatten(Väg,Way),
	Way=[Huvud|Svans],
	plats(_,Huvud,_,_),
	vari(X),
	(Huvud==X),
	write('Resan påbörjas från  '),
	write(Huvud),nl,
	skrivut(Svans,M).	



skrivut(Väg,M):-
	Väg=[Huvud|Svans],
	plats(_,Huvud,_,_),
	vari(X),
	(Huvud\==X),nl,
	write('   passerar '),
	write(Huvud),nl,
	skrivut(Svans,M).	

skrivut(Väg,M):-
	Väg=[Huvud|Svans],
	\+(plats(_,Huvud,_,_)),
	write(' kör längs med '),
	write(Huvud),
	skrivut(Svans,M).	




%  plats(nummer, namm,            xkoord, ykoord). 
%                                 i 10-tal meter.

   plats( 1, 'Domkyrkan',            198, 306).
   plats( 2, 'Stortorget',           199, 290). 
   plats( 3, 'Mårtenstorget',        221, 278).
   plats( 4, 'Clemenstorget',        172, 341).
   plats( 5, 'AF',                   214, 320).
   plats( 6, 'Universitetet',        198, 326). 
   plats( 7, 'Kulturen',             218, 312).
   plats( 8, 'Stationen',            166, 320).
   plats( 9, 'Stadshallen',          209, 289).
   plats(10, 'Biskopshuset',         222, 342). 
   plats(11, 'Tomegap',              246, 322).
   plats(12, 'Spyken',               247, 275).
   plats(13, 'Tornav/Dalbyv',        313, 254).
   plats(14, 'Bantorget',            168, 304).
   plats(15, 'Kung Oscars bro',      167, 389).
   plats(16, 'Allhelgonakyrkan',     200, 362).
   plats(17, 'Tunaparken',           298, 340).
   plats(18, 'Lasarettet',           216, 400). 
   plats(19, 'Brandstationen',       188, 389).
   plats(20, 'Tornav/Getingev',      262, 434).
   plats(21, 'Svenshögsv/Norra Ringen',  259, 484).
   plats(22, 'Sparta',               343, 364).
   plats(23, 'Sankt Lars',           140, 124).
   plats(24, 'Markaskälsvägen 28',   331, 538). 
   plats(25, 'Sankt Petri',          159, 301).
   plats(26, 'Södertull',            177, 219).
   plats(27, 'La Strada',            394, 478).
   plats(28, 'Dalbykarusellen',      353, 243). 
   plats(29, 'Linero',               504, 192).
   plats(30, 'Högevall',             155, 276).  
   plats(31, 'Delphi',               329, 476).
   plats(32, 'Monumentet',           152, 490).
   plats(33, 'Nöbbelöv',              91, 576).
   plats(34, 'Klostergården',        165, 160). 
   plats(35, 'Knästorpskarusellen',  128,  17).
   plats(36, 'Alfa Laval',           120, 386).  
   plats(37, 'Polhemsskolan',        100, 291).
   plats(38, 'Östra Torn',           433, 415).


%  billed(start,slut,riktning,distans,gator).
%                             i 10-tal meter.

   billed( 1,  6, dubbel,  20, ['Kyrkogatan']).
   billed( 1, 14,  enkel,  36, ['Klostergatan']).
   billed( 2,  1,  enkel,  17, ['Kyrkogatan']).
   billed( 3,  7, dubbel,  48, ['Svartbrödrag.', 'Skomakareg.', 
                                'Kiliansg.', 'Krafts Torg']).
   billed( 3,  9, dubbel,  17, ['Svartbrödrag.', 'Skomakareg.']).
   billed( 3, 12, dubbel,  32, ['Östra Mårtensgatan']).
   billed( 3, 26,  enkel,  90, ['Bankgatan', 'Södra Esplanaden']).
   billed( 4,  6, dubbel,  34, ['Sankt Petri Kyrkogata']).
   billed( 4,  8, dubbel,  22, ['Bangatan']).
   billed( 4, 15, dubbel,  49, ['Spolegatan']).
   billed( 4, 16, dubbel,  35, ['Sankt Laurentiigatan']).
   billed( 5, 10, dubbel,  24, ['Sandgatan']).
   billed( 6, 16, dubbel,  37, ['Bredgatan']).
   billed( 7, 11,  enkel,  78, ['Krafts Torg', 'Kiliansg.',
                                'Magle St Kyrkog.', 'Stora Tomeg.']).
   billed( 8, 14, dubbel,  17, ['Bangatan']).
   billed(10, 11, dubbel,  32, ['Biskopsgatan']).
   billed(10, 16, dubbel,  32, ['Allhelgona Kyrkogata']).
   billed(11,  5,  enkel,  38, ['Tomegapsgatan', 'Sandgatan']).
   billed(11,  7,  enkel,  40, ['Tomegapsgatan', 'Sankt Anne Gatan']).
   billed(11, 12, dubbel,  53, ['Östra Vallgatan']).
   billed(11, 17, dubbel,  56, ['Tunavägen']).
   billed(12, 13, dubbel,  70, ['Dalbyvägen']).
   billed(12, 26, dubbel,  99, ['Östra Vallgatan', 'Södra Esplanaden']).
   billed(13, 17, dubbel,  97, ['Tornavägen']).
   billed(13, 26, dubbel, 167, ['Tornavägen', 'Solvägen', 'Södra Vägen']).
   billed(13, 28, dubbel,  42, ['Dalbyvägen']).
   billed(14, 25, dubbel,  12, ['Trollebergsvägen']).
   billed(14, 30,  enkel,  33, ['Nygatan']).
   billed(15, 19, dubbel,  21, ['Kung Oscars väg']).
   billed(15, 36, dubbel,  48, ['Kung Oscars väg']).
   billed(16, 18, dubbel,  42, ['Getingevägen']).
   billed(16, 19, dubbel,  32, ['Kævlingevägen']).
   billed(17, 20, dubbel, 101, ['Tornavägen']).
   billed(17, 22, dubbel,  53, ['Tunavägen']).
   billed(18, 19, dubbel,  32, ['Getingevägen', 'Kung Oscars väg']).
   billed(18, 20, dubbel,  58, ['Getingevägen']).
   billed(19, 32, dubbel, 108, ['Kävlingevägen']).
   billed(20, 21, dubbel,  51, ['Svenshögsvägen']).
   billed(20, 31, dubbel,  81, ['Getingevägen']).
   billed(21, 24, dubbel, 207, ['Svenshögsvägen', 'Norra Gränsvägen']).
   billed(21, 31, dubbel,  71, ['Norra Ringen']).
   billed(21, 32, dubbel, 108, ['Norra Ringen']).  
   billed(22, 29, dubbel, 314, ['Tunav.', 'Spelmansv.', 'Thulehemsv.', 
                                'Vikingav.']).
   billed(22, 38, dubbel, 125, ['Tunavägen', 'Sångarevägen', 'Spexarevägen']).
   billed(23, 34, dubbel,  52, ['Sankt Lars Väg']).
   billed(24, 31, dubbel, 234, ['Norra Gränsv.', 'Klosterängsv.',
                                'Magistratsv.', 'Delfinv.']).
   billed(25, 30, dubbel,  31, ['Gasverksgatan', 'Svanegatan']).
   billed(25, 36, dubbel, 118, ['Byggmästaregatan', 'Bryggaregatan']).
   billed(25, 37, dubbel,  60, ['Trollebergsvägen']).
   billed(26,  3,  enkel,  81, ['Stora Södergatan', 'Västra Mårtensgatan']).
   billed(26, 30, dubbel,  73, ['Gyllenkroks alle', 'Svanegatan']).
   billed(26, 34, dubbel,  61, ['Malmövägen']).
   billed(26, 37, dubbel, 118, ['Ringvägen']).
   billed(27, 28, dubbel, 239, ['Motorvägen']).
   billed(27, 31, dubbel,  66, ['Norra Ringen']).
   billed(28, 29, dubbel, 186, ['Dalbyvägen', 'Norrängavägen']).
   billed(28, 35, dubbel, 323, ['Motorvägen']).
   billed(29, 38, dubbel, 345, ['Vikingav.', 'Thulehemsv.', 'Spelmansv.',
                                'Sångarev.', 'Spexarev.']).
   billed(30, 37, dubbel,  63, ['Svanevägen', 'Trollebergsvägen']).
   billed(32, 33, dubbel, 134, ['Kävlingevägen']).
   billed(32, 36, dubbel, 118, ['Kaprifolievägen']).
   billed(34, 35, dubbel, 152, ['Malmövägen']).
   billed(34, 37, dubbel, 147, ['Stattenavägen', 'Ringvägen']).
   billed(36, 37, dubbel,  98, ['Bryggaregatan', 'Fasanvägen']). 



