% data of a variable in active,
% currently Data = [Method,Fd,Needs,Reqred]
% Needs = [(Var,Constr)|T]
% Method = (Method,{Fd,(Fd,Var,Constr,Prob)}

data_choices_for_label_n( [], [], [], [] ).
data_choices_for_label_n( [_H-Datah|T], [Mt|Mts],[Fd|Fds],[Nd|Nds] ) :-
	data_choices( [mtd(Mt),dmn(Fd),nds(Nd)], Datah ),
	data_choices_for_label_n( T, Mts, Fds, Nds ).

data_choices( [], _Data ).
data_choices( [H|T], Data ) :-
	data_choose( H, Data ),
	data_choices( T, Data ).

data_choose( mtd(Method), [Method,_Fd,_Needs,_ReqBy] ).
% see data_update( dmn(), ... )
data_choose( dmn_or_v(Fd), [_Method,Fd,_Needs,_ReqBy] ).
data_choose( clpfd_dmn(ClpFd), [_Method,PrvFd,_Needs,_ReqBy] ) :-
	PrvFd = fdv(Var,_Idx),
	fd_set( Var, Now ),
	% Now \== [[inf|sup]],
	fdset_to_list( Now,ClpFd ).
data_choose( dmn(Fd), [_Method,PrvFd,_Needs,_ReqBy] ) :-
	( PrvFd = fdv(Var,Idx) ->
		fd_set( Var, Now ),
		% Now \== [[inf|sup]],
		fdset_to_list( Now,ClpFd ),
		( bb_get( Idx, FullFd ) ->
			sieve_positions( ClpFd, 1, FullFd, Fd )
			;
			Fd = ClpFd
		)
		;
		( atomic(PrvFd) ->
			Fd = [PrvFd]
			;
			Fd = PrvFd
		)
	).
data_choose( nds(Needs), [_Method,_Fd,Needs,_ReqBy] ).
data_choose( rqr(ReqBy), [_Method,_Fd,_Needs,ReqBy] ).

data_update( mtd(Method), [_OldMtd,Fd,Needs,ReqBy], [Method,Fd,Needs,ReqBy] ).
data_update( dmn(Fd), [Method,_OldFd,Needs,ReqBy], [Method,Fd,Needs,ReqBy] ).
% alternatively change the auxil.pl aux_map_variables/3. 2000/02/24
% data_update( dmn(Fd), [_Method,_OldFd,_Needs,_ReqBy], Fd ).
data_update( nds(Needs), [Method,Fd,_OldNds,ReqBy], [Method,Fd,Needs,ReqBy] ).
data_update( rqr(ReqBy), [Method,Fd,Needs,_OldRqr], [Method,Fd,Needs,ReqBy] ).

data_swap( mtd(OldM), [OldM,Fd,Needs,ReqBy], NewM, [NewM,Fd,Needs,ReqBy] ).
data_swap( dmn(OldFd), [Method,OldFd,Needs,ReqBy], NewFd, [Method,NewFd,Needs,ReqBy] ).
data_swap( nds(OldN), [Method,Fd,OldN,ReqBy], NewN, [Method,Fd,NewN,ReqBy] ).
data_swap( rqr(OldR), [Method,Fd,Needs,OldR], NewR, [Method,Fd,Needs,NewR] ).

data_needs_is_empty( [] ).

data_domain_concrete( PrvFd, Fd ) :-
	( var(PrvFd) ->
		fd_set( PrvFd, Now ),
		% Now \== [[inf|sup]],
		fdset_to_list( Now, Fd )
		;
		Fd = PrvFd
	).

data_update_dmns( [], [], [] ).
data_update_dmns( [H|T], [HVr-HDat|TDat], [HVr-HUp|TUp] ) :-
	ensure_list( H, HList ),
	data_update( dmn(HList), HDat, HUp ),
	data_update_dmns( T, TDat, TUp ).

% data_needs_satisfy( Rv, Val, Dv, Fd, Needs, NewFd, RemNeeds [++, +Prb] ) :-
% Rv, prb var, has value Val and is required by the variable to which
% Fd and Needs, belong (now in Dv), NewFd and RemNeeds are the results of
% applying the relavant constraint in Needs that involves
% the two variables and the remaining dependant constraints
% for the variable left in RemNeeds.
%
data_needs_satisfy( Rv, Val, Dv, _MStr, Fd, Needs, NewFd, RemNeeds, Prb ) :-
	select( Rv-NdCnstr, Needs, RemNeeds ),
	% 2002da05, this only covers one constraint per Dep/Qlf pair...
	!,
	% ( MethodStr=(_Method,Var,_Constr,_Prob) ->
		% NewFd = Fd
		% ;
		apply_conditional( NdCnstr, Val, Dv, Fd, NewFd, Prb ),
		dbg( apply_conditional( NdCnstr, Val, Dv, Fd, NewFd, Prb )).
	% ).

apply_conditional( cond_diff(Pi), Elem, _Dv, Set, RedSet, Prb ) :-
	!,
	( Pi = A/A ->
		Prb = 1/1, ord_del_element( Set, Elem, RedSet )
		;
		(
		Prb = Pi, ord_del_element( Set, Elem, RedSet ) ;
		  RedSet = [Elem], rationals_prob_compliment( Pi, Prb )
		  % RedSet = Set, rationals_prob_compliment( Pi, Prb )
		)
	)
	.

apply_conditional( Term, Elem, Dpv, Set, RedSet, Prb ) :-
	dbg( term(Term) ),
	dbg( elem(Elem) ),
	dbg( dpv(Dpv) ),
	dbg( set(Set) ),
	copy_term( Term, Fresh ),
	Fresh = (D,Pi,Q,Dv,Qv,_Zs),
	dbg( Qv = Elem ),
	Qv = Elem,
	dbg( Qv = Elem ),
	% ( call(Q) ->
	( pfd_call_once(Q) ->
		( is_list( D ) ->
			( Pi == onevar  ->
				member(Di:Prb,D),
				dbg( member(Di:Prb,D) ),
				apply_unconditional_rev( Di, Dv, Set, RedSet )
				;
				% member(Dv-SmCnsts,D),
				member(SmPv-SmCnsts,D),
				member(Di:Prb,SmCnsts),
				( SmPv == Dpv ->
					% SmCn = Di:Prb,
					apply_unconditional_rev( Di, Dv, Set, RedSet )
					;
					RedSet = Set % , Prb = 1/1
				)

			)
			;
			apply_unconditional_rev( D, Dv, Set, RedSetA ),
			dbg( apply_unconditional_rev(D,Dv,Set,RedSetA) ),
			( Pi =  A/A ->
				RedSet = RedSetA, Prb = Pi
				; 
				( RedSet = RedSetA, Prb = Pi ;
					apply_compliment_rev( D, Dv, Set, RedSet ),
			  	% RedSet = RedSetA, Prb = Pi % ;
			  	% RedSet = Set, 
			     	rationals_prob_compliment( Pi, Prb )
				)
			)
		)
		;
		RedSet = Set, Prb = 1/1
	).

apply_compliment_rev( Uncond, Pvar, Vdom, RedDom ) :-
	apply_compliment_rev_1( Uncond, Pvar, Vdom, RedDom ),
	( RedDom == [] -> write(empty_compliment), nl, fail ; true ).
	
apply_compliment_rev_1( (_X # Y), _Pvar, _Vdom, [Y] ).
apply_compliment_rev_1( (_X = Y), _Pvar, Vdom, RedDom ) :-
	( ord_del_element( Vdom, Y, RedDom ) -> true
		; RedDom = Vdom ).
apply_compliment_rev_1( Uncond, Pvar, Vdom, RedDom ) :-
	apply_unconditional_rev_2( (\+ Vdom), Uncond, Pvar, RedDom ).

apply_unconditional_rev( Uncond, Pvar, Vdom, RedDom ) :-
	apply_unconditional_rev_1( Uncond, Pvar, Vdom, PrvDom ),
	% ( PrvDom == [] -> RedDom = Vdom ; RedDom = PrvDom ).
	( PrvDom == [] -> write(empty_uncond(Uncond)), nl, fail ; RedDom = PrvDom ).

apply_unconditional_rev_1( (_X # Y), _Pvar, Vdom, RedDom ) :-
	% assume this ( pvar(X) -> Z = X ; Z = Y ),
	!,
	% only for development version.
	( atomic( Y ) -> true ; 
		write( internal_error(apply_unconditional_rev_1/4,1)), nl,
		abort
	),
	( ord_del_element( Vdom, Y, RedDom ) -> true
		; RedDom = Vdom ).
apply_unconditional_rev_1( (_X = Y), _Pvar, Vdom, RedDom ) :-
	!,
	% only for development version.
	% ( atomic( Y ) -> true ; 
		% write( internal_error(apply_unconditional_rev_1/4,2)), nl,
		% abort
	% ),
	( memberchk( Y, Vdom ) -> RedDom = [Y]
		; RedDom = Vdom ).
apply_unconditional_rev_1( Uncond, Pvar, Vdom, RedDom ) :-
	apply_unconditional_rev_2( Vdom, Uncond, Pvar, RedDom ).

apply_unconditional_rev_2( [], _Uncond, _Pvar, [] ).
apply_unconditional_rev_2( [H|T], Uncond, Pvar, RedDom ) :-
	% copy_term( Pvar-Uncond, Vdash-Udash ),
	( \+ \+ (H=Pvar,pfd_call_once(Uncond)) -> 
		RedDom = [H|RedT]
		;
		RedDom = RedT
	),
apply_unconditional_rev_2( T, Uncond, Pvar, RedT ).

/*
apply_conditional( cond_diff, Elem, Set, RedSet ) :-
	ord_del_element( Set, Elem, RedSet ).

% 19990721

apply_conditional( (RfFn-RfVl,DpFn-DpVl), Elem, Set, RedSet ) :-
	% ( apply_conditional_1( RfFn, RfVl, Elem ) -> 
	( unconditional_satisfied_1(RfFn,RfVl,Elem) -> 
		apply_conditional_rev( DpFn, DpVl, Set, RedSet )
		;
		RedSet = Set
	).

% apply_conditional_rev( CnFn, CnVal, OthVal,  ).
apply_conditional_rev( diff, CnVal, Set, RedSet ) :-
	!,
	( ord_del_element( Set, CnVal, RedSet ) ->
		true
		;
		RedSet = Set
	).
apply_conditional_rev( eq, CnVal, Set, RedSet ) :-
	memberchk( CnVal, Set ),
	RedSet = [CnVal].

*/
% end addition

% data_add_needs( DepVar, Constr, Var, DpVDt, NewDpVDt ) :-
% add the information, that DepVar needs Constr-Var, in its data 
% part, DpVDt. Yielding NewDpVDt data part.
%
data_add_needs( Constr, Var, DpVDt, NewDpVDt ) :-
	data_swap( nds(Needs), DpVDt, NewNeeds, NewDpVDt ),
	ord_add_element( Needs, Var-Constr, NewNeeds ).

data_add_required_many( [], _DepVar, _What, NewRoots, NewRoots, [] ).
data_add_required_many( [HDt|T], DepVar, What, Roots, NewRoots, [HNwDt|TNwDts] ) :-
	data_add_required( DepVar, What, HDt, Roots, HNwDt, NxRoots ),
	data_add_required_many( T, DepVar, What, NxRoots, NewRoots, TNwDts ).

% data_add_required( Var, DepVar, Constr, VarDt, Roots, NewVDt, NewRoots ) :-
% DepVar is added in the required data part (of Var), VarDt to NewVDt.
% DepVar is eliminated, if it exists, from Roots, yielding NewRoots.
% Constr is not used currently.
%
data_add_required( DepVar, _Constr, VarDt, Roots, NewVDt, NewRoots ) :-
	data_swap( rqr(ReqBy), VarDt, NewReqBy, NewVDt ),
	ord_add_element( ReqBy, DepVar, NewReqBy ),
	( ord_del_element(Roots,DepVar,NewRoots) -> 
		true
		;
		NewRoots = Roots
	).

probe_parts( V-[Fd,Prs,ReqBy], V, Fd, Prs, ReqBy ).
	
probed_find( Var, Probed, Val ) :-
	memberchk( Var-Val, Probed ).


% we expect Zs will always be a list of vars here (ie not a var).
% bi_unconditional_constraint_pairs( +Pairs, +Zs, +APrs, +APvs, -NrmPairs, -Vars, -Pvars ).
bi_unconditional_ind_const_pairs( [], _FdIs, _Zs, APrs, Pvs, _Var, Prs, Pvs ) :-
	reverse( APrs, RPrs ),
	kv_consolidate( RPrs, Prs ).
	% dbg( conso_pairs(Prs) ).
bi_unconditional_ind_const_pairs( [DepPrd:PiIn|T], FdIs, Zs, APrs, APvs, Var, Prs, Pvs ) :-
	in_num_to_fraction( PiIn, (DepPrd::PiIn), Pi ),
	dep_unconditional_constraint( DepPrd, FdIs, NrmPrd, Var, Pvar, DepZs ),
	ord_add_element( APvs, Pvar, NxPvs ),
	G = (DepPrd:Pi),
	zs_consistency( Zs, G, DepZs ),
	NxPrs = [Pvar-(NrmPrd:Pi)|APrs],
	bi_unconditional_ind_const_pairs( T, FdIs, Zs, NxPrs, NxPvs, Var, Prs, Pvs ).

bi_unconditional_constraint_pairs( [], _FdIs, _Zs, [], _Var, _Pvar ).
bi_unconditional_constraint_pairs( [DepPrd:PiIn|T], FdIs, Zs, [Hn|Tn], Var, Pvar ) :-
	in_num_to_fraction( PiIn, (DepPrd::PiIn), Pi ),
	dep_unconditional_constraint( DepPrd, FdIs, NrmPrd, Var, Pvar, DepZs ),
	G = (DepPrd:Pi),
	zs_consistency( Zs, G, DepZs ),
	Hn = NrmPrd:Pi,
	% ( Zs == [] -> Hn = NrmPrd:Pi ; Hn = (NrmPrd:Pi)-DepZs ),
	bi_unconditional_constraint_pairs( T, FdIs, Zs, Tn, Var, Pvar ).

% bi_unconditional_constraint( +InConstr, -NormConstr, Var, Zs ) :-
% bi_unconditional_constraint(  (Any1 # Any2), (Var # Val), Var, Pvar, Zs ) :-
	% !,
	% args_to_pfd_vars_and_not( Any1, Any2, '#', Var, Pvar, Val ),
	% well_formed_conditional( Val, (Any1 # Any2), Zs ).
% bi_unconditional_constraint(  (Any1 = Any2), =(Var,Val), Var, Pvar, Zs ) :-
	% !,
	% args_to_pfd_vars_and_not( Any1, Any2, '=', Var, Pvar, Val ),
	% well_formed_conditional( Val, (Any1 = Any2), Zs ).
dep_unconditional_constraint( Cnstr, FdIs, MrkCnstr, MkVar, Pvar, Zs ) :-
	bi_unconditional_constraint( Cnstr, FdIs, MrkCnstr, MarkVars, Pvars, Zs ),
	( (Pvars=[Pvar],MarkVars=[MkVar]) ->
		true
		;
		G  = event(Cnstr), I1 = [], I2 = [], 
		M  = 'There should be at most one pvar in dependent event.',
		print_message( error,
					pfd(8,consistency_error(G,I1,I2,M)) )

	).
bi_unconditional_constraint( Cnstr, FdIs, MrkCnstr, MarkVars, Pvars, Zs ) :-
	Cnstr =.. [Name|Args],
	sieve_n_mark_pvars( Args, [], [], LVars, VarsAndMarks, FdIs, Marked ),
	kv_decompose( VarsAndMarks, Pvars, MarkVars ),
	% sieve_vars( NoPvars, LVars, _RemArgs ),
	% ( Pvars = [Pvar] ->
		% true
		% ;
		( Pvars == [] ->
				G  = event(Cnstr), I1 = [], I2 = Args, 
				M  = 'There should be at least one pvar in event.',
				print_message( error,
					pfd(8,consistency_error(G,I1,I2,M)) )
				;
				true
				% G  = event(Cnstr), I1 = Pvars, I2 = Args, 
				% M  = 'There should be at most one pvar in event.',
				% print_message( error,
					% pfd(8,consistency_error(G,I1,I2,M)) )
		),
	% ),
	G  = event(Cnstr),
	zs_consistency( Zs, G, LVars ),
	MrkCnstr =.. [Name|Marked].

zs_consistency( Zs, G, LVars ) :-
	( var(Zs) -> 
		Zs = LVars
		;
		( memberchk_identical_list( LVars, Zs ) ->
				true
				;
				I1 = LVars, I2 = Zs, 
				M  = 'All lhs logical vars should appear in rhs event.',
				print_message( error,
					pfd(8,consistency_error(G,I1,I2,M)) )
		)
	).

well_formed_conditional( Val, Cnstr, Zs ) :-
	( var(Val) ->
		( var(Zs) ->
			Zs = [Val]
			;
			( Zs==[Val] ->
				true
				;
				G  = lhs_of_conditional(Cnstr),
				I1 = Val, I2 = Zs, 
				M  = 'Logical variable of lhs should appear in rhs.',
				print_message( error,
					pfd(8,consistency_error(G,I1,I2,M)) )
			)
		)
		;
		( var(Zs) -> 
			Zs = []
			;
			true
		)
	).

/* 
% bi_unconditional_constraint( +Constr, -Constr, Var, Val ) :-
% this is targeted to (each of the two) sides of the condiotional,
% at putting in the store point. (as oppose to enforce time.)
%

bi_unconditional_constraint(  diff(Var1,Var2), diff, Vars, Vals ) :-
	args_to_pfd_vars_and_not( Var1, Var2, diff, Vars, Vals ).
bi_unconditional_constraint(  eq(Var1,Var2), eq, Vars, Vals ) :-
	args_to_pfd_vars_and_not( Var1, Var2, eq, Vars, Vals ).
*/

% args_to_pfd_vars_and_not( ?Item1, ?Item2, -Var, -Val ).
% Succeeds iff one of Items is a pfd variable and 
args_to_pfd_vars_and_not( Item1, Item2, Fnctr, _Var, Pvar, Val ) :- 
	( pfd_var(Item1) -> 
		( pfd_var(Item2) -> 
			Goal =.. [Fnctr,Item1,Item2],
			print_message( error, pfd(8,consistency_error(
				Goal, Item1, Item2, 'Only one of operands should be a Pfd variable.')) )
			;
			Pvar = Item1,
			Val = Item2
		)
		;
		( pfd_var(Item2) -> 
			Pvar = Item2, 
			Val = Item1
			;
			Goal =.. [Fnctr,Item1,Item2],
			print_message( error, pfd(8,consistency_error(
				Goal, Item1, Item2, 'At least one of operands should be a Pfd variable.')) )
		)
	).

pfd_to_prolog_predicate( PfdPred, FdIs, PrologPred, PfdVars, PlaceVars ) :-
	pfd_to_prolog_predicate_1( PfdPred, FdIs, PrologPred, [], [], PfdVars, PlaceVars ),
	( var(PrologPred) -> 
		write_message( error, instantiation_error(p(PfdPred)), 1 )
		;
		true
	).

pfd_to_prolog_predicate_1( PfdVar, FdIs, Prolog, AccPfds, AccPrlgs, Pfds, Prlgs ) :-
	pfd_var( PfdVar, FdIs ),
	!,
	Pfds = [PfdVar|AccPfds],
	Prlgs= [Var|AccPrlgs],
	Prolog=Var.
pfd_to_prolog_predicate_1( Var, _FdIs, Prolog, AccPfds, AccPrlgs, Pfds, Prlgs ) :-
	var(Var),
	!,
	Prolog = Var,
	Prlgs = AccPrlgs,
	Pfds = AccPfds.
pfd_to_prolog_predicate_1( [], _FdIs, [], Pfds, Prlgs, Pfds, Prlgs ) :-
	!.
pfd_to_prolog_predicate_1( [H|T], FdIs, [HPg|TPg], AccPfds, AccPrlgs, Pfds, Prlgs ) :-
	!,
	pfd_to_prolog_predicate_1( H, FdIs, HPg, AccPfds, AccPrlgs, NxPfds, NxPrlgs ),
	pfd_to_prolog_predicate_1( T, FdIs, TPg,  NxPfds,  NxPrlgs,   Pfds,   Prlgs ).
pfd_to_prolog_predicate_1( PfdTerm, FdIs, Prolog, AccPfds, AccPrlgs, Pfds, Prlgs ) :-
	PfdTerm =.. [Functr|Args],
	pfd_to_prolog_predicate_1( Args, FdIs, PrologArgs,  AccPfds, AccPrlgs, Pfds, Prlgs ),
	Prolog =.. [Functr|PrologArgs].

unconditional_constraint( Cnstr, RealCnstr, PfdVars, PlaceVars ) :-
	Cnstr =.. [Op|Oprds],
	unconditional_pfd_to_sicstus_op( Op, RealOp ),
	copy_pfd_uncond_operands( Oprds, Cnstr, 1, OprdsCopy, PfdVars, PlaceVars ),
	RealCnstr =.. [RealOp|OprdsCopy].

copy_pfd_uncond_operands( [], _Gl, _N, [], [], [] ).
copy_pfd_uncond_operands( [H|T], Gl, N, [TrH|TrT], PFdIs, PlaceVs ) :-
	( pfd_var(H) -> 
		TrH = FreshVar,
		PlaceVs = [FreshVar|MrPlaceVs],
		PFdIs = [H|MrPFdIs]
		;
		( var(H) ->
			print_message( error, instantiation_error(Gl,N) )
			;
			TrH = H,
			PlaceVs = MrPlaceVs,
			PFdIs = MrPFdIs
		)
	),
	NxtN is N + 1,
	copy_pfd_uncond_operands( T, Gl, NxtN, TrT, MrPFdIs, MrPlaceVs ).

unconditional_pfd_to_sicstus_op( Op, RealOp ) :-
	( Op == '='	-> 
		RealOp = '=='
		;
		( Op == '#'	-> 
			RealOp = '\\=='
			;
			RealOp = Op
		)
	).

%
conditional_constraint( cond_diff(Var1,Var2), [cond_diff,Var1,Var2] ).

% ok this is the minimum check
pfd_var( PfdVar  ) :-
	pfd_var( PfdVar, [] ).
pfd_var( PfdVar, _ ) :-
	atom( PfdVar ),
    atom_concat( _, '_', PfdVar ),
	!.
pfd_var( PfdVar, FdIs  ) :-
	id_memberchk( FdIs, PfdVar ).

is_val( Val ) :-
	atomic( Val ).

mustbe_var( Var ) :-
	( var( Var ) ->
		true
		;
		% this is an internal error. The whole predicate should not be used (maybe)
		% once the system is stable.
		print_message( error, type_error(must_var(Var),1,prolog_variable,Var) )
	).

% 2002da05
data_needs_to_adds_n_qlf( [], _V, _PlV, _Stcs, [], _AQVs, AccPlVs, [], [], [], PlVs, [] )
	:- reverse( AccPlVs, PlVs ).
data_needs_to_adds_n_qlf( [H|T], V, PlV, Stcs, Adds, AcQVs, AcQPlVs, Doms, Qlfs, Frees, PlVs, [Deps|TDps] ) :-
	H = QVs-Deps,
	data_needs_dependent_decompose( Deps, V, PlV, Add, Qlf, QPlVs, Qfree ), 
	Adds = [Add|TAdds],
	Qlfs = [Qlf|TQlfs],
	% Qlfs = [Qlf/Qfree|TQlfs],
	Frees = [Qfree|TQfree],
	SoFar = (Doms,AcQVs,AcQPlVs), 
	NxRound = (NxDoms,NxQVs,NxQPlVs),
	data_cohese_qlf_vars( QVs, QPlVs, Stcs, SoFar, NxRound ),
	data_needs_to_adds_n_qlf( T, V, PlV, Stcs, TAdds, NxQVs, NxQPlVs, NxDoms, TQlfs, TQfree, PlVs, TDps ).

data_cohese_qlf_vars( [], _QPlVs, _Stcs, Reached, Reached ).
data_cohese_qlf_vars( [QV|TQVs], [QPlV|TQPlVs], Stcs, SoFar, FinRound ) :-
	SoFar = (Doms,AcQVs,AcQPlVs), 
	( nth(Nth,AcQVs,QV) ->
		nth(Nth,AcQPlVs,QPlV),
		NxRound = SoFar
		;
		% SoFar = (Doms,QVs,QPlVs),
		( memberchk(QV-HDom,Stcs) ->
			true
			;
			print_message( error, missing_qvar(QV,Stcs) ),
			write( ssttiill ), nl, abort
		),
		Doms = [HDom|TDoms],
		NxRound = (TDoms,[QV|AcQVs],[QPlV|AcQPlVs])
	),
	data_cohese_qlf_vars( TQVs, TQPlVs, Stcs, NxRound, FinRound ).
	% data_cohesedata_needs_to_adds_n_qlf_qlf_vars( TQVs, TQPlVs, Stcs, NxRound, FinRound ).

% data_needs_dependent_decompose( NdTuple, _V, PlV, Add, Qlf, QVs, QPlVs ) :-
data_needs_dependent_decompose( NdTuple, _V, PlV, Add, Qlf, QPlVs, FreeVs ) :-
% data_needs_dependent_decompose( NdTuple, _V, PlV, Add/FreeVs, Qlf, QPlVs, FreeVs ) :-
	% assume all dependent refer to same implit variable (V)
	NdTuple = (Add,_Onevar,Qlf,PlV,QPlVs,FreeVs).
	% NdTuple = (Add,onevar,Qlf,PlV,QPlVs,_Req).

data_needs_has_free( _Var-Tuple, Free ) :-
	Tuple = (_Add,_Onevar,_Qlf,_PlV,_QPlVs,Free).
% interaction with clpfd 
%
fdlist_to_pfd_domain( List, FullFd, Fd ) :-
	fdlist_to_pfd_domain_1( List, 1, FullFd, Fd ).
	
fdlist_to_pfd_domain_1( [], _Idx, _RemFd, [] ).
fdlist_to_pfd_domain_1( [H|T], Idx,  [HRem|TRem], Fd ) :-
	NxIdx is Idx + 1,
	( H =:= Idx ->
		Fd = [HRem|TFd],
		NxList = T
		;
		Fd = TFd,
		NxList = [H|T]
	),
	fdlist_to_pfd_domain_1( NxList, NxIdx,  TRem, TFd ).
	
