Another use for the function trail is check for floundering in the presence of delayed goals.
Often, when implementing certain kinds of constraint solvers, it may not be possible to actually solve all of the constraints at the time they are added. Instead, it may be necessary to simply delay their execution until a later time, in the hope the constraints may become solvable when more information is available. If you do implement a constraint solver with these properties, then at certain points in the computation — for example, after executing a negated goal — it is important for the system to check that their are no outstanding delayed goals which might cause failure, before execution commits to this execution path. If there are any such delayed goals, the computation is said to “flounder”. If the check for floundering was omitted, then it could lead to unsound behaviour, such as a negation failing even though logically speaking it ought to have succeeded.
The check for floundering can be implemented using the function trail, by simply calling ‘MR_trail_function()’ to add a function trail entry whenever you create a delayed goal, and putting the appropriate check for floundering in the ‘MR_commit’ and ‘MR_solve’ cases of your function. The Mercury extras distribution includes an example of this: see the ‘ML_var_untrail_func()’ function in the file ‘extras/trailed_update/var.m’.) If your function does detect floundering, then it should print an error message and then abort execution.