One can write this SQL statement in DES and see its translation to (an extension of) Datalog:
DES> /show_compilations on
DES> WITH RECURSIVE temp (n, fact) AS
(SELECT 0, 1 -- Initial Subquery
UNION ALL
SELECT n+1, (n+1)*fact FROM temp -- Recursive Subquery
WHERE n < 9)
SELECT * FROM temp;
Info: SQL statement compiled to:
answer(A,B) :-
temp(0,1)
/\
(temp(C,D) :-
temp(E,F),
E<9,
C=E+1,
D=(E+1)*F)
=>
temp(A,B).
answer(temp.n:int,temp.fact:int) ->
{
answer(0,1),
answer(1,1),
answer(2,2),
answer(3,6),
answer(4,24),
answer(5,120),
answer(6,720),
answer(7,5040),
answer(8,40320),
answer(9,362880)
}
Info: 10 tuples computed.
Curiously, this translation uses hypothetical reasoning for solving the CTE (Common Table Expression in SQL jargon for referring to the local view declaration). This translation was made for the sake of experimenting with this kind of reasoning, where the fact temp(0,1)
and the rule temp(C,D) :- temp(E,F), E<9, C=E+1, D=(E+1)*F
are assumed in order to solve the goal temp(A,B)
(the symbol =>
is known as embedded implication in hypothetical Datalog). Note also that, since terms are not allowed, a goal such as C=E+1
in this particular system evaluates the arguments of the equality before unifying them.
The more expected translation of the original SQL statement is got from another (quasi) equivalent formulation:
DES> CREATE VIEW temp (n, fact) AS
(SELECT 0, 1 -- Initial Subquery
UNION ALL
SELECT n+1, (n+1)*fact FROM temp -- Recursive Subquery
WHERE n < 9);
Info: SQL statement compiled to:
temp(0,1).
temp(A,B) :-
temp(C,D),
C<9,
A=C+1,
B=(C+1)*D.
This SQL syntax for recursive queries seems (to me) more natural, though a view must be created for the self-reference. It is not supported in the standard.
We have proposed students to solve SQL puzzles for fun, and wrote a paper around this:
Experiencing Intuitionistic Logic Programming in SQL Puzzles