:- dynamic backend/1, showatom/2.

backend(dlv).

%%% loading files %%%%%%%%%%%%%%%%

loadfile(F,T):-see(F), read_clauses([],T), seen.

read_clauses(L1,L):- read(C),(
      C=end_of_file,!,L=L1
    ; append(L1,[C],L2),
      read_clauses(L2,L)
    ).

showatom(A,A) :- A=.. [F|_], \+ concat_atom(['aux_',_],F).

%%% lparse %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

get_solutions_lparse(Ms) :-
	gettoken([10],T,_),!,
    (T='False',!,Ms=[]
    ;T='True',!,Ms=[]
    ;gettoken([0':],_,_), % remove text 'Stable Model:',
     get0(_),             % remove blank
     get_solution_lparse(M),
	 get_solutions_lparse(Ms0), Ms=[M|Ms0]
).

get_solution_lparse(M) :-
	gettoken([0' ,10],T,D), 
	D=0' ,!,
	atom_to_term(T,Term,_),
	get_solution_lparse(M0),
	(showatom(Term,Term1),!,M=[Term1|M0]
	; M=M0
	).
get_solution_lparse([]).	

%%% dlv %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

get_solutions_dlv([M|Ms]) :-
    get0(C),C=0'{,!,    % new solution
	get_solution_dlv(M),
	gettoken([10],_,_), % remove up to breakline
	get_solutions_dlv(Ms).
get_solutions_dlv([]).	
	
get_solution_dlv(M):-
	gettoken([0' ,0'}],T,D),
	( T='',!,M=[]     % empty model (no facts)
	; D=0' ,!,
	  % remove last ',' from atom
	  atom_codes(T,Cs),append(Cs2,[0',],Cs),atom_codes(T2,Cs2),
	  atom_to_term(T2,Term,_),
	  get_solution_dlv(M0),
	  ( showatom(Term,Term1),!,M=[Term1|M0]
	  ; M=M0)
	; % D=0'},
	  atom_to_term(T,Term,_),
	  ( showatom(Term,Term1),!,M=[Term1]
	  ; M=[]
	  )
).

%%%%%%%%%%%%%%%%%%
% Get the answer sets Ms using Backend={lparse, dlv}, program P, maximum number N of answer sets
% using auxiliary files Fs

answersets(P,N,Ms) :- answersets(P,[],N,Ms).
answersets(P,Fs,N,Ms) :-
	backend(Backend),
	tell('in.tmp'),
	write_lines(P),
	told,
	insert_blanks(Fs,Fs1),
	concat_atom(Fs1,Fs2),
	( Backend=lparse,!,
	  concat_atom(['lparse in.tmp ',Fs2,' | smodels ',N,' > out.tmp'],Command),
	  shell(Command,_),
	  see('out.tmp'),
      gettoken([10],_,_), % remove first line
	  get_solutions_lparse(Ms),
	  seen
    ; Backend=dlv,!,
      concat_atom(['dlv -silent -n=',N,' in.tmp ',Fs2,'> out.tmp '],Command),
	  shell(Command,_),
	  see('out.tmp'),
	  get_solutions_dlv(Ms),
	  seen
	).

%%%% Auxiliary predicates

write_lines([]):-!.
write_lines([R|Rs]) :- write(R),write('.'),nl,write_lines(Rs).

gettoken(Delims,Tok,Delim):-
	gettokenchars(Delims,Chars,Delim),
	atom_codes(Tok,Chars).

gettokenchars(Delims,Cs,Delim):-
	get0(C),!,
	( C = -1,!,fail
	; member(C,Delims),!,Delim=C,Cs=[]  
	; gettokenchars(Delims,Cs0,Delim), Cs=[C|Cs0]
	).

insert_blanks([],[]):-!.
insert_blanks([A|As],[A,' '|Bs]):-insert_blanks(As,Bs).
