:- export call_all/1, scanVars/3, init_basic/0, toggle_mode/0, trmode/1.
:- export delete_all/1, deletelist/1, getlist/3.
:- export on_backtracking/1, insertbase/1, deletebase/1, inserting/1, deleting/1.
:- export ins_name/2, del_name/2, insertedname/2, key_name/3, val_name/3, index_list/2,
   deletedname/2, dbname/2, dynpred/1.
:- export insertlist/1.
:- import retract/1, assert/1 from assert.
:- import append/3 from basics.

:- op(710,fx,[not]).

init_basic :- assert(trmode(compile)).

% define not
%
not(X) :- call(X), !, fail
	  ;
	  true.

toggle_mode :-
	retract(trmode(compile)),
	assert(trmode(database)).
toggle_mode :-
	retract(trmode(database)),
	assert(trmode(compile)).

call_all([]).
call_all([Pred|Rest]) :-
	call(Pred),
	call_all(Rest).

delete_all(Value) :-
	getlist(Value,Value,List), !,
	deletelist(List).
deletelist([]).
deletelist([Pred|Rest]) :-
	deletebase(Pred),
	deletelist(Rest).

% weak assert and retract X with backtracking.
%
inserting(X) :-
	assert(X), on_backtracking(retract(X)).
deleting(X) :-
	call(X) ->
		(
		retract(X), on_backtracking(assert(X)) )
	;
	true.

insertbase(X) :- assert(X), !, on_backtracking((retract(X))).
deletebase(X) :- retract(X), !, on_backtracking((asserta(X))).

on_backtracking(_).
on_backtracking(X) :-
	call(X), !, fail.

% Same as built-in predicate findall except that it is always true.
%
getlist(Fun1,Fun2,List) :-
	(
	setof(Fun1,Fun2,List) -> true
	;
	List = []).




scanVars([],X,X).
scanVars([X|L],InList,OutList) :-
	var(X),
	checkrepeat(X,InList,InList,NewList),
	scanVars(L,NewList,OutList).
scanVars([X|L],InList,OutList) :-
	atomic(X), nonvar(X),
	scanVars(L,InList,OutList).
scanVars([X|L],InList,OutList) :-
	not atomic(X), 
	X =.. [_|MoreArgs],
	scanVars(MoreArgs,InList,NewList),
	scanVars(L,NewList,OutList).

checkrepeat(X,[],List,[Y|List]) :-
	Y = X.

checkrepeat(X,[Y|_],List,List) :-
	X == Y.
checkrepeat(X,[Y|L],List,List2) :-
	X \== Y, 
	checkrepeat(X,L,List,List2).


index_list(NArgs,IdList) :-
	name(NArgs,NAList),
	append(NAList,"_",IdList).
key_name(BeforeName,IdList,KeyName) :-
	name(BeforeName,NList),
	append(IdList,NList,IdNList),
	append("key_",IdNList,VList),
	name(KeyName,VList).
val_name(Before,IdList,ValName) :-
	name(Before,NList),
	append(IdList,NList,IdNList),
	append("val_",IdNList,VList),
	name(ValName,VList).	
ins_name(Name,InsName) :-
	name(Name,NameList),
	append("ins_",NameList,InsList),
	name(InsName,InsList).
del_name(Name,DelName) :-
	name(Name,NameList),
	append("del_",NameList,DelList),
	name(DelName,DelList).
insertedname(Name,IName) :-
	name(Name,NameList),
	append("i_",NameList,IList),
	name(IName,IList).
deletedname(Name,DName) :-
	name(Name,NameList),
	append("d_",NameList,DList),
	name(DName,DList).
dbname(Name,DBName) :-
	name(Name,NameList),
	append("db_",NameList,DBList),
	name(DBName,DBList).

dynpred(X) :- dynamic(X).

insertlist([]).
insertlist([H|L]) :-
	insertbase(H),
	insertlist(L).

deletelist([]).
deletelist([H|L]) :- deletebase(H),  deletelist(L).


