(Copying over from my reddit post. Same question plz)
Hey can you help me out with how this can be done?
Suppose I’m doing something like this
hooray :- writeln("hooray").
rand_check :-
random_permutation([1,2,3],L),
random_between(0,2,Position),
random_between(1,3,Target),
nth0(Position,L,Target).
foo :-
rand_check,
hooray, !
;
writeln("missed foo").
bar_(0) :- !.
bar_(N) :-
( rand_check,
hooray, !
;
writeln("missed bar")
),
succ(N0,N),
bar_(N0).
bar :-
bar_(20).
main :-
foo,
bar.
but let’s say in addition to printing “hooray”, I want to gain 1 point for each hit and then return my total points when the program completes.
One way to do this would be to thread a point accumulator throughout my entire program
hooray :- writeln("hooray").
rand_check :-
random_permutation([1,2,3],L),
random_between(0,2,Position),
random_between(1,3,Target),
nth0(Position,L,Target).
foo(P0,P1) :-
rand_check,
hooray,
P1 is P0+1, !
;
P1 = P0,
writeln("missed foo").
bar_(0,P,P) :- !.
bar_(N,P1,P2) :-
( rand_check,
hooray,
P3 is P1+1, !
;
P3 is P1+0,
writeln("missed bar")
),
succ(N0,N),
bar_(N0,P3,P2).
bar(P1,P2) :-
bar_(20,P1,P2).
main :-
P0 = 0,
foo(P0,P1),
bar(P1,P2),
write("Score: "),
writeln(P2).
but I think the problems with this are obvious? Inconvenient to implement, doesn’t scale well, error prone, muddies up your code with all the extra variables, etc. Not ideal, especially for larger apps.
You can also use a mutable flag
hooray :- writeln("hooray").
add_point :- flag(points,P,P+1).
rand_check :-
random_permutation([1,2,3],L),
random_between(0,2,Position),
random_between(1,3,Target),
nth0(Position,L,Target).
foo :-
rand_check,
hooray,
add_point, !
;
writeln("missed foo").
bar_(0) :- !.
bar_(N) :-
( rand_check,
hooray,
add_point, !
;
writeln("missed bar")
),
succ(N0,N),
bar_(N0).
bar :-
bar_(20).
main :-
set_flag(points,0),
foo,
bar,
get_flag(points,P),
write("Score: "),
writeln(P).
Better, cleaner, but I feel like you’re still muddying up your code a little bit by sprinkling calls to your flag all over, and also what if you prefer a more immutable solution? A flag is basically just a mutable variable, thread-safe though it is.
Tell me if this is crazy but I was wondering if an MCI could be used to completely decouple the point tracking system from the actual logic, ie. the first code block above.
If so, what would that look like? If not, is there a better way to do this? Thanks.