80 likes | 234 Views
Mode Inference. Given the definition of a predicate p/N infer a calling pattern p(M 1 , …, M N ) where each M i 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’.
E N D
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).