% Reifying clauses % Transforming clauses from Prolog representation to % explicit terms and propositions % Author: Frank Pfenning % reify(Pred/Arity, D) if D is the explicit representation of Pred/Arity reify(Pred/Arity, D) :- fresh_vars(Arity, Xs), P =.. [Pred|Xs], findall((P :- B), clause(P, B), Clauses), reify_clauses(Clauses, D). % reify_goal(A, G, N) if G is explicit represenation of query A % containing N-1 free variables var(1),...,var(n-1) reify_goal(A, GRho, N) :- reify_prop(A, G, 1, N), bound_to_free(1, N, Rho), apply_prop(G, Rho, GRho). % reify_clauses(Clauses, D) reify_clauses([], top). reify_clauses([(P :- B)|Clauses], and(D1, D2)) :- reify_clause((P :- B), D1), reify_clauses(Clauses, D2). % reify_clause(Clause, D) reify_clause((P :- B), D) :- reify_prop(P, Q, 1, N2), reify_prop(B, G, N2, N3), quantify_upto(1, N3, implies(G, Q), D). % reify_prop(A, G, N1, N2) if G is the reified form of A % using variables bd(N1), ..., bd(N2-1) reify_prop(true, top, N, N) :- !. reify_prop((A1 , A2), and(G1, G2), N1, N3) :- !, reify_prop(A1, G1, N1, N2), reify_prop(A2, G2, N2, N3). reify_prop(fail, bot, N, N) :- !. reify_prop((A1 ; A2), or(G1, G2), N1, N3) :- !, reify_prop(A1, G1, N1, N2), reify_prop(A2, G2, N2, N3). reify_prop((T1 = T2), equal(S1, S2), N1, N3) :- !, reify_term(T1, S1, N1, N2), reify_term(T2, S2, N2, N3). reify_prop(P, Q, N1, N2) :- reify_term(P, Q, N1, N2). % reify_term(T, S, N1, N2) if S is the reified form of T % using variables bd(N1), ..., bd(N2-1) reify_term(T, S, N1, N3) :- var(T), !, T = '\$VAR'(N1), % inst to next variable N2 is N1+1, reify_term(T, S, N2, N3). reify_term('\$VAR'(M), var(bd(M)), N, N) :- % recognize earlier variable !. reify_term(T, app(T, []), N, N) :- integer(T), !. reify_term(T, app(F, Ss), N1, N2) :- T =.. [F|Ts], reify_terms(Ts, Ss, N1, N2). reify_terms([], [], N, N). reify_terms([T|Ts], [S|Ss], N1, N3) :- reify_term(T, S, N1, N2), reify_terms(Ts, Ss, N2, N3). % quantify_upto(N, M, D0, D) if D = forall(bd(N),...forall(bd(M-1), D0)) quantify_upto(N, N, D0, D0). quantify_upto(N, M, D0, forall(bd(N), D)) :- N < M, N1 is N+1, quantify_upto(N1, M, D0, D). % fresh_vars(N) = [_X1,...,_Xn], _Xi fresh fresh_vars(0, []). fresh_vars(N, [_X|Xs]) :- N > 0, N1 is N-1, fresh_vars(N1, Xs). % bound_to_free(N, M, Theta) if Theta = [var(N)/bd(N),...var(M-1)/bd(M-1)] bound_to_free(N, N, []). bound_to_free(N, M, [for(var(N),bd(N)) | Theta]) :- N < M, N1 is N+1, bound_to_free(N1, M, Theta).