% |
% This file contains the source code for the second optimization, |
% which implements the algorithm for query compilation |
% |
:- import updat/1 from updates. |
:- import append/3 from basics. |
% define directive opt2_trans |
opt2_trans(File_ctr) :- |
in_opt2(File_ctr,File1), |
see(File1), |
remove_upd1, |
insert_upd1(Preds), |
remove_graph1, |
remove_db_pred, |
opt_read_and_create_graph1(File1), |
seen, |
see(File1), |
out_opt2(File_ctr,FileOut2), |
unix('rm -f FileOut2 2>/dev/null', R1), |
tell(FileOut2), |
opt_read_and_compile2(File1,FileOut2), |
seen, told, |
opt_insert_file(FileOut2), |
see(File1), |
out_db(File_ctr,FileOut), |
unix('rm -f FileOut 2>/dev/null', R1), |
tell(FileOut), |
opt_read_and_compile1(File1,FileOut), |
seen, told, |
opt_insert_file(FileOut). |
% parse transaction base rules repeatedly |
% to create dependency graph |
opt_read_and_create_graph1(FileIn) :- |
read(Term), |
( |
(Term == end_of_file) -> true |
; |
opt_read_rule1(Term,FileIn), |
opt_read_and_create_graph1(FileIn) ). |
% read transaction base object file and write |
% optimized object database file |
opt_read_and_compile1(FileIn,FileOut) :- |
read(Term), |
( |
(Term == end_of_file) -> true |
; |
opt_read_and_write_rule1(Term,FileIn,FileOut), |
opt_read_and_compile1(FileIn,FileOut) ). |
% read transaction base object file and write |
% optimized transaction-base object file |
opt_read_and_compile2(FileIn,FileOut) :- |
read(Term), |
( |
(Term == end_of_file) -> true |
; |
opt_read_and_write_rule2(Term,FileIn,FileOut), |
opt_read_and_compile2(FileIn,FileOut) ). |
% determine edges from transaction base rules |
opt_read_rule1(':-'(trans(Lhs),Rhs),_) :- |
Lhs =..Lname, |
Lname = [Name|_], |
insert_edge1(Name, Rhs). |
opt_read_rule1(':-'(Lhs,Rhs),_). |
% write optimized rules in database file |
opt_read_and_write_rule1(':-'(trans(Lhs),Rhs),_,_) :- |
Lhs =..LLhs, |
LLhs = [Name|_], |
check_pred(Name), |
opt(Lhs, Rhs, PRhs), |
create_trans_db(Lhs, NLhs), |
write(NLhs), |
write(' :- '), |
(islist(PRhs), |
write_list(PRhs) |
; |
create_trans_db(PRhs, NPRhs), |
write(NPRhs), |
write('.')), |
nl, |
write(NLhs), |
write(' :- '), |
write(Lhs), |
write('.'), |
nl, |
(islist(PRhs), |
write_list_pred_rules(PRhs) |
; |
(updat(PRhs), |
create_trans_db(PRhs, NRhs), |
write(NRhs), |
write(' :- '), |
write(PRhs), |
write('.'), nl |
; |
not(updat(PRhs)))). |
opt_read_and_write_rule1(':-'(Lhs,Rhs),_,_). |
% write optimized rules in transaction base file |
opt_read_and_write_rule2(':-'(trans(Lhs),Rhs),_,_) :- |
check_ref(Lhs), |
write(trans(Lhs)), |
write(' :- '), |
optT(Rhs, PR, PRhs), |
write(PRhs), |
write('.'), nl, |
(islist(PR), |
write_list_pred_trans(PR) |
; |
(updat(PR), |
create_trans_db(PR, NR), |
write(trans(NR)), |
write(' :- '), |
write(PR), |
write('.'), nl |
; |
not(updat(PR)))). |
opt_read_and_write_rule2(':-'(trans(Lhs),Rhs),_,_) :- |
write(trans(Lhs)), |
write(' :- '), |
optT(Rhs, PR, PRhs), |
write(PRhs), |
write('.'), nl. |
opt_read_and_write_rule2(':-'(Lhs,Rhs),_,_) :- |
write(Lhs), |
write(' :- '), |
write(Rhs), |
write('.'), nl. |
opt(Lhs, Rhs, PRhs) :- not(iref1(Lhs,_)), |
not(dref1(Lhs,_)), |
remove_op(Rhs, PRhs). |
% translate CTR terms into Prolog terms |
optT(isolate(P), PR, R) :- not(iref1(P,_)), |
not(dref1(P,_)), |
remove_op(isolate(P), PR), |
(islist(PR), |
create_ctr_list(PR, NPR), |
conv(NPR, R, ',') |
; |
PR =..LPR, |
LPR = [Name|_], |
assert(db_pred(Name)), |
create_trans_db(PR, NPR), |
conv_one([NPR], R, '')). |
optT(isolate(P), PR, isolate(R)) :- optT(P, PR, R). |
optT(isolate1(P), PR, R) :- not(iref1(P,_)), |
not(dref1(P,_)), |
remove_op(isolate1(P), PR), |
(islist(PR), |
create_ctr_list(PR, NPR), |
conv(NPR, R, ',') |
; |
PR =..LPR, |
LPR = [Name|_], |
assert(db_pred(Name)), |
create_trans_db(PR, NPR), |
conv_one([NPR], R, 'call')). |
optT(isolate1(P), PR, isolate1(R)) :- optT(P, PR, R). |
optT(seq(L), PR, seq(L1)) :- optT_list(L, PR, L1). |
optT(conc(L), PR, conc(L1)) :- optT_list(L, PR, L1). |
optT(conc1(L), PR, conc1(L1)) :- optT_list(L, PR, L1). |
optT(P, PR, P). |
optT_list([], PR, []). |
optT_list(L, PR, L1) :- L = [H0|Tail0], |
L1 = [H1|Tail1], |
optT(H0, PR, H1), |
optT_list(Tail0, PR, Tail1). |
% create translated clauses |
remove_op(isolate(P), R) :- remove_op(P, R). |
remove_op(isolate1(P), R) :- remove_op(P, R). |
remove_op(seq(L), R) :- proc_list(L, R). |
remove_op(conc(L), R) :- proc_list(L, R). |
remove_op(conc1(L), R) :- proc_list(L, R). |
remove_op(P, P). |
proc_list([], []). |
proc_list(L, L1) :- L = [H0|Tail0], |
L1 = [H1|Tail1], |
remove_op(H0, H1), |
proc_list(Tail0, Tail1). |
% build dependency graph |
insert_edge1(Name, Rhs) :- appears(Rhs, X), |
not(edge1(Name, X)), |
not(Name = X), |
assert(edge1(Name, X)), |
fail. |
insert_edge1(Name, Rhs). |
insert_upd1(Preds) :- updat(Preds), |
Preds =..Lpreds, |
Lpreds = [Name|_], |
assert(upd(Name)), fail. |
insert_upd1(Preds). |
% determine nodes for dependency graph |
appears(conc(L), X) :- L = [Head|_], |
appears(Head, X). |
appears(conc(L), X) :- L = [_|Tail], |
appears(conc(Tail), X). |
appears(conc1(L), X) :- L = [Head|_], |
appears(Head, X). |
appears(conc1(L), X) :- L = [_|Tail], |
appears(conc1(Tail), X). |
appears(seq(L), X) :- L = [Head|_], |
appears(Head, X). |
appears(seq(L), X) :- L = [_|Tail], |
appears(seq(Tail), X). |
appears(isolate1(E), X) :- !, appears(E, X). |
appears(isolate(E), X) :- !, appears(E, X). |
appears(ins(X), Y) :- !, X =..Pred, |
Pred = [Name|_], |
Y = ins(Name). |
appears(del(X), Y) :- !, X =..Pred, |
Pred = [Name|_], |
Y = del(Name). |
appears(P, Y) :- P =..Pred, |
Pred = [Name|_], |
not(Name = conc), |
not(Name = conc1), |
not(Name = seq), |
not(Name = isolate), |
not(Name = isolate1), |
atom(Name), |
Y = Name. |
% find connected nodes in dependency graph |
reachable1(P, P). |
reachable1(P, Q) :- edge1(P, Q). |
reachable1(P, Q) :- edge1(P, R), reachable1(R, Q). |
% query sets definition |
qref1(Q, Q) :- Q =..Pred, |
Pred = [Name|_], |
upd(Name). |
qref1(E, Q) :- appears(E, P), reachable1(P, Q), upd(Q). |
qref2(E, Q) :- appears(E, P), reachable1(P, Q). |
% insert sets definition |
iref1(ins(Q), Q). |
iref1(E, Q) :- appears(E, P), reachable1(P, ins(Q)). |
% delete sets definition |
dref1(del(Q), Q). |
dref1(E, Q) :- appears(E, P), reachable1(P, del(Q)). |
% cleanup before the algorithm begins |
remove_upd1 :- retract(upd(X)), fail. |
remove_upd1. |
remove_db_pred :- retract(db_pred(X)), fail. |
remove_db_pred. |
% delete any previously created dependency graph |
remove_graph1 :- retract(edge1(X, Y)), fail. |
remove_graph1. |
remove_dep1 :- retract(dep(1)). |
remove_dep1. |
remove(K) :- retract(dep(K)). |
remove(K). |
% create file names for input object files |
in_opt2(FileIn,FileOut) :- |
name(FileIn,NameIn), |
append(NameIn,".opt1.o",NameOut), |
name(FileOut,NameOut). |
% create file names for output optimized files |
out_db(FileIn,FileOut) :- |
name(FileIn,NameIn), |
append(NameIn,".opt2.db",NameOut), |
name(FileOut,NameOut). |
out_opt2(FileIn,FileOut) :- |
name(FileIn,NameIn), |
append(NameIn,".opt2.o",NameOut), |
name(FileOut,NameOut). |
% load optimized rules in database |
opt_insert_file(FileName) :- |
seeing(X), |
see(FileName), |
opt_read_and_add_line, |
see(X). |
opt_read_and_add_line :- |
read(Line), |
( |
(Line == end_of_file) -> true |
; |
assert(Line), |
opt_read_and_add_line ). |
% build new predicate names for database optimized file |
create_trans_db(monitor(Lhs), monitor(NLhs)) :- |
not(islist(Lhs)), |
Lhs =..X, |
X = [Head|Tail], |
not(Head = conc), |
not(Head = conc1), |
not(Head = seq), |
not(Head = isolate), |
not(Head = isolate1), |
name(Head, NameHead), |
append(NameHead,"_ctr_db", OutHead), |
name(NewName, OutHead), |
Y = [NewName|Tail], |
NLhs =..Y. |
create_trans_db(Lhs, NLhs) :- |
not(islist(Lhs)), |
Lhs =..X, |
X = [Head|Tail], |
not(Head = conc), |
not(Head = conc1), |
not(Head = seq), |
not(Head = isolate), |
not(Head = isolate1), |
name(Head, NameHead), |
append(NameHead,"_ctr_db", OutHead), |
name(NewName, OutHead), |
Y = [NewName|Tail], |
NLhs =..Y. |
% translate rules for database optimized file |
create_ctr_list([], []). |
create_ctr_list(PR, NPR) :- flatten(PR, LR), |
LR = [Head|Tail], |
assert(db_pred(Head)), |
NPR = [Head1|Tail1], |
create_trans_db(Head, Head1), |
create_ctr_list(Tail, Tail1). |
write_list([]). |
write_list(L) :- L = [Head|Tail], |
create_trans_db(Head, NHead), |
write(NHead), |
(Tail = [], |
write('.') |
; |
write(',')), |
L1 = Tail, |
write_list(L1). |
%write new rules in optimized database file |
write_list_pred_rules([]). |
write_list_pred_rules(L) :- L = [Head|Tail], |
updat(Head), |
create_trans_db(Head, NHead), |
write(NHead), |
write(' :- '), |
write(Head), |
write('.'), |
nl, |
L1 = Tail, |
write_list_pred_rules(L1). |
write_list_pred_rules(L) :- L = [Head|Tail], |
not(updat(Head)), |
L1 = Tail, |
write_list_pred_rules(L1). |
write_list_pred_trans([]). |
write_list_pred_trans(L) :- L = [Head|Tail], |
updat(Head), |
create_trans_db(Head, NHead), |
write(trans(NHead)), |
write(' :- '), |
write(Head), |
write('.'), |
nl, |
L1 = Tail, |
write_list_pred_trans(L1). |
write_list_pred_trans(L) :- L = [Head|Tail], |
not(updat(Head)), |
L1 = Tail, |
write_list_pred_trans(L1). |
islist([]). |
islist([_|_]). |
conv([], [],_). |
conv([First|Tail], NewList, Functor) :- |
(not(Tail = []), |
NewList =..[Functor, First, NewTail] |
; |
NewList = First, |
NewTail = []), |
conv(Tail, NewTail, Functor). |
conv_one([El], NewEl, F1) :- |
NewEl =..[F1, El]. |
flatten([], []). |
flatten([Head|Tail], FlatList) :- flatten(Head, FlatHead), |
flatten(Tail, FlatTail), |
append(FlatHead, FlatTail, FlatList), !. |
flatten(X, [X]). |
check_ref(Lhs) :- iref1(Lhs,_). |
check_ref(Lhs) :- dref1(Lhs,_). |
check_pred(Name) :- db_pred(Name). |
check_pred(Name) :- db_pred(Y), |
qref2(Y, Name). |
edge1(dummy, dummy) :- fail. |
modifiable(dummy) :- fail. |
upd(dummy) :- fail. |
dep(dummy) :- fail. |
db_pred(dummy) :- fail. |