Re: [eclipse-clp-users] Propagators with a state

From: Kish Shen <kisshen_at_cisco.com>
Date: Mon, 16 Feb 2009 17:32:58 +0000
Wit Jakuczun wrote:
> 2009/2/16 Kish Shen <kisshen_at_cisco.com>:
>> Wit Jakuczun wrote:
>>
>>> But I would love to have other features:
>>> - initial call of a propagator (could result in suspending). This would be
>>>  especially useful for propagators based on demons.
>> As propagators are normal ECLiPSe goals, you can simply write your
>> propagator such that it is executed once before suspension, something like:
>>
>> propagator(...) :-
>>        do_propagation(....),
>>        suspend(do_propagation(....)...).
>>
> 
> The code looks like that:
> 
> propagator(Vars, state(State0)) :-
>     update_state(Vars, State0, State1),
>     ( ground(Vars) -> check_solution(Vars)
>     ; do_propagate(Vars, State1),
>       suspend(propagator(Vars, state(State1), Susp), 3, Vars->inst, Susp)).
> 
> propagator(Vars, State,  Susp) :-
>     State = state(State0),
>     update_state(Vars, State0, State1),
>     ( ground(Vars) -> kill_suspension(Susp), check_solution(Vars)
>     ; do_propagate(Vars, State1), setarg(1, State, State1)).
> 
> update_state/3 must be called as there can be more that
> one variable instantiated comparing to previous call of a propagator.
> This is due to priorities!
> Now, propagator/2 is called and if there is a need for suspension
> a propagator/3 (demon) is suspended. If there were guarantee
> that propagators are called for each variable change separately
> then I could do as you proposed.
> I hope I clarified the issue.
> 
> Best regards
Hi Wit,

You can avoid writing two versions of propagator by checking if there
is a suspension in the propagator/3 code, e.g.:

propagator(Vars, State) :-
	propagator(Vars, State, _Susp).

propagator(Vars, State, Susp) :-
	State = state(State0),
	update_state(Vars, State0, State1),
	( ground(Vars) ->
		( is_suspension(Susp) -> kill_suspension(Susp) ; true ),
		check_solution(Vars)
	;
		do_propagate(Vars, State1),
		(is_suspension(Susp) ->
			true
		;
			suspend(propagator(Vars, ....)
		)
	).

On a more general point, if I understood you correctly, you are doing 
the update_state/3 in propagator/2 in your original code because the
state can change between calling propagator/2 and executing the goals
in propagator/2, because other propagators can wake up and update the 
State. If this is your concern, then I am not sure if your code would 
avoid the problem, because the update can happen after you do the
update_state/3.

To avoid this problem, you should use call_priority/2 to call
propagator/2 with a higher priority than what you are suspending your
propagators at -- so 2 in your case. In this case, you can also
miss out the initial update_state, and simplify the code a little.

Cheers,

Kish
	
-- 
This e-mail may contain confidential and privileged material for the
sole use of the intended recipient. Any review, use, distribution or
disclosure by others is strictly prohibited. If you are not the intended
recipient (or authorized to receive for the recipient), please contact
the sender by reply e-mail and delete all copies of this message.
Cisco Systems Limited (Company Number: 02558939), is registered in
England and Wales with its registered office at 1 Callaghan Square,
Cardiff, South Glamorgan CF10 5BT.
Received on Mon Feb 16 2009 - 17:33:05 CET

This archive was generated by hypermail 2.2.0 : Thu Feb 02 2012 - 02:31:58 CET