/* ========================================================================== */
/*                              NUMBER CONSTANTS                              */
/*             number the constants denoting objects of each example          */
/*             so that examples do not share any constant.                    */
/*             D. Bouthinon (04/01/2010)                                      */
/* ========================================================================== */

   /* create a file containing positive and negative archs */
number_objects(File_name, Concept) :-
   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),

   	% build name of the input file and output file
   atom_concat(File_name, '.int', File_in),

   bk:consult(File_in),

   numbers(File_name, Concept).

/* ========================= Numbers the objects of each example ==================== */

numbers(File_name, Concept) :-
   atom_concat(File_name, '.obj', File_obj),
   atom_concat(File_name, '.f', File_pos),
   atom_concat(File_name, '.n', File_neg),
   atom_concat(File_name, '.typ', File_typ),

   open(File_obj, write, Stream_obj),
   open(File_pos, write, Stream_pos),
   open(File_neg, write, Stream_neg),
   open(File_typ, write, Stream_typ),

   reset_count,
   Concept =..[Pred|LObjects],

   get_positive_examples(LPos),
   deal_with_examples(Pred, LPos, LObjects, Stream_pos, Stream_obj, Stream_typ),
   nl(Stream_obj),
   nl(Stream_obj),

   get_negative_examples(LNeg),
   deal_with_examples(Pred, LNeg, LObjects, Stream_neg, Stream_obj, Stream_typ),

   close(Stream_obj),
   close(Stream_pos),
   close(Stream_neg),
   close(Stream_typ).


get_positive_examples(LPos) :-
   findall(Ex, bk:pos(_N,Ex), LPos).

get_negative_examples(LNeg) :-
   findall(Ex, bk:neg(_N,Ex), LNeg).


	/* draw an example Ex in Lex and discard some atoms of Ex according to
	   Proba */
deal_with_examples(_, [], _LObjects, _, _, _) :-
   !.

deal_with_examples(Pred, [Ex|LEx], LObjects, Stream_ex, Stream_obj, Stream_typ) :-
   get_count(N),
   atom_number(Na, N),
   set_constants(LObjects, Na, LObjects1),
   Head =..[Pred|LObjects1],
   numbers_example(Ex, LObjects, LObjects1, Ex1),
   write_data(Ex1, Stream_obj),
   nl(Stream_obj),
   fwrite_point_ln(Stream_ex, Head),
   write_types(LObjects1, Stream_typ),
   deal_with_examples(Pred, LEx, LObjects, Stream_ex, Stream_obj, Stream_typ).


/* write the type object */
write_types([], _) :-
   !.

write_types([C|LC], Stream) :-
   fwrite_point_ln(Stream, object(C)),
   write_types(LC, Stream).

/* add N to the name of each constant */
set_constants([], _N, []) :-
   !.

set_constants([C|LC], N, [C1|LC1]) :-
   atom_concat(C, N, C1),
   set_constants(LC, N, LC1).


/* write the current ambiguous example */

write_data([], _Stream) :-
   !.

write_data([neg(_)|LAtom], Stream) :-
   !,
   write_data(LAtom, Stream).

write_data([Atom|LAtom], Stream) :-
   fwrite_point_ln(Stream, Atom),
   write_data(LAtom, Stream).

/* add N to each constant denoting an object */
numbers_example([], _LObjects, _LObjects1, []) :-
   !.

numbers_example([Atom|LAtom], LObjects, LObjects1, [Atom1|LAtom1]) :-
   numbers_atom(Atom, LObjects, LObjects1, Atom1),
   numbers_example(LAtom, LObjects, LObjects1, LAtom1).


numbers_atom(Atom, LObjects, LObjects1, Atom1) :-
   	Atom =..[Functor|LArgs],
   	replace_constants(LArgs, LObjects, LObjects1, LArgs1),
   	Atom1 =..[Functor|LArgs1].


/* In LArgs replace each constant of LObjects by the constant of same rank
   in LObjects1 */
replace_constants([], _, _, []) :-
   !.

replace_constants([C|LC], LObjects, LObjects1, [C1|LC1]) :-
   member(C, LObjects),
   nth1(Pos, LObjects, C),
   nth1(Pos, LObjects1, C1),
   !,
   replace_constants(LC, LObjects, LObjects1, LC1).

replace_constants([C|LC], LObjects, LObjects1, [C|LC1]) :-
   replace_constants(LC, LObjects, LObjects1, LC1).

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



