Inference of Calling Patterns and Program Transformation in Logic Programming
This document explores the inference of calling patterns for predicates in logic programming by determining the modes of arguments. It covers transition rules between modes and details how to infer types using built-in predicates such as `atom/1` and equality checks. Additionally, it explains program unfolding and folding techniques through examples like reversing lists (`rev/2`) and calculating distance in paths. The emphasis is on maintaining a common control structure while transforming programs, providing insight into the logic programming paradigm and its practical applications.
Inference of Calling Patterns and Program Transformation in Logic Programming
E N D
Presentation Transcript
Mode Inference Given the definition of a predicate p/N infer a calling pattern p(M1, …, MN) where each Mi is the mode of the appropriate argument. A mode can be one of the following: ‘v’ Always a variable ‘g’ Always a ground term ‘?’ Not determined ‘v’ or ‘g’ Transitions: gg ?? vv ?v ?g vg
Modes Are Given For Built-in Predicates ?g atom(X) ?g gg N is E ?? A = B
Inferring Modes = given gg ?g sum([], 0). sum([H|T], N) :- sum(T, NT), N is NT + 1. gg ?g gg vg ?g gg
Program Unfolding q([], []). q([H|T], R) :- t(H), q(T, R). p(L, R) :- q(L, X), r(X, R). p([], R) :- r([], R) p([H|T], R) :- t(H), q(T, X), r(X, R) unfold
Program Folding s(A, B) :- q(A,C), r(C,B). p(A, B) :- q(A, C), r(C, B), t(B). p(A, B) :- s(A, B), t(B). fold
Program Folding/Unfolding Example rev([], []). rev([H|T], R) :- rev(T, T1), append(T1, [H], R). append([], L, L). append([H|T], L, [H|R]) :- append(T, L, R). r_a(L, A, R) :- rev(L, L1), append(L1, A, R). r_a([], A, R) :- append([], A, R). r_a([H|T], A, R) :- rev(T, T1), append(T1, [H], L1), append(L1, A, R). unfold r_a([], A, R) :- append([], A, R). r_a([H|T], A, R) :- rev(T, T1), append(T1, [H|A], R). simplify r_a([], A, A). r_a([H|T], A, R) :- rev(T, T1), append(T1, [H|A], R). unfold r_a([], A, R). r_a([H|T], A, R) :- r_a(T, [H|A], R). fold
Preserving a Common Control Structure dist([X|_], X, 0). dist([H|T], X, D) :- dist(T, X, Dt), D is Dt + 1. path_dist(L, X, P, D) :- path(L, X, P), dist(L, X, D). path([X|_], X, []). path([H|T], X, [H|R]) :- path(T, X, R). unfold + fold path_dist([X|_], X, [], 0). path_dist([H|T], X, [H|R], D) :- path_dist(T, X, R, Dt), D is Dt + 1. What is wrong with this picture?
Preserving a Common Control Structure dist([X|_], X, 0). dist([H|T], X, D) :- dist(T, X, Dt), D is Dt + 1. path_dist(L, X, P, D) :- path(L, X, P), dist(L, X, D). path([X|_], X, []). path([H|T], X, [H|R]) :- path(T, X, R). unfold + fold path_dist([X|T], X, [], D) :- dist([X|T], X, D). path_dist([H|T], X, [H|R], D) :- path(T, X, R), dist([H|T], X, D). unfold + fold path_dist([X|T], X, [], 0). path_dist([X|T], X, [], D) :- dist(T, X, Dt), D is Dt + 1. path_dist([H|T], X, [H|R], D) :- path_dist(T, X, R, Dt), D is Dt + 1. path_dist([H|T], X, [H|R], D) :- path(T, X, R), dist([H|T], X, D).