%======================================================================
%----This module holds the clauses for reading input sets in TPTP 
%----format. 

%----Written by Geoff Sutcliffe, July, 1992.
%----Updated by Geoff Sutcliffe, March, 1994.
%----Revised by Geoff Sutcliffe, May 1994, with ideas from 
%----    Gerd Neugebauer
%======================================================================
%---------------------------------------------------------------------
%----Make a completed path name from the TPTP directory and the
%----supplied file name
%----If the pathname is user, then do nothing
tptp_path_name(user,user):-
    !.

%----If there is a leading /,~ or ., then do nothing.
tptp_path_name(FileName,FileName):-
    name(FileName,[FirstAscii|_]),
%----Would be better to use member here, but it's the only place
    (FirstAscii == 46 ;           %----  .
     FirstAscii == 47 ;           %----  /
     FirstAscii == 126),          %----  ~
    !.

%----If no leading /, then put the TPTP directory on front
tptp_path_name(FileName,PathName):-
    name(FileName,FileNameList),
    tptp_directory(Directory),
    name(Directory,DirectoryList),
    append(DirectoryList,[47|FileNameList],PathNameList),
    name(PathName,PathNameList).
%---------------------------------------------------------------------
%----Determine what to do with the term read.
%----Input clauses are returned in a list. Note the dictionary is 
%----embedded in another list to align with the list of lists that can
%----return from an include.
filter_for_clauses(input_clause(Name,Status,Literals),Dictionary,
[input_clause(Name,Status,Literals)],[Dictionary]):-
    !.
    
%----Include directive cause recursive call to the top level to read
%----the included file.
filter_for_clauses(include(FileName),_,InputClauses,Dictionary):-
    !,
    read_input_clauses_from_file(FileName,InputClauses,_,
Dictionary).
    
filter_for_clauses(Term,_,[],[]):-
    write('Input term '),
    write(Term),
    write(' ignored'),
    nl.
%---------------------------------------------------------------------
%----This pulls apart the dictionary and instantiates the variables
%----with their names.
instantiate_variables_in_clause([]):-
    !.

%----Otherwise instantiate this node and do sub-dictionaries
instantiate_variables_in_clause([Name=Name|RestOfList]):-
    instantiate_variables_in_clause(RestOfList).
%----------------------------------------------------------------------
%----This pulls apart the dictionary and instantiates the variables
%----with their names.
instantiate_variables_from_dictionary([]):-
    !.

%----Special case of numbervars, simply call it
instantiate_variables_from_dictionary([[numbervars=Term]|RestOfList]):-
    !,
    numbervars(Term,0,_),
    instantiate_variables_from_dictionary(RestOfList).

%----If it's a list, then it's the list for a clause. Do recursively
instantiate_variables_from_dictionary([ClauseList|RestOfList]):-
    !,
    instantiate_variables_in_clause(ClauseList),
    instantiate_variables_from_dictionary(RestOfList).
%----------------------------------------------------------------------
%----Convert a SICStus dictionary into a list of variable-name pairs
make_dictionary_from_SICStus_Dictionary(SICStusDictionary,[]):-
    var(SICStusDictionary),
    !.

make_dictionary_from_SICStus_Dictionary(dic(NameList,[Variable|_],
SmallerSICStusDictionary,LargerSICStusDictionary),
[Name=Variable|RestOfDictionary]):-
    name(Name,NameList),
    make_dictionary_from_SICStus_Dictionary(SmallerSICStusDictionary,
SmallerDictionary),
    make_dictionary_from_SICStus_Dictionary(LargerSICStusDictionary,
LargerDictionary),
    append(SmallerDictionary,LargerDictionary,RestOfDictionary).
%----------------------------------------------------------------------
%----Convert Sepia's dictionary to standard dictionary. Supplied by
%----Max Moser of TUM.
make_dictionary_from_Sepia_dictionary([],[]).

make_dictionary_from_Sepia_dictionary([[Name|Variable]|Rest],
[Name=Variable|RestConverted]):-
    make_dictionary_from_Sepia_dictionary(Rest,RestConverted).
%----------------------------------------------------------------------
%----This is the entry point for reading
%----Generic version (does not preserve variable names)
real_read_for_dialect(generic,Term,Dictionary):-
    read(Term),
%----Set the dictionary to a special flag for later instantiating.
    Dictionary = [numbervars=Term].

%----BinProlog version
real_read_for_dialect(binprolog,Term,Dictionary):-
    real_read_for_dialect(generic,Term,Dictionary).

%----Sepia version (supplied by Max Moser of TUM)
real_read_for_dialect(sepia,Term,Dictionary):-
    readvar(input,Term,SepiaDictionary),
    (Term == end_of_file -> 
        SepiaDictionary=[]; 
        true),
    make_dictionary_from_Sepia_dictionary(SepiaDictionary,Dictionary).

%----Quintus version
real_read_for_dialect(quintus,Term,Dictionary):-
    read_term([variable_names(Dictionary)],Term).

%----SISCtus 0.7 version
real_read_for_dialect(sicstus07,Term,Dictionary):-
   'SYSCALL'(read_top_level(Term,SICStusDictionary)),
   make_dictionary_from_SICStus_Dictionary(SICStusDictionary,
Dictionary).

%----SICStus 2.1 version
real_read_for_dialect(sicstus21,Term,Dictionary):-
    current_input(InputStream),
    prolog:read_top_level(InputStream,Term,SICStusDictionary),
    make_dictionary_from_SICStus_Dictionary(SICStusDictionary,
Dictionary).

%----Redirect reading to the code for the current dialect
real_read(Term,Dictionary):-
    prolog_dialect(Dialect),
    !,
    real_read_for_dialect(Dialect,Term,Dictionary).

real_read(_,_):-
    write('No Prolog dialect installed, reading aborted'),
    nl,
    fail.
%----------------------------------------------------------------------
%----Read in cluases from current input device, until eof
read_input_clauses(InputClauses,Dictionary):-
%----Need to deal with skolem_functor facts here, if and when I add
%----the equality stuff again
    real_read(PrologTerm,TermDictionary),
    \+ (PrologTerm == end_of_file),
    !,
%----Check if an include, and return all clauses resulting
    filter_for_clauses(PrologTerm,TermDictionary,InputClauseList,
ClauseDictionary),
    read_input_clauses(RestOfClauses,RestOfDictionary),
    append(InputClauseList,RestOfClauses,InputClauses),
    append(ClauseDictionary,RestOfDictionary,Dictionary).

read_input_clauses([],[]).
%----------------------------------------------------------------------
%----Read input clauses from a file, doing includes too
read_input_clauses_from_file(FileName,InputClauses,ProblemName,
Dictionary):-
    seeing(CurrentInput),
    tptp_path_name(FileName,PathName),
    see(PathName),
    read_input_clauses(InputClauses,Dictionary),
%----Cut, so that later errors do not try to read more input clauses
    !,
    seen,
    see(CurrentInput),
%----Make problem name from file name
    basename(FileName,'.p',ProblemName).
%--------------------------------------------------------------------
