/* *********************************************************
        upload module
********************************************************** */

:- export loadbase/1, loadtrans/1.
:- import append/3 from basics.
:- import write_new_rules/0, parse_body/3 from parser3.
:- import declare/1 from keys_basics3.
:- import set_n_create/1 from keys_appl3.
:- import insert_file/1, write_pred/1, insertbase/1 from basic_funs3.

:- op(800,xfy,[while,forall]).
:- op(800,fx,[while,forall,if]).
:- op(770,fx,[unique,possible]).
:- op(750,fx,[with]).
:- op(750,xfy,[do,then,else]).
:- op(720,xfy,[in]).
:- op(1000,xfy,[sc]).
:- op(1000,xfy,[conj]).
:- op(1130,xfy,[<-]).  

% upload a program into transaction base.
%
loadtrans(File) :-  
		see(File), 
	      	out_filename(File,FileOut),	
	        tell(FileOut), 
		repeat_read_and_compile(File,FileOut),
		write_new_rules,
		seen, told, 
		insert_file(FileOut).

/* parsing rules repeatedly */
repeat_read_and_compile(FileIn,FileOut) :-
	read(Term),
	(
	(Term == end_of_file) -> true
	;
	read_and_write_rule(Term,FileIn,FileOut), 
	repeat_read_and_compile(FileIn,FileOut)  ).


/* parse rule if it has body 
*/
/* translation of declare statement */
read_and_write_rule(declare(Term),FileIn,FileOut) :-
	declare(Term), see(FileIn), tell(FileOut).

/* translation of a clause */
read_and_write_rule('<-'(Lhs,Rhs),_,_) :-
	write_pred(Lhs),
	write(' :- tr, '),
	parse_body(Rhs,PRhs,transaction),
	write_pred(PRhs),
	write('.'), nl.

/* translation of a transaction atom */
read_and_write_rule(Term,_,_) :-
	not(Term = declare(_)),
	not(Term = '<-'(_,_)),
	write_pred(Term), write(' :- tr.'), nl.


% upload a program into database.
% (similar to load_dyn)
loadbase(File) :- 
		see(File),
		read(Term),
		load_a_line(Term,File),
		seen.

% declare a new tuple
load_a_line(declare(Term),File) :-
		declare(Term),
		see(File),
		read(Next), !,
		load_a_line(Next,File).

% insert a clause to database
load_a_line((Lhs :- Rhs),File) :-
		insertbase((Lhs :- dbase(Rhs))),
		read(Next), !,
		load_a_line(Next,File).

% insert a new tuple to database
load_a_line(Term,File) :-
		not(Term = declare(_)),
		read_and_assert(Term,File).

% insert a new tuple(by create)
read_and_assert(Term,File) :-
		(Term == end_of_file), !, true
		;
		set_n_create(Term), 
		read(Next), !,
		load_a_line(Next,File).

% change the name into name_tran for output file
out_filename(FileIn,FileOut) :-
        name(FileIn,NameIn),
        append(NameIn,"_tran",NameOut),
        name(FileOut,NameOut).

