/* **************************************************************
	Query module 
**************************************************************** */

:- export trans/1.
:- import retract/1 from assert.
:- import append/3 from basics.
:- import parse_body/3, write_new_rules/0 from parser3.
:- import keyedlist/1 from keys_basics3.
:- import bulk_del/1 from keys_appl3.
:- import deletelist/1, getlist/3, inserting/1, deleting/1 from basic_funs3.
:- import createpreds/2 from tr_basics3.
:- import index_list/2 from naming3.

:- op(1180,fx,[trans]).

trans(X) :- 
	cleanup, !,
	parse_body(X,L,query),
	write_new_rules,
	assert((query :- L)), !,
	inserting(tr), call(L), deleting(tr).



% remove some useless rules from database
%
cleanup :-
	retract((query :- _)),
	cleanup.
cleanup :-
	cleanup_temp,		% remove temperory rules and predicates
	keyedlist(KList),
	clean_keyedlist(KList). % clean up tuples which are deleted


% remove temperory rules and predicates
cleanup_temp :-
	retract(templist(TList)),
	retract(looplist(LList)),
	clean_templist(TList),	% remove temperory predicates
	clean_looplist(LList),	% remove temperory rules
	assert(looplist([])),
	assert(templist([])).	


% remove all tuples in the database according to the input list
clean_templist([]).
clean_templist([Temp|Rest]) :-
	bulk_del(Temp),
	clean_templist(Rest).


% remove all rules in the database with the head in the input list
clean_looplist([]).
clean_looplist([Pred|Rest]) :-
	remove_all(Pred),
	clean_looplist(Rest).

remove_all(Pred) :-
	copy_term(Pred,Copy),
	retract((Copy :- _)),
	remove_all(Pred).
remove_all(_).

% look for tuples which are deleted and remove the tags from the database
clean_keyedlist([]).
clean_keyedlist([(Name,NArgs,NKeys)|List]) :-
	name(Name,NList),
	index_list(NArgs,IdList),
	append(IdList,NList,IdNList),
	append("i_key_",IdNList,IList),
	append("d_key_",IdNList,DList),
	name(IName,IList),
	name(DName,DList),
	createpreds(NKeys,Args),
	IPred =.. [IName|Args],
	DPred =.. [DName|Args],
	clean_pred(IPred,DPred),
	clean_keyedlist(List).

% remove predicates with both insert and delete tags
clean_pred(IPred,DPred) :-
	getlist(IPred,DPred,List), !,
	retractall(DPred),
	deletelist(List)
	;
	true.
	
