/*  FLAGS.PL  */
 
 
:- module flags.
 
 
:- public flag/3,
          flag/2.
 
 
/*
SPECIFICATION
-------------
 
This module implements global variables. It exports two predicates,
one for simultaneously examining the old value of a variable and
reassigning it, and one for just examining without reassigning.
 
 
PUBLIC flag( Flag+, OldValue?, NewValue+ ):
-------------------------------------------
 
"The old and new values of Flag are OldValue and NewValue respectively".
 
Flag can be any term, and denotes a global variable. It must be
instantiated. OldValue will be unified with the variables' current
value. If unification succeeds, then the value will be reset to
NewValue. Errors are reported if Flag or NewValue are uninstantiated.
 
 
PUBLIC flag( Flag+, OldValue? ):
--------------------------------
 
"The current value of Flag is OldValue".
 
Unifies Flag's current value with OldValue.
 
 
I don't use this module in the Tutor, but once thought I might. You
may as well have it, since it's more trouble than it's worth to
avoid copying it.
*/
 
 
:- needs bug/2.
 
 
flag( Flag, OldValue, NewValue ) :-
    var( NewValue ),
    bug( 'flag: new value is uninstantiated', Flag ).
 
flag( Flag, OldValue, NewValue ) :-
    var( Flag ),
    bug( 'flag: flag is uninstantiated' ).
 
flag( Flag, OldValue, NewValue ) :-
    (
        '$flag'( Flag, OldValue )
    ;
        OldValue = undefined
    ),
    (
        NewValue == OldValue
    ;
        retractall( '$flag'(Flag,OldValue) ),
        asserta( '$flag'(Flag,NewValue) )
    ).
 
 
flag( Flag, OldValue ) :-
    flag( Flag, OldValue, OldValue ).
 
 
:- endmodule.
