
% File: cspdemo.pl
% Author: Peter Clark
% Purpose: Demo of LPE and other learning methods working on the
%	various constraint satisfaction problems.

:- ensure_loaded(['../lpe','../utils']).
:- ensure_loaded([library(random)]).

:- nl, nl, write('Type `| ?- demo.'' to start!'), nl, nl.

demo :-
	ensure_loaded_domain_theory,
	set_tracing_mode(on),
	repeat,
	learning_mode(Mode),
	tracing(TMode),
	member(NewTMode, [on,off]),
	NewTMode \= TMode,
	nl, write('What do you want to do?'), nl, nl,
	write('       1. (Re)initialise the concept definition'),
	write(' (NB must do this first!).'), nl,
	write('       2. List the current concept definition.'), nl,
	write('       3. Run the definition on an example, doing '), 
	write(Mode), write('.'), nl,
	write('       4. Change to a different learning mode.'), nl,
	write('       5. Switch the tracing mode '), write(NewTMode), 
	write('.'), nl,
	write('       6. Quit.'), nl, nl,
	write('                  Option number (eg `1.'') -> '),
	read(N),
	nl, 
	write('(Hit <return> to execute the goal below...)'), nl, nl,
	demo(N),
	N = 6,
	!.


demo(1) :- demo_goal( lpe_setup(fails/3) ).
demo(2) :- demo_goal( lpe_listing(fails/3) ).
demo(3) :- 
	random_example(E),
	write('Random hypothesis solution to the CSP: '),
	write(E), nl, nl,
	write(' - Let''s see if it fails any constraints.'), nl,
	write(' - If it does, we want to know which values caused the '),
	write('problem'), nl,
	write(' - If more than one constraint is violated, we want the'),
	write(' *best* explanation for'), nl,
	write('   failure (ie. the one blaming the earliest values in the'),
	write(' example)'), nl, nl,
	demo_goal( lpe_call(fails(E,Vs,N)) - [Vs/'Vs',N/'N'] - onesoln ), 
	nl, nl, nl,
	learning_mode(LMode),
	( member(LMode,[lpe,pe]) ->
	    write('Found the best solution!!!'), nl
	  ; write('Found a solution!!! (but not neccessarily the best)'), nl ),
	nl, write('This example ('), write(E), write(') fails constraint '), 
	write(N), nl,
	text(N, Text),
	write('     "'), write(Text), write('"'), nl,
	write('because of the values of variable(s) '),	write(Vs), nl, nl,
	write('============================'), nl.
demo(4) :-
	write('New learning mode (`lpe.'', `pe.'', `ebg.'' or `none.'')? '),
	read(Mode),
	set_learning_mode(Mode).
demo(5) :-
	tracing(TMode),
	member(NewTMode, [on,off]),
	NewTMode \= TMode, !,
	demo_goal( set_tracing_mode(NewTMode) ).
demo(6).

random_example(E) :-
	random_example(1, E).

random_example(N, []) :-
	no_of_generators(NMax),
	N > NMax,
	!.
random_example(N, [V|Vs]) :-
	all_vals(N, AllVs),
	random_member(V, AllVs),	% in library(random)
	NewN is N + 1,
	random_example(NewN, Vs).

% ======================================================================
%		DEFINITION OF CONCEPT DEFN QUALITY FOR THE CSPs
% ======================================================================

:- no_style_check(multiple).

% Order by how early the latest variable involved (see ML92 paper for details)
quality(Defn, Q) :-
	Defn = ( fails(_,VarsInvolved,_) :- _),
	remove_tail_var(VarsInvolved),
	sort(VarsInvolved, EarliestToLatest),
	reverse(EarliestToLatest, Q).	

:- style_check(multiple).

remove_tail_var(X) :- myappend(X,[],_), !.	%  make X=[a|_] -> X=[a]

reverse(List, Reversed) :-
	reverse(List, [], Reversed).

reverse([], Reversed, Reversed).
reverse([Head|Tail], Sofar, Reversed) :-
	reverse(Tail, [Head|Sofar], Reversed).

ensure_loaded_domain_theory :-
	source_file(fails(_,_,_), _), !.
ensure_loaded_domain_theory :-
	write('Hey! You must load a domain theory (`compile(cities).'''),
	write(' or `compile(zebras).'')'), nl,
	write('first!'), nl, nl,
	fail.

