/* Parses a Logic Program with Annotated Disjunctions
   to an Independent Choich Logic program.
   
   Input:
      (h1 : a1) v ... v (hn : an) <- b1 & ... & bm.

   Output:
   
      h1 :- b1, ... bm, choice_rule_NB( ... , 1).
         ...
      hn :- b1, ... bm, choice_rule_NB( ... , n).
   
      disjoint([choiche_rule_NB( ... , 1) : a1, 
                     ... , 
                choiche_rule_NB( ... , n) : an]).
*/

?- use_module(library(lists)).
?- use_module(library(terms)).

:- op(100, xfx, v).
:- op(200, xfx, :).
:- op(1060, xfy, [ & ]).
:- op(900,fy, ~).
:- op(700,xfx, \=).
:- op(1150, xfx, <- ).


/* OutFile contains the ICL-translation of the LPAD-clauses in InFile. */

parse(InFile, OutFile) :- open(InFile, read, InStream), open(OutFile, write, OutStream), parse2(InStream, OutStream, 1).

/* Translates the ClauseNb-th clause from InStream to OutStream. */

parse2(InStream, OutStream, ClauseNb) :- read(InStream, Clause), ClauseNbPP is ClauseNb + 1,
	(
	  (Clause = end_of_file) 
	->
	  write('done.')
	;
	  icl_code(Clause, ICL, ClauseNb), print_list_to(ICL, OutStream), parse2(InStream, OutStream, ClauseNbPP)
	).
			
/* icl_code(+Clause, -List_Of_ICL_Clauses, +ClauseNb)
   Creates the list of ICL-clauses corresponding to an LPAD-rule. */

/* Case: Real clause. */
icl_code((Head <- Body), Out, Count) :- !, icl_code2(Head, Body, Out, Count).

/* Case: Fact. */
icl_code(Head, Out, Count) :- icl_code2(Head, true, Out, Count).


/* icl_code2(+Head, +Body, -Out, +ClauseNb) */
icl_code2(Head, Body, Out, ClauseNb) :-
	term_variables((Head :- Body), Vars), append([choice,
						      ClauseNb], Vars,
						     Switch),
	icl_for_rule(Head, 1, Body, Switch, Out_rules, Out_disj),
	append([random(Out_disj)], Out_rules, Out).


/* icl_for_rule(+Head, +NbOfChoices, +Body, +DisjointVariable,
/* -Clauses, -DisjointList). */
icl_for_rule((H_i : A_i) v Rest,
	     ChoiceNb, Body, PartOfSwitch,
	     [(H_i <- Body & Switch) | Other_clauses],
	     [(Switch : A_i) | OtherDisj]) :-
	!, append(PartOfSwitch, [ChoiceNb], SwitchL), Switch =.. SwitchL,
	ChoiceNbPP is ChoiceNb + 1,
	icl_for_rule(Rest, ChoiceNbPP, Body, PartOfSwitch, Other_clauses, OtherDisj).

icl_for_rule((H_i : A_i),
	     ChoiceNb, Body, PartOfSwitch,
	     [(H_i <- Body & Switch)],
	     [(Switch : A_i)]) :- 
	!, append(PartOfSwitch, [ChoiceNb], SwitchL), Switch =.. SwitchL.


icl_for_rule(H_i,_,Body,_,[(H_i :- Body)],[]).

print_list_to([L|Ls], Str) :- 
	write(Str, L), write(Str, '.\n'),  print_list_to(Ls, Str).

print_list_to([], _).










