%%%	0440949	Andreas van Cranenburgh
%%%	0518808	Joris de Groot

%%% Rule-bases classification
%%% Tropische ziekten.

:- dynamic(fact/1).
:- retractall(fact(_)).

:- [risks].
:- [symptomen].
:- [ziekten].

go :-
	retractall(fact(_)),
	writeln('Geef symptoom gevolgd door enter. Geef stop om verder te gaan.'),
	readsymptoms,
	riskfactors,
	classify.

readsymptoms :-
	readln(X),
	(	X = [stop]
	;	checksymptom(X),
		writeln('Geef symptoom: '),
		readsymptoms).
		
checksymptom(X) :-
	(match(X, begin, Symptom) ->
		(ziekte(_, symptomen, Symptom) ->
			write('Match: '), writeln(Symptom),
			assert(fact(symptoom(Symptom))),
			findall(ChildSymptom, 
				symptoom(Symptom, ChildSymptom), List),
			(\+ List = [] ->
				writeln('De volgende specifiekere symptomen zijn ook mogelijk:'),
				printlist(List)
			;	true)
		;	findall(ChildSymptom, symptoom(Symptom, ChildSymptom), List),
			(\+ List = [] ->
				writeln('Voeg svp een van de de volgende kwalificaties toe: '),
				printlist(List)
			;
				writeln('sorry symptoom niet herkend')))
	;	writeln('sorry, symptoom niet herkend')).

ask(Q, Ans) :-
	write(Q), writeln(' (ja/nee) '),
	readln(X),
	((X = ['ja'] ; X = ['nee']) -> 
		Ans = X
	;	ask(Q, Ans)).

%%if X then Y :- symptoom(X), ziekte(Y).

%find symptom which (best) describes given input sentence.
%also try synonyms ('synoniem' always matches against itself).
%match(Input, Best, Result).
match([], Result, Result) :- \+ Result = begin.
match([H|List], Best, Result) :-
	symptoom(_, X),
	concat_atom(XList, ' ', X),
	(synoniem(HSyn, H), member(HSyn, XList),
	dist(X, DH), 
	dist(Best, DBest),
	DH > DBest ->
		match(List, X, Result)).

match([_H|List], Best, Result) :-
		match(List, Best, Result).

%get distance to rootnode.
dist(begin, 1).
dist(Y, Dist) :-
	symptoom(X, Y),
	dist(X, New),
	Dist is New + 1.

%find disease matching input symptoms
classify :-
	findall(X, ziekte(X, _, _), List),
	list_to_set(List, Ziektes),
	findall(Y, fact(symptoom(Y)), Symptomen),
	classify(Symptomen, Ziektes, _, 0).
	%classify(Symptomen, []).

%given a list of input symptoms, traverse the known diseases
%and match the one with the most overlap.
classify(_Symptoms, [], _Best, 1) :-
	writeln('Het resultaat is gebaseerd op te weinig symptomen, meer symptomen opgeven svp!'),
	readsymptoms, classify.
classify(_Symptoms, [], Best, BestScore) :-
	writeln('Resultaat:'), write(Best), write(' met '), write(BestScore),
	writeln(' overeenkomende symptomen'),
	showconsequences(Best).

classify(Symptoms, [H|Tail], Best, BestScore) :-
	findall(X, ziekte(H, symptomen, X), HSymptoms),
	(ziekte(H, familie, HParent) -> 
		findall(X, ziekte(HParent, symptomen, X), HParentSymptoms),
		append(HSymptoms, HParentSymptoms, H1Symptoms)
	;
		H1Symptoms = HSymptoms),
	intersection(Symptoms, H1Symptoms, CommonSymptoms),
	length(CommonSymptoms, HScore),
	(HScore > 0 ->
		write(H), write(' heeft '),
		write(HScore), writeln(' overeenkomstige symptomen.')
	; 	true),
	(HScore > BestScore ->
		classify(Symptoms, Tail, H, HScore)
		; classify(Symptoms, Tail, Best, BestScore)).

%If available, show a list of consequences.
showconsequences(Disease) :-
	findall(X, ziekte(Disease, gevolg, X), List),
	(\+ List = [] ->
		writeln('Mogelijke gevolgen van deze ziekte zijn: '),
		printlist(List)
	;	true).
	
printlist([]).
printlist([H|List]) :-
	writeln(H),
	printlist(List).
