abolish( F, A) :- functor( Term, F, A), retract_all( Term).
retract_all( X) :- retract( X), fail.
retract_all( X) :- retract( X :- _), fail.
retract_all( _).
assert_test :-
assert(test(1)),
assert(test(2)),
assert(test(3) :- test(a, b)),
assert(test(a, b)).
filter( P, [ X| Xs], [ X| Ys]) :-
F =.. [P, X], call( F), !,
filter( P, Xs, Ys).
filter( P, [ _| Xs], Ys) :- filter( P, Xs, Ys).
filter( _, [], []).
pos( X) :- X > 0.
neg( X) :- X < 0.
Back to example 6.1
:- dynamic fibo/2.
fibo( 0, 0).
fibo( 1, 1).
fibo( N, F) :-
N > 1, N1 is N - 1, N2 is N - 2,
fibo( N1, F1), fibo( N2, F2), F is F1 + F2,
asserta( fibo( N, F) :- !).
fibo_iter(Counter, F2, F1, Result) :-
Counter > 0,
Sum is F2 + F1,
F2_new = F1,
F1_new = Sum,
Counter1 is Counter - 1,
fibo_iter(Counter1, F2_new, F1_new, Result).
fibo_iter(0, F2, F1, Result) :-
Result = F1.
fibo_iter(0, 0).
fibo_iter(1, 1).
fibo_iter(N, F) :-
N > 1,
Counter is N - 1,
fibo_iter(Counter, 0, 1, F).
Back to example 6.2
:- dynamic dist/3.
dist( zuerich, baden, 22).
dist( baden, basel, 83).
distances :-
nl, write( 'Input: d( City1, City2).'),
nl, write( 'Quit: exit.'),
repeat,
nl, write( 'Input: '),
read( Input),
process_input( Input), !.
d( X, Y, D) :- dist( X, Y, D).
d( X, Y, D) :- dist( Y, X, D).
process_input( exit) :- !.
process_input( d( S1, S2)) :- distance( S1, S2, _), fail.
output( S1, S2, D) :-
nl, write( 'The distance between '), write( S1), write( ' and '), write( S2),
write( ' is '), write( D), write( ' km ').
distance( S1, S2, D) :- d( S1, S2, D), output( S1, S2, D), !.
distance( S1, S2, D) :- ask_user( S1, S2, D), !.
ask_user( S1, S2, D) :-
nl, write( 'I do not know. Please tell me:'),
read( DR), process_answer( S1, S2, D, DR).
process_answer( S1, S2, D, DR) :-
number( DR), !, D = DR, assert( dist( S1, S2, D)),
nl, write( 'Thank you. I confirm:'), output( S1, S2, D).
process_answer( _, _, _, no).
process_answer( _, _, _, eof).
process_answer( S1, S2, D, _) :-
nl, write( '*** Invalid Input ***'), ask_user( S1, S2, D).
Back to example 6.3
init( C, V) :- retractall( counter( C, _)),
assert( counter( C, V)), !.
get( C, V) :- counter( C, V).
inc( C) :- retract( counter( C, N)), N1 is N + 1,
assert( counter( C, N1)), !.
dec( C) :- retract( counter( C, N)), N1 is N - 1,
assert( counter( C, N1)), !.
del( C) :- retract( counter( C, _)).
Back to example 6.4
bag_of( X, P, _) :-
asserta( found( mark)),
call( P),
asserta( found(X)),
fail.
bag_of( _, _, B) :-
collect( [], B).
collect( B, BB) :-
retract( found( X)),
( X == mark -> BB = B
; collect( [ X| B], BB)
), !.
set_of( X, P, S) :-
bag_of( X, P, L),
sort1( L, S).
sort1( [], []).
sort1( [ X1| Xs], Y) :-
sort1( Xs, Ys),
insert1( X1, Ys, Y).
insert1( X, [], [ X]).
insert1( X, [ Y1| Ys], [ X, Y1| Ys]) :- X < Y1.
insert1( X, [ Y1| Ys], [ Y1| Zs]) :- X > Y1, insert1( X, Ys, Zs).
insert1( X, [ X| Ys], [ X| Ys]).
a(4).
a(1).
a(5).
a(3).
a(4).
a(1).
Back to example 6.5