%------------------------------------------------------------

%   File   : chr_lib.pl

%   Author : Neng-Fa ZHOU

%   Date   : April 2006

%   Purpose: A library of predicates needed to run CHR programs 

%   translated into Action Rules.

%------------------------------------------------------------

/*************************************************************************************************  
    Get the communication channels for a constraint having the name ConstrName and the term Term.
    ConstrName and Term are used as the key of a mapping table. All constraints with the same name 
    and the same term share the same channels. If Term is a variable, channels are attached to the 
    variable as attributes. Otherwise, the mapping table is stored in the global heap variable 
    named ConstrName and linear search is used to find the channels for Term.
**************************************************************************************************/
get_channel(ConstrName,Term,Channels):-
    get_channels(ConstrName,Term,Channels).

get_channels(ConstrName,Term,Channels):-
    susp_var(Term),
    susp_attached_term(Term,NameVarChannels),
    NameVarChannels\==[],!,
    lookup_register_channels(ConstrName,Term,NameVarChannels,Channels).
get_channels(ConstrName,Term,Channels):-
    var(Term),!,
    NameVarChannels=[channels(ConstrName,Term,Channels)|_],
    susp_attach_term(Term,NameVarChannels).
get_channels(ConstrName,Term,Channels):-true :
    (ground(Term)->
     global_heap_get((ConstrName,Term),Channels);
     global_heap_get(ConstrName,NameVarChannels),
     lookup_register_channels(ConstrName,Term,NameVarChannels,Channels)).

/* linear search */
lookup_register_channels(ConstrName,Term,NameVarChannels,Channels):-var(NameVarChannels) :
    NameVarChannels=[channels(ConstrName,Term,Channels)|_].
lookup_register_channels(ConstrName,Term,[channels(ConstrName,Term,Channels)|_],Channels1):-true :
    Channels1=Channels.
lookup_register_channels(ConstrName,Term,[_|NameVarChannels],Channels):-true :
    lookup_register_channels(ConstrName,Term,NameVarChannels,Channels).
    
/*********************************************************************/
new_constr_num(NewN):-
    global_heap_get($constr_num,N),
    (var(N)->N=0;true),
    NewN is N+1,
    global_heap_set($constr_num,NewN).