Prolog Cookbook
Classic factorial function,
factorial(0, 1). factorial(N, N_Fact) :- N > 0, M is N-1, factorial(M, M_Fact), N_Fact is M_Fact*N.Fibonacci functions
;; Non tail recursive version - is going to stack overflow quickly fib(0, 0). fib(1, 1). fib(N, N_Fib) :- N > 1, M is N-1, T is N-2, fib(M, M_Fib), fib(T, T_Fib), N_Fib is M_Fib + T_Fib. ;; Tail recursive version fibonacci(N, N_Fib) :- tfib(N, 0, 1, N_Fib). tfib(0, A, _, A). tfib(N, A, B, N_Fib) :- N > 0, Next_N is N-1, Next_A is B, Next_B is A + B, tfib(Next_N, Next_A, Next_B, N_Fib).Aggregate counting in SWI-Prolog,
likes(jimmy, anna). likes(paul, anna). likes(jimmy, paul). popular(X) :- aggregate(count, Y^likes(Y,X), N), N > 1.Here,
popularfunction checks whether given person is liked by more than one person. In the definitionYis existentionally qualified.References - https://stackoverflow.com/questions/5930340/aggregate-3-in-swi-prolog/5930420
Higher order functions,
double(X, Y) :- Y is X + X. pow2(X, Y) :- Y is X * X. map([], _, []). map([X|Xs], P, [Y|Ys]) :- call(P, X, Y), map(Xs, P, Ys). ;; Examples map([1, 2, 3], double, Xs). ;; Xs = [1, 4, 6] map([1, -2, 3], pow2, Xs). ;; Xs = [1, 4, 9]Checking whether a predicate exists - https://stackoverflow.com/questions/12886179/prolog-how-to-check-if-a-predicate-exists.
current_predicate(map/3). ;; checks whether map which takes 3 parameters existsDefine contains based on append function,
append([], Ys, Ys). append([X|Xs], Ys, [X|Zs]) :- append(Xs, Ys, Zs). prefix(P, L) :- append(P, _, L). suffix(S, L) :- append(_, S, L). contains(SubL, L) :- suffix(S, L), prefix(SubL, S), !.Palindrome check in Prolog is quite nice,
palindrome(Xs) :- reverse(Xs, Xs).In a restricted set, we can even use this declarative definition to generate palindromes, as in the following example!
member(X, [1, 2, 3]), member(Y, [10, 11, 12]), member(Z, [1, 2]), palindrome([X, Y, Z]).Fizz buzz in Prolog,
```prolog print_fizz_buzz(N) :- ( 0 is mod(N, 15) -> write("fizzbuzz"),nl ; 0 is mod(N, 3) -> write("fizz"), nl ; 0 is mod(N, 5) -> write("buzz"), nl ; write(N), nl ).
fizz_buzz(N) :- aux_fizz_buzz(0, N). aux_fizz_buzz(M, N) :- M < N, print_fizz_buzz(M), M1 is (M + 1), aux_fizz_buzz(M1, N). aux_fizz_buzz(M, N) :- M >= N, !, nl.
In true Prolog fashion, one can find out all the operators which are curently definied using something like follows,
which will list all the opeartors with their respective precedence and type.
Permutations,
Last updated