Write a Prolog program to compute a Relational Algebra expression corresponding
to a single Datalog rule. You will implement the predicate processRule(A,P,N,C,Q),
where A is the argument list of the head predicate, P is a list of positive
sub-goals in the rule, N is a list of negative sub-goals in the rule, and
C is a list of comparison atoms in the rule and Q is the output Relational
Algebra Query for the head predicate (which is unnamed here).
We will assume that the argument list of the head predicate does not contain any constants.
As an example, consider the Datalog rule:
p(x,y) :- q(x,z), r(z,y), not s(x,20), z<20.
To find the Relational Algebra query for the head predicate p(x,y),
you will invoke the processRule oredicate as shown in the following
sample run:
2 ?- processRule([x,y],[[q,[x,z]],[r,[z,y]]],[[s,[x,20]]],[[z,<,10]],Q).
Q = "
project[x,y](
select[z<10](
rename[x,z](q) join rename[z,y](r) join
( (rename[x](project[x_0](rename[x_0,x_1](q))))
minus
rename[x](project[x_0](select[x_1=20](rename[x_0,x_1](s))))
)
)
)" .
3 ?- processRule([x,y],[[q,[x,z,"john"]],[r,[z,y,z,20]]],[[s,[y,20,x]]],[[z,<,10],[z,>,10]], Q).
Q = "
project[x,y](
select[z<10 and z>10](
rename[x,z](project[x_0,x_1](select[x_2='john'](rename[x_0,x_1,x_2](q))))
join
rename[y,z](project[x_1,x_2](select[x_3=20 and x_0=x_2](rename[x_0,x_1,x_2,x_3](r))))
join
( (rename[y](project[x_1](rename[x_0,x_1,x_2,x_3](r)))
times
rename[x](project[x_0](rename[x_0,x_1,x_2](q)))
)
minus
rename[y,x](project[x_0,x_2](select[x_1=20](rename[x_0,x_1,x_2](s))))
)
)
)" .
Handle multiple rules for the same predicate; Implement the predicate
processRules(P,R,Q), where P is the predicate name, R is a list of rules that define the
predicate and Q is the Relational Algebra query for predicate P.
The following is a sample run:
4 ?- processRules(p,[[[x,y],[[q,[x,y]]],[],[]],[[x,y],[[q,[x,z]],[r,[z,y]]],[],[]]],Q).
Q = "project[x,y](rename[x,y](q)) union project[x,y](rename[x,z](q) join rename[z,y](r))" .