% unconditional_satisfied( +Unconditional, +Vars, +Vals, +Probed ) :-
% true if the Vars and Vals, involved in the Unconditional (constraint),
% satisfy it. Probed contains Var-Val pairs from which Vars are instantiated,
% before being checked.
%
unconditional_satisfied( Constr, Vars, InVals, Probed ) :-
	pfd_vars_probed_to_values( Vars, Probed, Values ),
	append( InVals, Values, [Val1,Val2] ),
	unconditional_satisfied_1( Constr, Val1, Val2 ).

% unconditional_satisfied( Constr, LV, RV, Probed ) :-
	% memberchk( LV-LDat, Probed ),
	% memberchk( RV-RDat, Probed ),
	% unconditional_satisfied_1( Constr, LDat, RDat ).
	
unconditional_satisfied_1( diff, LDat, RDat ) :-
	LDat \== RDat.
unconditional_satisfied_1( eq, LDat, RDat ) :-
	LDat == RDat.

probe_event_in_labels( Event, PfdVs, PrlgVs, Labels ) :-
	instantiate_from_labels( PfdVs, PrlgVs, Labels ),
	pfd_call_once( Event ).

instantiate_from_labels( [], [], _Labels ).
instantiate_from_labels( [H|T], [Hvr|TVrs], Labels ) :-
	( memberchk(H-Hvr,Labels) -> true ;
		write( error(chk_this_out(H,Hvr,Labels)) ), nl
	),
	instantiate_from_labels( T, TVrs, Labels ).

probe_event_in_statics( Event, PfdVs, PrlgVs, Probed, Prb ) :-
	findall( LblPrb,
			( 
				probed_stcs_cartesian_label( PfdVs, PrlgVs, Probed, 1/1, LblPrb ),
				pfd_call_once( Event ),
				dbg( succeeded(Event) )
			),
			AllLblPrbs ),
	rationals_add_list( AllLblPrbs, Prb ).

probed_stcs_cartesian_label( [], [], _Statics, Prb, Prb ).
probed_stcs_cartesian_label( [H|T], [Hpv|Tpv], Statics, AccPrb, Prb ) :-
	id_memberchk_kv( Statics, H-Hdistro ),
	member( Hpv-Hprb, Hdistro ),
	rationals_multiplication( AccPrb, Hprb, NxPrb ),
	probed_stcs_cartesian_label( T, Tpv, Statics, NxPrb, Prb ).

% 2002da05 not used anymore ?
% probed_predicate_is_in_event( Predicate, PfdVars, PrologVars, Probed )
probed_predicate_is_in_event( Predicate, PfdVs, PrlgVs, Probed ) :-
	pfd_vars_probed_to_values( PfdVs, Probed, Values ),
	Values = PrlgVs,
	pfd_call_once( Predicate ).

pfd_vars_probed_to_values( PfdVars, Probed, Values ) :-
	findall( Val,
		( member(Var,PfdVars),
		  ( memberchk(Var-Val,Probed) -> true ; 
			G = pfd_vars_probed_to_values/2,
			M = 'should be a member of.',
			print_message( error, consistency_error(G,Var-Val,Probed,M) ),
			abort
		  )
		),
			Values ).

constraint_consistency( cond_diff, DepVal, InDpFD ) :-
	\+ (DepVal==InDpFD;InDpFD=[DepVal]).
	% \+ DepVal==InDpFD.

% constraint_consistency( (RfFn-RfVl,DpFn-DpVl), DepVal, InDpFD ) :-
	% write( left( RfFn-RfVl) ), nl,
	% write( right( DpFn-DpVl) ), nl,
	% write( dep_value(DepVal) ), nl,
	% ( unconditional_satisfied_1(DpFn,DpVl,DepVal) -> 
		% write( in_tightly ), nl,
		% not_tightly_satisfied( RfFn, RfVl, InDpFD )
		% ;
		% true
	% ).

% this  implements a conservative, consistency check, 
% 
constraint_consistency( (IfFn-IfVl,ExcFn-ExcVl), Proposed, IfFd ) :-
	( tightly_satisfied( IfFn, IfVl, IfFd ) -> 
		% unconditional_satisfied_1( ExcFn, ExcVl, Proposed )
		( unconditional_satisfied_1( ExcFn, ExcVl, Proposed ) -> 
			true
			;
			fail
		)
		;
		true
	).

tightly_satisfied( Cnstr, Val, Either ) :-
	( atomic(Either) -> 
		unconditional_satisfied_1( Cnstr, Val, Either )
		;
		( Either=[Atom] -> 
			unconditional_satisfied_1( Cnstr, Val, Atom )
			;
			fail
		)
	).

dependent_value_satisfies_all( [], _Val, _Active ).
dependent_value_satisfies_all( [NdVar-NdCnstr|Tail], Val, Active ) :-
	active_selects( [NdVar], Active, [NdVar-NdVarData] ),
	data_choose( dmn(NdFd), NdVarData ),
	constraint_consistency( NdCnstr, Val, NdFd ),
	dependent_value_satisfies_all( Tail, Val, Active ).

% the following is a provisional implementation of the predicate.
% it will behave incorrectly (although on the "safe" side)
% if vals havent been incorporated in active  already.
dependent_values_satisfies_all( [], [], _Act ).
dependent_values_satisfies_all( [NeedsH|NeedsT], [Vl|Vls], Active ) :-
	dependent_value_satisfies_all( NeedsH, Vl, Active ),
	dependent_values_satisfies_all( NeedsT, Vls, Active ).
