
:- dynamic(fact/1).
:- dynamic(derived_fact/2).
:- retractall(fact(_)).
:- retractall(derived_fact(_,_)).

/* --- Defining operators --- */

:- op(800, fx, if).
:- op(700, xfx, then).
:- op(200, xfy, and).

:- dynamic(wrong/1).
:- retractall(wrong(_)).
/* --- A simple backward chaining rule interpreter --- */

is_true( P ):-
    fact( P ).

is_true( P ):-
    if Condition then P,
    is_true( Condition ).

is_true( P1 and P2 ):-
    is_true( P1 ),
    is_true( P2 ).




/* --- A simple forward chaining rule interpreter --- */
% too bad we don't   really use it :)
forward:-
    new_derived_fact( P ),
    !,
    write( 'Derived:' ), write_ln( P ),
    assert( fact( P )),
    forward
    ;
    write_ln( 'No more facts' ).

new_derived_fact( Conclusion ):-
    if Condition then Conclusion,
    not( fact( Conclusion ) ),
    composed_fact( Condition ),
	assert(derived_fact(Condition,Conclusion)).

composed_fact( Condition ):-
    fact( Condition ).

composed_fact( Condition1 and Condition2 ):-
    composed_fact( Condition1 ),
    composed_fact( Condition2 ).



go :-
	writeln('welkom bij dokter doolittle diagnose systeem'),
	writeln('vult aub alle symptomen in die u heeft met een . erachter'),
	writeln('bijvoorbeeld: klierzwellingen.'),
	writeln('vul q. in als u klaar bent'),
	readsymptoms,!,
	(	valuefacts
		;
		writeln('einde van het programma')
	). 

readsymptoms :-
	read(Z),
	(	string_length(Z,1)
		;
		%abstraction layer here??
		assert(fact(symptoom(Z))),
		writeln('vult aub het volgende symptoom in: '),
		readsymptoms
		
	).

:- dynamic(numberscor/5).

valuefacts :-
	retractall(numberscor(_,_,_,_,_)),
	(	if Condition then Conclusion,
		numbercor(Condition,R,U,W),
				%Right, Unknown, Wrong
		assert(numberscor(Condition,R,U,W, Conclusion)),
		%	writeln(numbercor(Condition,R,U,W, Conclusion)),
		fail
		;
		true
	),
	writeln('high fact:  '),
	returnhighestfact(numberscor(Condition,_,_,_,_)),!,
	writeln(Condition),
	ask_question(Condition).


returnhighestfact(Max) :-
        findall(R^numberscor(Condition, R, U, 0, Conclusion), numberscor(Condition,R,U,0,Conclusion), List),
        findmax(List, 0^foo, MaxR^Max),
	checkR(MaxR, Max), !.

getnumscor(numberscor(Cond, R, U, W, Concl), Cond, R, U, W, Concl).

checkR(R, Max) :-
        getnumscor(Max, _Cond, R, U, _W, Concl),
        R >= 4, U is 0,
        writeln('U bent ziek:'), writeln(Concl),!, fail.
	
checkR(_R, _Condition). % :- writeln('(nog) niet ziek').

findmax([], Result, Result).

%not higher, accu is still best match
findmax([HR^_|Tail], AR^Accu, Result) :-
        nonvar(AR), nonvar(HR),
        AR >= HR,
        findmax(Tail, AR^Accu, Result).

%found a higher match
findmax([HR^H|Tail], AR^_, Result) :-
        nonvar(AR), nonvar(HR),
        AR < HR,
        findmax(Tail, HR^H, Result).






%findbestfact(Z) :-

ask_question(Condition) :-
	findunknown(Condition,Unknown),	
	write('onze vraag: '),
	question(Unknown),
	valuefacts.	%value all facts to restart 

question(symptoom(Unknown)) :-
	write('heeft u het symptoom: '),writeln(Unknown),!,
	read(Answer),
	procesquestion(symptoom(Unknown),Answer).


question(sexe(Unknown)) :-
	write('heeft u de sexe: '),writeln(Unknown),!,
	read(Answer),
	procesquestion(sexe(Unknown),Answer).


question(Unknown) :-
	write('heeft u: '),writeln(Unknown),!,
	read(Answer),
	procesquestion(Unknown,Answer).
	%assert something here

manvrouw(man,vrouw).
manvrouw(vrouw,man).

procesquestion(sexe(Unknown),Yes) :-
	shortcut(Yes,ja),
	assert(fact(sexe(Unknown))),
	manvrouw(Unknown,Other),
	assert(wrong(sexe(Other))),
	writeln(new_fact_true(sexe(Unknown))),
	writeln(new_fact_wrong(sexe(Other))).

procesquestion(sexe(Unknown),Yes) :-
	shortcut(Yes,nee),
	assert(wrong(sexe(Unknown))),
	manvrouw(Unknown,Other),
	assert(fact(sexe(Other))),
	writeln(new_fact_wrong(sexe(Unknown))),
	writeln(new_fact_true(sexe(Other))).

procesquestion(Symptrue,Yes) :-
	shortcut(Yes,ja),
	assert(fact(Symptrue)),
	writeln(fact(Symptrue)).

procesquestion(Symptwrong,No) :-
	shortcut(No,nee),
	assert(wrong(Symptwrong)),
	writeln(new_fact_wrong(Symptwrong)).

shortcut(ja, ja).
shortcut(j, ja).
shortcut(yes, ja).
shortcut(klopt, ja).
shortcut(zeker, ja).
shortcut(y, ja).
shortcut(nee, nee).
shortcut(n, nee).
shortcut(no, no).
shortcut(man, man).
shortcut(m, man).
shortcut(male, man).
shortcut(vrouw, vrouw).
shortcut(v, vrouw).
shortcut(female, vrouw).
shortcut(f, vrouw).

findunknown(Cond1 and Cond2,Unknown) :-
	!,
	(	findunknown(Cond1,Unknown);
		findunknown(Cond2,Unknown);
		fail
	).

findunknown(Condition,_Unknown) :-
	fact(Condition),
	!,fail.

findunknown(Condition,_Unknown) :-
	wrong(Condition),
	!,fail.

findunknown(Unknown,Unknown) :-
	!.

numbercor(Condition,1,0,0) :-
	fact( Condition),!.

numbercor(Condi1 and Condi2,R,U,W) :-
	numbercor(Condi1,R1,U1,W1),
	numbercor(Condi2,R2,U2,W2),
	R is R1 + R2,
	U is U1 + U2,
	W is W1 + W2,!.

numbercor(Condition,0,0,1) :-
	wrong(Condition),!.

numbercor(_Condition,0,1,0) :-
	!.


how(C) :-
	derived_fact(How,C),
	write(C),write(' is derived from '),writeln(How),
	how(How).

how(C) :-
	not(derived_fact(_How,C)),
	fact(C),
	write(C),writeln(' is a fact known in the data.pl').

how(A and B) :-
	how(A),
	how(B).
	
fact(a).
fact(b).

if symptoom('hoofdpijn') and symptoom('hoofdpijn achter ogen') and symptoom('spierpijn') and symptoom('gewrichtspijn') then ziekte('dengue').
if symptoom('onregelmatige koorts') and symptoom('klierzwellingen') and symptoom('huidafwijkingen') and symptoom('psychische veranderingen') then ziekte('afrikaanse slaapziekte').
if symptoom('onregelmatige koorts') and symptoom('hartafwijkingen') then ziekte('ziekte van chagas').
if symptoom('onregelmatige koorts') and symptoom('afwijking diverse organen') then ziekte('Kala azar').
if symptoom('onregelmatige koorts') and symptoom('hoofdpijn') and symptoom('rugpijn') and symptoom('gewrichtspijn') then ziekte('Brucellose').

if symptoom('koorts') and symptoom('huiduitslag')  and symptoom('lymfeklierpijn') then ziekte('Tick-typhus').

if sexe('man') and symptoom('Etterige afscheiding in uretha/pisbuis') then ziekte('Gonorroe').
if sexe('vrouw') and symptoom('Versterkte vaginale afscheiding') then ziekte('Gonorroe').

if symptoom('Harde niet pijnlijke zweer op geslachtsdeel of anus') then ziekte('Syfilis').

if symptoom('pijnlijke zweren aan geslachtsorganen') then ziekte('Ulcus molle').


if symptoom('hardnekkige zweren') then ziekte('kleine huidwondjes').
if symptoom('jeukende rode pukkels') and symptoom('rode vlekken')  then ziekte('pricky heat').

if symptoom('kleine licht-schilferende lichte vlekken') then ziekte('Pityriasis versicolor').

if symptoom('lichte huidvlekken') and symptoom('gevoelloze huidvlekken') then ziekte('lepra').

if symptoom('framboosachtige huidafwijkingen') then ziekte('framboesia').

if symptoom('steenpuisten') then ziekte('myiasis').

if symptoom('hard knobbeltje') and symptoom('erwtgroot hard knobbeltje') then ziekte('zandvlooien').

if symptoom('lastig jeukende huidafwijkingen') then ziekte('mijten').

if symptoom('jeuk') and symptoom('huiduitslag') then ziekte('luizen en vlooien').

if symptoom('koorts') and symptoom('temperatuur > 40') then ziekte('malaria tropica').
if symptoom('koorts') and symptoom('koude rillingen') and symptoom('hevige transpiratie') and symptoom('hoofdpijn') and symptoom('diarree') and symptoom('braken') and symptoom('stuipen') then ziekte('malaria tropica').


if symptoom('vochtverlies') then ziekte('turista').

if symptoom('waterdunne diarree') and symptoom('opgezet gevoel') and symptoom('pijn in de buik') and symptoom('misselijkheid') and symptoom('frequente brijig-vettige ontlasting') then ziekte('giardiasis').

if symptoom('hoge koorts') and symptoom('heftige krampende aandrang') and symptoom('ontlasting met bloederige slijm') then ziekte('bacillaire dysenterie').

if symptoom('hoge koorts') and symptoom('obstipatie') and symptoom('hoofdpijn') and symptoom('enkele dagen stuffig') then ziekte('typhoid').

if symptoom('waterdunne diarree') then ziekte('cholera').

if symptoom('patient geel') and symptoom('urine donker') and symptoom('ontlasting licht') and symptoom('pijn rechtsboven in buik') and symptoom('misselijkheid') then  ziekte('geelzucht').

if symptoom('worm in ontlasting') and symptoom('buikpijn') and symptoom('jeuk aan anus') then ziekte('aarsmaden').

if symptoom('buikpijn') and symptoom('diarree') then ziekte('zweepwormen').

if symptoom('bloedarmoede') and symptoom('zware infectie') then ziekte('mijnwormen').

if symptoom('buikpijn') and symptoom('diarree') and symptoom('netelroosachtige huidafwijkingen') then ziekte('strongyloides stercoralis').

if symptoom('langzaam voortkruipende huidgangetjes') then ziekte('larva migrans').

if symptoom('wormen in ontlasting') and symptoom('buikpijn') then ziekte('taenia saginata').

if symptoom('knobbeltjes') and symptoom('epilepsie') then ziekte('taenia solium').

if symptoom('buikpijn') and symptoom('diarree') then ziekte('hymenolepis nana').

if symptoom('klachten bij urineren') then ziekte('schistosoma haematobium').



