Your program runs correctly when compiled.
| ?- cl(sergey)
Compiling::sergey.pl
** Warning: Variable 'Sb' is treated as global in foreach (17-25).
** Warning: Variable 'Sb' is treated as global in list_comprehension (36-38).
compiled in 0 milliseconds
loading...
yes
| ?- test1
sa(6)
yes
| ?- test2
sb(6)
sb(6)
sb(6)
sa(18)
yes
| ?- test3
sb(6)
sb(6)
sb(6)
sa(18)
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.
test1 =>
Sa = 0,
foreach(A in 1..3)
Sa := Sa+A
end,
writeln($sa(Sa)).
test2 =>
Sa = 0,
foreach(_A in 1..3)
Sb := 0,
foreach(B in 1..3)
Sb := Sb+B
end,
writeln($sb(Sb)),
Sa := Sa+Sb
end,
writeln($sa(Sa)).
An even better way is to use list comprehension.
test1 =>
Sa = sum([A : A in 1..3]),
writeln($sa(Sa)).
test2 =>
Sa = sum([Sb : _A in 1..3, Sb=sum([B : B in 1..3])]),
writeln($sa(Sa)).
The compiler compiles the summations into programs that use ':='. As lists are not actually constructed, there is no overhead.