
%% This file (main_loop) contains the predicates directly serving 
%% the main interactive loop of the program. This is largely a 
%% matter of handling the different cases for user command input 
%% then acting accordingly. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% loop/0: 
%
% Starts main loop of the program. 

loop:- nl, 
   write('TULIP MAIN LOOP'),  
   set_flag(mode,analysis), nl,      % default initial mode is analysis. 
   command_options(loop),            % Print out command options. 
    print_mode,                      % Print current mode. 
   nextloop.                         % Get next command and proceed. 

%%%%%%%%%

% nextloop/0: 
%
% read next user command, and passes onto loop/1, which
% handles all the different command cases. 

nextloop:- 
   get_command(loop,R),        % Read user command. 
   loop(R).       

%%%%%%%%%

% loop/1: <command>
%
% handles the different user command cases. 

loop([number,Ds]):-             % User input was a number (digit string). 
   digits_to_number(Ds,N), !,   % Convert to decimal number. 
   process_example(N),          % Process the identified example, according to current mode. 
   nextloop.                    % Get next command and proceed. 


loop([incremental]):- !,  
   set_flag(mode,incremental_analysis),      % Change to incremental mode. 
   print_mode, 
   nextloop.                                 % Get next command and proceed. 

loop([incremental,Ds]):-                  % Case: Process example (Ds), in incremental mode.
   digit_string(Ds), !, 
   set_flag(mode,incremental_analysis),   % Change to incremental mode. 
   print_mode,  
   loop([number,Ds]).                     % Call loop/1 to process example Ds. 

loop([analysis]):- !, 
   set_flag(mode,analysis),      % Change to analysis mode. 
   print_mode, 
   nextloop.                     % Get next command and proceed. 

loop([analysis,Ds]):-               % Case: Process example (Ds), in analysis mode.
   digit_string(Ds), !, 
   set_flag(mode,analysis),         % Change to analysis mode. 
   print_mode, 
   loop([number,Ds]).               % Call loop/1 to process example Ds. 

loop([generation]):- !, 
   set_flag(mode,generation),           % Change to generation mode.   
   print_mode, 
   nextloop. 

loop([generation,Ds]):-            % Case: Process example (Ds), in generation mode.
   digit_string(Ds), !, 
   set_flag(mode,generation),      % Change to generation mode.   
   print_mode, 
   loop([number,Ds]).              % Call loop/1 to process example Ds. 

loop([read_example]):- !,          % This case allows user to input a list of segments, 
                                   % for processing according to current mode.
				   % May be subsequently re-referred to as example 0. 
   write('Enter input phoneme list (ending with a fullstop)'), 
   nl, write('|: '), read(INPUT),  % Read in the segment list. 
   set_flag(input_example,INPUT),  % Record the segment list. 
   process_example(0),             % Processing example 0 = process what is stored with
                                   % the input_example flag. 
   nextloop.                     % Get next command and proceed. 

loop([redo]):-                     % Case: redo the most recently performed process. 
   flag(last_process,Mode),       
   set_flag(mode,Mode),            % Set the mode to be that of most recent process. 
   flag(last_input,N), !,          % Look up example number for most recent process. 
   nl, write('Redo example '), write(N), 
   print_mode, 
   process_example(N),             % Redo the example. 
   nextloop.                    % Get next command and proceed. 

loop([redo]):-                                     % No previous process to redo. 
   nl, write('No previous process to redo'), nl,   % Warn. 
   nextloop.                                       % Get next command and proceed. 

loop([mode]):- !,    
   print_mode,                  % Print the current mode (i.e. analysis, 
                                % generation or incremental analysis). 
   nextloop.                    % Get next command and proceed. 

loop([reload]):- !, 
   reload,                      % Call the reloading predicate. 
   nextloop.                    % Get next command and proceed. 

loop([recompile]):- !, 
   set_up,                      % Call predicate for recompiling macros/rules/lexicon. 
   nextloop.                    % Get next command and proceed. 

loop([examples]):- 
   (flag(mode,analysis) ; 
    flag(mode,incremental_analysis)), !, nl, 
   egs_a,                       % Print analysis examples. 
   nextloop.                    % Get next command and proceed. 

loop([examples,Ds1,Ds2]):- 
   (flag(mode,analysis) ; 
    flag(mode,incremental_analysis)), !, nl, 
   digits_to_number(Ds1,N1), 
   digits_to_number(Ds2,N2), 
   egs_a(N1,N2),                % Print analysis examples in range N1 to N2. 
   nextloop.                    % Get next command and proceed. 

loop([examples]):- 
   flag(mode,generation), !, nl, 
   egs_g,                       % Print generation examples. 
   nextloop.                    % Get next command and proceed. 

loop([examples,Ds1,Ds2]):- 
   flag(mode,generation), !, nl, 
   digits_to_number(Ds1,N1), 
   digits_to_number(Ds2,N2), 
   egs_g(N1,N2),                % Print generation examples in range N1 to N2. 
   nextloop.                    % Get next command and proceed. 

loop([answers]):-               % Case: print answers for last process done in current mode. 
   flag(mode,generation),                        % Current mode = generation. 
   \+(last_generation_answer(_,_)), !, nl,       % BUT no previous generation answers recorded. 
   write('No previous generation answers'), nl, 
   nextloop.                                     % Get next command and proceed. 

loop([answers]):-               % Case: print answers for last process done in current mode. 
   flag(mode,generation), !, nl,                         % Current mode = generation. 
   fail_drive((last_generation_answer(N,Partition),      % Look up previous generation answers. 
               write('Answer '), write(N), write(':  '), 
	       departition(Partition,Surf,_Lex), 
	       print_segment_list(Surf),                 % Print answer. 
	       print_partition(Partition),nl)), 
   nextloop.                                             % Get next command and proceed. 

loop([answers]):-                % Case: print answers for last process done in current mode. 
   flag(mode,analysis),                            % Current mode = analysis. 
   \+(last_analysis_answer(_,_)), !,               % BUT no previous generation answers recorded. 
   nl, write('No previous analysis answers'), nl, 
   nextloop.                                       % Get next command and proceed. 

loop([answers]):-                % Case: print answers for last process done in current mode. 
   flag(mode,analysis), !, nl,                            % Current mode = analysis. 
   fail_drive((last_analysis_answer(N,Partition),         % Look up previous analysis answers. 
               write('Answer '), write(N), write(':  '), 
	       departition(Partition,_Surf,Lex), 
	       print_segment_list(Lex),                   % Print answers. 
	       print_partition(Partition),nl)), 
   nextloop.                                              % Get next command and proceed. 

loop([answers]):-                % Case: print answers for last process done in current mode. 
   flag(mode,incremental_analysis), !,             % Current mode = incremental_analysis. 
                                                   % - answers are not stored for this mode. 
   nl, write('Previous answers not stored for incremental analysis'), nl,     % Warn. 
   nextloop.                                       % Get next command and proceed. 

loop([switches]):- !, 
   switches,         % Call predicate that allows user to change state of the printing switches.
   nextloop.         % Get next command and proceed. 

loop([quit|_]):- nl,                         % Command is to quit the loop. 
   write('quitting main loop.'), nl, nl,  
   write('BYE!'), nl, nl.                    % Finish. 

loop([commands]):- 
   command_options(loop),       % Print list of commmand options. 
   nextloop.                    % Get next command and proceed. 
   
loop(_):-                                   % Catch all case, where user's command not recognised. 
   nl, write(' ** Input not recognised. '), % Warn. 
   write('Use a designated option **'), nl, 
   command_options(loop),                   % Print list of commmand options. 
   nextloop.                                % Get next command and proceed. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Prints the current mode (i.e. analysis, generation or incremental analysis). 

print_mode:-  
   flag(mode,M), nl, write('(Mode: '),
   write(M), write(')'), nl. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Process example identified by number, according to the current mode. 

process_example(N):-  
   flag(mode,Mode),                              % Look up current mode. 
   (get_example(N,Mode,EG)                       % Look up example (according to mode), 
        -> true
	 ;  (nl, write('Example '), write(N),    % - if example not found, warn. 
	     write(' not found'), nl, fail)), 
   process_example_main(Mode,EG),                % Process segment list, by mode. 
   set_flag(last_process,Mode),                  % Record details of 
   set_flag(last_input,N), !.                    % last process. 

process_example(_N):-                                  % Warn if processing example, failed. 
   nl, nl, write(' *** Goal failed *** '), nl, nl.  

%%%%%%%

% process_example_main/2: <mode><seglist>
%
% Pass <seglist> onto appropriate predicate to process it, for current mode <mode>> 

process_example_main(analysis,EG):-    analysis(EG).  
process_example_main(generation,EG):-  generation(EG). 
process_example_main(incremental_analysis,EG):-  
    incremental_analysis(EG).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Look up example N, according to mode (i.e. different example sets
% for analysis and generation). 
% Note that first case is a special instance -- the number 0 doesn't
% refer to a prestated example, but rather to a segment list inputted
% by user to command-line, under command `read_input', and recorded 
% as a flag value. 

get_example(0,_Mode,EG):-                flag(input_example,EG), !. 
get_example(N,analysis,EG):-             eg_a(N,EG). 
get_example(N,incremental_analysis,EG):- eg_a(N,EG). 
get_example(N,generation,EG):-           eg_g(N,EG). 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



