Poplog 15.5 (Prolog)Version of implementation Poplog (Prolog) of programming language Prolog
A version of Poplog.
This example consists of two parts — the first part of code should be stored in a file
fact.pl placed in working folder of Poplog, and the second one has to be entered manually.
[-fact]. downloads facts and rules from this file to current Prolog session (and outputs
fact reconsulted to note that download succeeded). Query
fact(16,X). tries to find value of X for which this predicate will evaluate to true. The output required in the example is side effect of query evaluation, and the actual result will be
X = 20922789888000 ?. This means that if you’re not satisfied with this binding, you can reject it (by entering ;), and the search for better binding will continue.
% fact.pl fact(X, F) :- ( X=0, F=1; Y is X-1, fact(Y, Z), F is X*Z), write(X), write('! = '), write(F), nl. % interactive [-fact]. fact(16,X).
Straightforward recursive implementation is too memory inefficient to be executed in Poplog, so this example shows a more advanced technique — recursion with memoization. An additional predicate
memo(Goal) is defined so that the first time
Goal is evaluated, the result of its evaluation is added to facts database, and next time it is questioned, it is not re-evaluated but taken as a known fact.
After this predicate
fib(N,F) is defined recursively, but each call to
fib is wrapped in
memo, so for each value of N
fib(N,F) is evaluated only once. With such approach printing calculated numbers can be done immediately after their calculation, without extra loop.
% fibonacci.pl :- dynamic(stored/1). memo(Goal) :- stored(Goal) -> true; Goal, assertz(stored(Goal)). fib(1,1) :- !, write('1, '). fib(2,1) :- !, write('1, '). fib(N,F) :- N1 is N-1, memo(fib(N1,F1)), N2 is N-2, memo(fib(N2,F2)), F is F1 + F2, write(F), write(', '). % interactive [-fibonacci]. fib(16,X), write('...'), nl.
This example doesn’t need any facts or rules to be evaluated. The query is executed in interactive mode, and results in the following output:
First line is the actual output of
write predicate, and second line is the result of query evaluation.
Note that replacing single-quotes with double-quotes makes Prolog output the string as an array of ASCII-codes of individual characters:
| ?- write("Hello, World!").
write('Hello, World!'), nl.