Thanks for splitting the topic. Yes, you use once if you want a first solution of an otherwise nondet goal. This is in my experience hardly ever the case though. In a deterministic context one typically uses (semi-)deterministic sub-goals. There can be some exceptions, such as handling a line “Var=Value”. Now you could do
line_var_value(Line, Var, Value) :-
once(sub_atom(Line, B, _, A, =)),
sub_atom(Line, 0, B, _, Var),
sub_atom(Line, _, A, 0, Value).
I think the above is perfectly ok code, although in practice I’d write
line_var_value(Line, Var, Value) :-
( sub_atom(Line, B, _, A, =))
-> sub_atom(Line, 0, B, _, Var),
sub_atom(Line, _, A, 0, Value).
; syntax_error(invalid_var_decl)
).
For example, all libraries and packages use once/1 68 times in 300Klines (that includes the definition and probably some more false hits), mostly in old(er) code.