:- export call_all/1, scanVars/3.
:- export delete_all/1, deletelist/1, getlist/3, getbag/3, if/3, append/3.
:- export on_backtracking/1, insertbase/1, deletebase/1, inserting/1, deleting/1.
:- export insertlist/1, dynpred/1.
:- export insert_file/1, write_pred/1.
:- import assert/1 from assert.

append([],L1,L2) :- L2 = L1.
append([H|L],L1,[H2|L2]) 
	:- append(L,L1,L2),
	   H2 = H.

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(asserta(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^Fun2,List) -> true
	;
	List = []).
getbag(Fun1,Fun2,List) :-
	(
	bagof(Fun1,Fun2^Fun2,List) -> true
	;
	List = []).

/* to be modified */
dynpred(X) :- dynamic(X).
if(X,Y,_) :- call(X) , call(Y).
if(X,_,Z) :- not(X),   call(Z).
/* end */

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


write_pred(X) :- write_canonical(X).

insert_file(FileName) :-
	seeing(X),
	see(FileName),
	read_and_add_line,
	see(X).

read_and_add_line :-
	read(Line),
	(
	(Line == end_of_file)	-> true
	;
	assert(Line),
	read_and_add_line ).


/*

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).

*/
