B-Prolog has logical loops. For example, that's how we can calculate sum of [1,2,3]:
test1 :-
foreach(A in 1..3, [], ac(Sa, 0), (
Sa^1 is Sa^0 + A
)),
writeln(sa(Sa)).
?- test1.
test1.
sa(6)
yes
But when I try two nested loops with accumulators, I get errors:
test2 :-
foreach(_A in 1..3, [Sb], ac(Sa, 0), (
foreach(B in 1..3, [], ac(Sb, 0), (
Sb^1 is Sb^0 + B
)),
writeln(sb(Sb)),
Sa^1 is Sa^0 + Sb
)),
writeln(sa(Sa)).
?- test2.
test2.
*** error(invalid_argument,(+)/2)
Another variant, not including Sb in the list of local variables of the outer loop:
test3 :-
foreach(_A in 1..3, [], ac(Sa, 0), (
foreach(B in 1..3, [], ac(Sb, 0), (
Sb^1 is Sb^0 + B
)),
writeln(sb(Sb)),
Sa^1 is Sa^0 + Sb
)),
writeln(sa(Sa)).
?- test3.
test3.
sb(6)
*** error(invalid_argument,(+)/2)
Is it even possible to have nested loops with accumulators in B-Prolog?
My B-Prolog version is 8.0#1.
Your program runs correctly when compiled.
| ?- cl(sergey)
There must be some problem with the interpreter. This accumulator thing is very ugly and I never use it. In Picat, the successor of B-Prolog, you can use := to "update" variables.
An even better way is to use list comprehension.
The compiler compiles the summations into programs that use ':='. As lists are not actually constructed, there is no overhead.