I got the following realization of the Partition function P
in Prolog, took it from rosetta here:
/* SWI-Prolog 8.3.21 */
:- table p/2.
p(0, 1) :- !.
p(N, X) :-
aggregate_all(sum(Z), (between(1,inf,K), M is K*(3*K-1)//2,
(M>N, !, fail; L is N-M, p(L,Y), Z is (-1)^K*Y)), A),
aggregate_all(sum(Z), (between(1,inf,K), M is K*(3*K+1)//2,
(M>N, !, fail; L is N-M, p(L,Y), Z is (-1)^K*Y)), B),
X is -A-B.
?- time(p(6666,X)).
% 13,962,294 inferences, 2.610 CPU in 2.743 seconds (95% CPU, 5350059 Lips)
X = 1936553061617076610800050733944860919984809503384
05932486880600467114423441282418165863.
How would one go about an implementation of the same in Picat? Is it
true that aggregate_all+sum can be replaced by foreach+:= ?
What about bignums in Picat?
Bignums is no problem in Picat. Here's my Picat version (inspired by the Maple approach):
Your (neat) SWI-Prolog version takes about 1,9s for
p(6666)on my machine.My Picat version takes about 0.2s
Update Here's a version using
findallin Picat instead, sort of mimicking your approach:But it's much slower (2.6s vs 0.2s):
I also tested to implement the same approach, i.e. using
findall/3in SWI-Prolog:It's faster than Picat's
findallapproach, and about the same time as your version (slightly faster but with more inferences).