?- set_prolog_flag(contiguous_warning,off).

attr_unify_hook(class(CLP,La,Lat,ABasis,PrioA),Y) :-
	!,
	var(Y),
	get_attr(Y,class,class(CLP,Lb,Lbt,BBasis,PrioB)),
	Lat = Lb,
	append(ABasis,BBasis,CBasis),
	combine(PrioA,PrioB,PrioC),
	put_attr(Y,class,class(CLP,La,Lbt,CBasis,PrioC)).
attr_unify_hook(_,_).

class_new(Class,CLP,All,AllT,Basis) :-
	put_attr(Su,class,class(CLP,All,AllT,Basis,[])),
	Su = Class.

class_get_prio(Class,Priority) :-
	get_attr(Class,class,class(_,_,_,_,Priority)).

class_get_clp(Class,CLP) :-
	get_attr(Class,class,class(CLP,_,_,_,_)).

class_put_prio(Class,Priority) :-
	get_attr(Class,class,class(CLP,All,AllT,Basis,_)),
	put_attr(Class,class,class(CLP,All,AllT,Basis,Priority)).

class_drop(Class,X) :-
	get_attr(Class,class,class(CLP,Allvars,Tail,Basis,Priority)),
	delete_first(Allvars,X,NewAllvars),
	delete_first(Basis,X,NewBasis),	
	put_attr(Class,class,class(CLP,NewAllvars,Tail,NewBasis,Priority)).

class_allvars(Class,All) :- get_attr(Class,class,class(_,All,_,_,_)).

% class_basis(Class,Basis)
%
% Returns the basis of class Class.

class_basis(Class,Basis) :- get_attr(Class,class,class(_,_,_,Basis,_)).

% class_basis_add(Class,X,NewBasis)
%
% adds X in front of the basis and returns the new basis

class_basis_add(Class,X,NewBasis) :-
	NewBasis = [X|Basis],
	get_attr(Class,class,class(CLP,All,AllT,Basis,Priority)),
	put_attr(Class,class,class(CLP,All,AllT,NewBasis,Priority)).

% class_basis_drop(Class,X)
%
% removes the first occurence of X from the basis (if exists)

class_basis_drop(Class,X) :-
	get_attr(Class,class,class(CLP,All,AllT,Basis0,Priority)),
	delete_first(Basis0,X,Basis),
	Basis0 \== Basis,   % anything deleted ?
	!,
	put_attr(Class,class,class(CLP,All,AllT,Basis,Priority)).
class_basis_drop(_,_).

% class_basis_pivot(Class,Enter,Leave)
%
% removes first occurence of Leave from the basis and adds Enter in front of the basis

class_basis_pivot(Class,Enter,Leave) :-
	get_attr(Class,class,class(CLP,All,AllT,Basis0,Priority)),
	delete_first(Basis0,Leave,Basis1),
	put_attr(Class,class,class(CLP,All,AllT,[Enter|Basis1],Priority)).

% delete_first(Old,Element,New)
%
% removes the first occurence of Element from Old and returns the result in New
%
% note: test via syntactic equality, not unifiability

delete_first(L,_,Res) :-
	var(L),
	!,
	Res = L.
delete_first([],_,[]).
delete_first([Y|Ys],X,Res) :-
	(   X==Y
	->  Res = Ys
	;   Res = [Y|Tail],
	    delete_first(Ys,X,Tail)
	).
