% 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 ).