@peter.ludemann
Thanks for the (reminder of the) links, Peter. I used these Logical Loops a lot when testing ECLiPSe CLP (http://hakank.org/eclipse/ ) and SICStus Prolog (http://hakank.org/sicstus/ ).
Joachim Schimpf’s paper “Logical Loops” is available from the ECLiPSe page you linked to (http://eclipseclp.org/software/loops/index.html). Here’s the PDF version: http://eclipseclp.org/reports/loops.pdf
Just as a proof-of-concept, I installed Jan W’s version of loop.pl (https://github.com/JanWielemaker/logical-loops) and tested it on some of my ECLiPSe Prolog predicates for Euler problem 1: http://hakank.org/swi_prolog/euler1_loop.pl
Here’s the code
%% From https://github.com/JanWielemaker/logical-loops
:- use_module("/home/hakank/swi_prolog/git/jan_wielemaker/logical-loops/loops.pl").
go :-
L = [
euler1a,
euler1b,
euler1c,
euler1d
],
( foreach(P, L) do
writeln(P),
time(P),
nl
),
nl.
euler1a :-
numlist(1,999,L),
filter(div3_or_5, L, Includes),
sumlist(Includes, SumList),
writeln(SumList).
euler1b :-
( for(N,1,999),
fromto(L,Out,In,[])
do
( M is N mod 3 ; M is N mod 5),
M =:= 0 -> Out = [N|In] ; Out = In
),
sumlist(L,S),
writeln(S).
euler1c :-
( for(I,1,999),
fromto(0,In,Out,Sum) do
div3_or_5(I) ->
Out is In + I
;
Out = In
),
writeln(Sum).
euler1d :-
(
for( I,1,999),
fromto(0,In,Out,Sum) do
M3 is I mod 3,
M5 is I mod 5,
(M3 == 0 ; M5 == 0) ->
Out is In + I
;
Out = In
),
writeln(Sum).
div3_or_5(N) :-
0 is N mod 3 ; 0 is N mod 5.
applyP(P, Xs) :- Query =.. [P,Xs], Query.
filter(P, List1, List2) :-
( foreach(X,List1),
fromto(List2,Out,In,[]),
param(P) do
applyP(P, X) -> Out = [X|In] ; Out=In
).
The output is
?- make,go.
euler1a
233168
% 8,804 inferences, 0.001 CPU in 0.001 seconds (100% CPU, 14555266 Lips)
euler1b
233168
% 6,465 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 16116889 Lips)
euler1c
233168
% 5,330 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 16417984 Lips)
euler1d
233168
% 3,465 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 8829330 Lips)
true.
Note: I got a warning which that is not occurrent when I run the program in ECLiPSe :
Warning: /home/hakank/swi_prolog/me/euler1_loop.pl:88:
Warning: do/2: inconsistent parameter declaration
Warning: Shared but not declared: List1 and List2
It would be great if this would be incorporated in SWI-Prolog.
(Hmm, for some reason, I never published my Project Euler programs for ECLiPSe CLP. This I must fix…
Later: And now that’s fixed: http://hakank.org/eclipse/ and https://github.com/hakank/hakank/tree/master/eclipse_clp/ )