#! /usr/bin/swipl
% (home + travail)

% #! /usr/local/swipl/bin/swipl
% (magi)

/* ========================================================================== */ 
/*                        LEAR to TILDE TRANSLATOR	                       */
/* ========================================================================== */

:- set_prolog_flag(verbose, silent).
												% stacks
:- set_prolog_stack(local,  limit(10**9)).  	% 1 Go
:- set_prolog_stack(global, limit(10**9)).	
:- set_prolog_stack(trail,  limit(10**9)).

:- initialization goal.

/* ========================================================================== */

goal :-
        get_arguments(File_lear_train, File_lear_test, File_tilde),
	   convert(File_lear_train, File_lear_test, File_tilde),
	   halt(0).
 
get_arguments(File_lear_train, File_lear_test, File_tilde) :-
        current_prolog_flag(argv, Argv),
        append(_, [File_lear_train, File_lear_test, File_tilde], Argv).


   /* create a file containing positive and negative ambiguous examples 
      from a lear format into a tilde (model) format */
convert(
        File_lear_train,   % file.int containing train examples
        File_lear_test,    % file.int containing test examples
        File_tilde         % name of the result file
       ) :- 

   init,
 
       		% build name of the input files
   atom_concat(File_lear_train, '.int', File_lear_train1),
   atom_concat(File_lear_test, '.int', File_lear_test1),
   
				% get train examples
   train:consult(File_lear_train1),
   get_pos_examples(train, LPos_train),
   get_neg_examples(train, LNeg_train),
   append(LPos_train, LNeg_train, LTrain),

				% get test examples
   test:consult(File_lear_test1),
   get_pos_examples(test, LPos_test),
   get_neg_examples(test, LNeg_test),
   append(LPos_test, LNeg_test, LTest),


				% convert examples in Tilde format
   reset_count(nb_examples),
   convert_examples(train, LTrain, LTrain_tilde),
   convert_examples(test, LTest, LTest_tilde),
   append(LTrain_tilde, LTest_tilde, LTilde),

				% write Tilde examples
   atom_concat(File_tilde, '.kb', File_tilde1),
   open(File_tilde1, write, Stream),
   write_examples(LTilde, Stream),
   close(Stream).


init :-
   getenv('LEAR_DIR', Lear),
   
   atom_concat(Lear, '/file.pl', File),
   use_module(File),

   atom_concat(Lear, '/list.pl', List),
   use_module(List),

   atom_concat(Lear, '/counter.pl', Counter),
   use_module(Counter).

/* ================================ GETTING EXAMPLES ======================== */     
  
get_pos_examples(Module, LEx) :-
   findall((N, Target, pos, Ex), 
           (Module:pos(N, Ex), Module:target(N, pos, Target)), LEx).
   
get_neg_examples(Module, LEx) :-
   findall((N, Target, neg, Ex), 
          (Module:neg(N, Ex), Module:target(N, neg, Target)), LEx).  

/* ========================= CONVERTING EXAMPLES ============================ */  

convert_examples(_Train_test, [], []) :-
   !.
   
convert_examples(Train_test, [Ex|Lex], [Ex2|Lex1]) :-   
   convert_one_example(Ex, Ex1),
   add_test(Train_test, Ex1, Ex2),
   convert_examples(Train_test, Lex, Lex1).
   
   
add_test(test, [Atom|Ex], [Atom, testid(1)|Ex]) :-
   !.
   
add_test(_, Ex, Ex).   

   
convert_one_example([], []) :-
   !.
   
convert_one_example((_N, Target, Class, Ex), Ex_out) :-
   convert_atoms(Ex, Ex1),
   Target=..[Pred|Args],
   append(Args, [Class], Args1),
   Target1=..[Pred|Args1],
   get_count(nb_examples, N),
   append([begin(model(N)), Target1|Ex1], [end(model(N))], Ex_out).


convert_atoms([], []) :-
   !.
   
convert_atoms([neg(_)|LAtoms], LAtoms_out) :-
   !,
   convert_atoms(LAtoms, LAtoms_out).
   
convert_atoms([Atom|LAtoms], [Atom|LAtoms_out]) :-
   convert_atoms(LAtoms, LAtoms_out).   

   
	/* write examples  */
write_examples([], _Stream) :-
   !.

write_examples([Ex|Lex], Stream) :-
   write_one_example(Ex,Stream),
   write_examples(Lex, Stream).


/* write the current example in Tilde format */  
write_one_example(Ex, Stream) :-
  write_atoms(Ex, Stream),
  nl(Stream).
    
    
write_atoms([], _Stream) :-
   !.
   
write_atoms([A|L], Stream) :-   
  fwrite_point_ln(Stream, A),
  write_atoms(L, Stream).

/* ============================== END OF LISTING ============================ */   

