| Computational Logic |
| Efficiency Issues in Prolog |
swap(S1, S2):-
functor(S1, f, 2), functor(S2, f, 2),
arg(1, S1, X1), arg(2, S1, Y1),
arg(1, S2, X2), arg(2, S2, Y2),
X1 = Y2, X2 = Y1.
swap(f(X, Y), f(Y, X)).
three_elements(L):-
length(L, N), N = 3.
(always traverses the list and computes its length)
three_elements([_,_,_]).
Example (real executions):
bad_count(N):-
assert(counting(N)),
even_worse.
even_worse:- retract(counting(0)).
even_worse:-
retract(counting(N)),
N > 0, N1 is N - 1,
assert(counting(N1)),
even_worse.
|
good_count(0).
good_count(N):-
N > 0, N1 is N - 1,
good_count(N1).
|
bad_count(10000): 165000 bytes, 7.2 sec.
good_count(10000): 1500 bytes, 0.01 sec.
fib(0, 0).
fib(1, 1).
fib(N, F):-
N > 1,
N1 is N - 1,
N2 is N1 - 1,
fib(N1, F1),
fib(N2, F2),
F is F1 + F2.
|
lfib(N, F):- lemma_fib(N, F), !.
lfib(N, F):-
N > 1,
N1 is N - 1,
N2 is N1 - 1,
lfib(N1, F1),
lfib(N2, F2),
F is F1 + F2,
assert(lemma_fib(N, F)).
:- dynamic lemma_fib/2.
lemma_fib(0, 0). lemma_fib(1, 1).
|
fib(24, F): 4800000 bytes, 0.72 sec.
lfib(24, F): 3900 bytes, 0.02 sec. (and zero from now on)
Warning: only useful when intermediate results are reused
member_check([X|_],X) :- !. member_check([_|Xs],X) :- member_check(Xs,X).
| Simplistic: | Better: | ||
|
|
same_elements(L1, L2):-
\+ (member(X, L1), \+ member(X, L2)),
\+ (member(X, L2), \+ member(X, L1)).
same_elements(L1, L2):-
sort(L1, Sorted),
sort(L2, Sorted).
(sorting can be done in
generate_z(Z):-
generate_x(X),
generate_y(X, Y),
test_x(X),
test_y(Y),
combine(X, Y, Z).
|
|
bad_greater(_X,[]). bad_greater(X,[Y|Ys]):- X > Y,bad_greater(X,Ys).
600000 elements: 2.3 sec.
good_greater([],_X). good_greater([Y|Ys],X):- X > Y, good_greater(Ys,X).
600000 elements: 0.67 sec
sum([], 0).
sum([N|Ns], Sum):-
sum(Ns, Inter),
Sum is Inter + N.
|
sum_iter(L, Res):-
sum(L, 0, Res).
sum([], Res, Res).
sum([N|Ns], In, Out):-
Inter is In + N,
sum(Ns, Inter, Out).
|
sum/2 100000 elements: 0.45 sec.
sum_iter/2 100000 elements: 0.12 sec.
<head>:-
<deterministic computation>
<recursive_call>.
a:-
test_1, !,
...
a:-
test_2, !,
...
...
a:-
test_n, !,
...
|
|
x2x3_2([], []).
x2x3_2([X|Xs], Out):-
X < 0, !,
NX is -X * 2,
Out = [NX|NXs],
x2x3_2(Xs, NXs).
x2x3_2([X|Xs], Out):-
X >= 0, !,
NX is X * 3,
Out = [NX|NXs],
x2x3_2(Xs, NXs).