%original code courtesty of Bratko.
%then modified mainly by Niels for KS assignment three.

:- 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 --- */

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 ).

%--- cut here

/*
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. 

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(Condition),!,
	ask_question(Condition).

returnhighestfact(Result) :-
	findall(R^numberscor(Condition, R, U, 0, Conclusion), numberscor(Condition,R,U,0,Conclusion), List),
	findmax(List, 0^_, MaxR^Max),
	getcondition(Max, Result),
	checkR(MaxR, Result).

getcondition(numberscor(Result, _, _, _, _), Result).

checkR(R, Condition) :-
	R >= 4,
	write('U bent ziek:'), write(Condition).

findmax([], Result, Result).

%not higher, accu is still best match
findmax([HR^_|Tail], AR^Accu, Result) :-
	AR >= HR,
	findmax(Tail, AR^Accu, Result).

%found a higher match
findmax([HR^H|Tail], AR^_, Result) :-
	AR < HR,
	findmax(Tail, HR^H, Result).





%returnhighfacts(Condi) :-
%	numberscor(Condi,R,U,W,Con),
%	R \= 0,
%	%findbestfact(Z),
%	writeln(numberscor(Condi,R,U,W,Con)).
%
%returnhighfacts(_Condi) :-
%	writeln('there are no good facts').

%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(Unknown) :-
	write('heeft u: '),writeln(Unknown),!,
	read(Answer),
	procesquestion(Unknown,Answer).
	%assert something here

procesquestion(Symptrue,Yes) :-
	shortcut(Yes,ja),
	assert(new_fact_true(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) :-
	!.

if symptoom('hoofdpijn') and symptoom('hoofdpijn achter ogen') then ziekte('dengue').
if symptoom('spierpijn') and symptoom('hoofdpijn') then ziekte('dengue').
if symptoom('gewrichtspijn') and symptoom('spierpijn') and symptoom('hoofdpijn') then ziekte('dengue').

if symptoom('onregelmatige koorts') and symptoom('klierzwellingen') then ziekte('afrikaanse slaapziekte').

%if e and c and p and z and y and g then x.
%if z and y and b and d then p.
%if a and b and e then c.
%if a and c then d.
%if c and d then e.

%if e or d and b then f.

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).

%symptoom(Description) :- 
*/
