
/* ========================================================================== */ 
/*             TILDE KEY FORMAT TO LEAR (format int) TRANSLATOR               */
/* ========================================================================== */


:- module(tileToLeaInt, [convert/1, convert/2]).


/* =========================== TRANSLATION OF EXAMPLES ====================== */

   /* create a file containing positive and negative incomplete examples 
      in a tilde format */
convert(
        File_train         % file containing train examples
       ) :- 

    gtrace,
    common_statements(File_train, File_out),
    tilde_to_lea(File_out).  

convert(
	      File_train,
	      File_bkg
       ) :-
 
	 common_statements(File_train, File_out),

	  		% build name of the input files
    atom_concat(File_bkg, '.bg', File_bkg1),
    bkg:consult(File_bkg1),

	 saturate,

    tilde_to_lea(File_out).  
  

common_statements(File_train, File_out) :-

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

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

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

   		% build name of the input files
   atom_concat(File_train, '.kb', File_train1),
   train:consult(File_train1),
   
   atom_concat(File_train, '.lang', File_language),
   lang:consult(File_language),
   
   atom_concat(File_train, '.int', File_out).
     

	/* saturate all clauses of the background knowledge on examples */
saturate :-
	module(bkg),
     bkg:p(X),
     bkg:predicates(LP),
     bkg:run_predicates(LP).

	/* execute all predicates of the list */
run_predicates([]) :-
   !.

run_predicates([P|LP]) :-
	writeln(P),	
	P,
     run_predicates(LP).
     
  
	/* get all defined user predicates of the background knowledge */
   
tilde_to_lea(File) :-
   get_examples(LPos, LNeg),
   write_lea_examples(File, LPos, LNeg).
  
/* ========================= READ EXAMPLES  ==================== */  
    
get_examples(LPos, LNeg) :-
   lang:concept(Concept/Arity),
   functor(Head, Concept, Arity), 
   lang:classes([Pos,Neg]),
   get_examples_properties(Head, Pos, LPos),
   get_examples_properties(Head, Neg, LNeg).  

get_examples_properties(Head, Label, LEx) :-
   copy_term(Head, Head1),
   lang:position_arg_class(P),
   arg(P, Head1, Label),
   findall(Head1, train:Head1, LHead),
   lang:properties(LProperties),
   get_properties(LHead, LProperties, LEx).


	/* get properties associated with given heads of concepts */
get_properties([], _Lproperties, []) :-
   !.

get_properties([Head|LHead], LProperties, [Ex|LEx]) :-
   arg(1, Head, N),								% N : identifier of example
   get_properties_example(N, LProperties, Ex1),
   lang:position_arg_class(P),
   delete_nth_arg(P, Head, Head1),            % delete class argument
   delete_first_argument([Head1|Ex1], Ex),
   get_properties(LHead, LProperties, LEx).


get_properties_example(_N, [], []) :-
   !.

get_properties_example(N, [Property/Arity|LProperties], Ex) :-
   functor(Proper, Property, Arity),
   arg(1, Proper, N),
   findall(Proper, train:Proper, LProper),
   get_properties_example(N, LProperties, Ex1),
   append(LProper, Ex1,Ex).
    
    
	/* delete first argument of all atoms in L */
delete_first_argument([], []) :-
   !.
   
delete_first_argument([Atom|LAtom], [Atom1|LAtom1]) :-
   Atom=..[Pred|[_|LArgs]],
   Atom1=..[Pred|LArgs],
   delete_first_argument(LAtom, LAtom1).


/* ==============================  WRITTING EXAMPLES ========================== */

write_lea_examples(
                     File,
                     LPos, 
                     LNeg
                     ) :- 
   
   open(File, write, Stream),
   reset_count(nb_examples),
   
   lang:modes(LModes),
   lang:types(LTypes),
   
   write_examples(pos, LPos, LModes, LTypes, Stream),
   nl(Stream),
   nl(Stream),
   write_examples(neg, LNeg, LModes, LTypes, Stream),
   
   close(Stream).


write_examples(_Label, [], _LModes, _LTypes, _Stream) :-
   !.

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


/* write the current example in lea format */ 
write_one_example(Label, [Head|Ex], LModes, LTypes, Stream) :-
  get_count(nb_examples, N),
  fwrite(Stream, Label),
  write(Stream, '('),
  write(Stream, N),
  write(Stream,','),
  nl(Stream),
  fwrite_list(Stream, Ex),
  fwrite_point_ln(Stream, ')'),
  nl(Stream),
  fwrite_point_ln(Stream, target(N, Head)),
  write_domains(Stream, N, LModes, LTypes, Ex),
  nl(Stream),
  nl(Stream).
  
  
write_domains(Stream, N, LModes, LTypes, Ex) :-
  get_domains(LTypes, LModes, Ex, LDomains),
  write(Stream, 'domains('),
  write(Stream, N),
  write(Stream, ','),
  fwrite_list(Stream, LDomains),
  write(Stream, ').').
  

	/* get values of types in the example Ex */  
get_domains([], _LModes, _Ex, []) :-
   !.
	
get_domains([Type|LTypes], LModes, Ex, [Domain|LDomains]) :-
   get_values_type(Type, LModes, Ex, LValues),
   sort(LValues, LValues1),
   not_empty(LValues1),
   !,
   Domain=..[Type|[LValues1]],
   get_domains(LTypes, LModes, Ex, LDomains).
   
get_domains([_Type|LTypes], LModes, Ex, LDomains) :-
    get_domains(LTypes, LModes, Ex, LDomains).
         

	/* get all values of the given type in the example Ex */
get_values_type(_Type, [], _Ex, []) :-
   !.
	
get_values_type(Type, [Mode|LModes], Ex, LValues) :-
   Mode=..[Pred|LArgs],
   get_indices(1, Type, LArgs, LIndices),
   length(LArgs, N),
   functor(Mode1, Pred, N), 
   get_values(LIndices, Mode1, Ex, LValues1),
   get_values_type(Type, LModes, Ex, LValues2),
   append(LValues1, LValues2, LValues).
   
   
	/* get indices in list L of occurrences of X */  
get_indices(_N, _X, [], []) :-
   !.
	
get_indices(N, X, [X|L], [N|LIndices]) :-
   !,
   N1 is N+1,
   get_indices(N1, X, L, LIndices).
   
get_indices(N, X, [_|L], LIndices) :-
   N1 is N+1,
   get_indices(N1, X, L, LIndices).
   
	/* get all values of arguments placed in positions given by LIndices */  
get_values([], _Mode, _Ex, []) :-
   !.
	
get_values([Indice|LIndices], Mode, Ex, LValues) :-
   findall(Value, (member(Mode, Ex), arg(Indice, Mode, Value)), LValues1),
   get_values(LIndices, Mode, Ex, LValues2),
   append(LValues1, LValues2, LValues).
     
   
write_atoms(_Stream, []) :-
   !.
   
write_atoms(Stream, [A|L]) :-   
  fwrite_point_ln(Stream, A),
  write_atoms(Stream, L).
  

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


    
    
