
%% This file (read_commands) contains predicates which help 
%% to recognise/handle user inputted commands. 
%% 
%% For different command-groups, the user may define a set 
%% of possible commmands, and a default response for where
%% no input is given. 

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

% get_command/2: <group><command>
%
% For command group <group>, read user's input and identify command given, 
% returning it as <command>. 

get_command(Group,Command):- 
   write_input_marker(Group),            % Print marker indicating that input is expected. 
   get_alphanum_strings(Input),          % Get input as a list of atom lists. 
   get_command(Group,Command,Input), !.  % Recognise the command, and return as Command. 

%%%%%%%
% get_command/3:

get_command(Group,Command,[]):-                % Input was null. 
   command_default(Group,repeat_command_loop), % command's default option = repeat, 
   get_command(Group,Command).                 % so just go round again. 

get_command(Group,Command,[]):-                % Input was null. 
   command_default(Group,Command),             % command's default \= repeat.
   \+(Command = repeat_command_loop).          % Return the default as the command. 

get_command(_Group,[number,A|As],[A|As]):-   % Input begins with a list of digits, 
   digit_string(A), !.                       % Return Command as `number', plus digits. 

get_command(Group,Command,[A|As]):-     % Otherwise look up commands beginning with the same
                                        % sequence of letters as first atom list of input, 
					% e.g. [a,n] is prefix of `analysis' and `answer'. 
   append(A,V,A1),    % Gives list a variable tail. 
   set_of(C,                                            % Look up commands beginning with 
          V^X^(command(Group,C,X), explode_atom(C,A1)), % the right sequence of letters. 
          Commands),
   get_command(Group,Command,As,Commands).      % Consider cases for command set found. 

%%%%%%%
% get_command/4:

get_command(Group,Command,_,[]):-                                         % No commands found.
   nl, write(' ** Input not recognised. Use a designated option **'), nl, % Print warning.
   command_options(Group),                                             % Print command options
   get_command(Group,Command).                                         % Try again. 

get_command(Group,Command,_,[A,B|C]):-           % Command set contains >1 command. 
   nl, write(' ** Input ambiguous ** '), nl,     % Print warning. 
   write([A,B|C]), nl, 
   get_command(Group,Command).                   % Try again. 

get_command(_Group,[Command|As],As,[Command]).   % A unique command identified. Return it, 
                                                 % together with remainder of user input. 

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

% Print out the command alternatives for the given command group. 

command_options(Group):- 
   nl,
   write('Command options:'), 
   nl, 
   fail_drive((command(Group,_Command,Comment), 
               write('  '), 
               write(Comment), nl)). 

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

% Prints a marker - indicating that input is expected. 
% User may define a marker specific to the command group 
% (using input_marker/2), otherwise a default marker `|:' 
% is printed. 

write_input_marker(Group):-             % Print group specific marker.
    input_marker(Group,Marker),         % Lookup group markers. 
    nl, write(Marker),                  % Print it. 
    write(' '), !.  

write_input_marker(_):-
    nl, write('|: ').                   % Otherwise, print default marker.

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

% command/3: <group><command><comment>
%
% The following facts define the commmand groups. Each fact
% specifies the command group (Arg 1), the defined command (Arg 2), 
% and what (Arg 3) is to be printed for this command by the predicate
% (command_options/1) that prints a list of command options for the
% group. command_options/1 will print the comments in the order in 
% in which the command/3 facts are defined. NOTE that any command/3
% statements whose <command> (Arg 2) is the null string '' define
% `spurious commands' whose only effect is to cause the <comment> to
% be printed when command_options/1 is called. 

% Definitions for the `loop' command group (for the `main_loop') : 

command(loop,  '',           'N               (N a number - process example N)'). 
command(loop,  analysis,     'analysis        (analysis mode)'). 
command(loop,  generation,   'generation      (generation mode)'). 
command(loop,  incremental,  'incremental     (incremental analysis mode)'). 
command(loop,  examples,     'examples        (list examples)'). 
command(loop,  '',           'examples M N    (list examples in range M to N)'). 
command(loop,  redo,         'redo            (redo last process)'). 
command(loop,  mode,         'mode            (state mode)'). 
command(loop,  quit,         'quit            (quit main loop)'). 
command(loop,  switches,     'switches        (change switches)'). 
command(loop,  answers,      'answers         (print last answers for current mode)'). 
command(loop,  commands,     'commands        (print command options)'). 
command(loop,  reload,       'reload          (reload source files)'). 
command(loop,  recompile,    'recompile       (recompile macros/rules/lexicon)'). 
command(loop,  read_example, 'read_example    (read segment sequence, and process)'). 

%%%%%%%%%%%

% Definitions for the `incremental' command group: 

command(incremental,  '',        'N            (N a number - advance N segments)'). 
command(incremental,  list,      'list         (list possible words)'). 
command(incremental,  quit,      'quit         (quit incremental loop)'). 
command(incremental,  commands,  'commands     (print command options for incremental loop)'). 
command(incremental,  answers,   'answers      (print current partial answers)'). 
command(incremental,  switches,  'switches     (change switches)'). 

%%%%%%%%%%%

% Definitions for the `reload' command group: 

command(reload,  compile,    'compile      (compile files)'). 
command(reload,  reconsult,  'reconsult    (reconsult files)'). 

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

% The following facts define the `default' response when the user's 
% input is null (i.e. user just presses return). 

% Default for loop command group: 

command_default(loop,repeat_command_loop).

% Default for incremental command group: 

command_default(incremental,[number,[1]]). 

% Default for reload command group: 

command_default(reload,[]). 

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

% Defines group specific input marker for the loop command group:

input_marker(loop,'=>').

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