[gecode-users] assert in propagator cast

Christian Schulte cschulte at kth.se
Mon Nov 7 10:23:43 CET 2011


Hi David,

What still could have happened is that you disposed the advisor without
cancelling this one out of five subscriptions. In that case there still
would a subscription left and there would be no possibility to cancel it as
the advisor has been removed from the council (this is a side-effect of
disposing an advisor, it gets removed from its council).

Christian

--
Christian Schulte, KTH, web.it.kth.se/~cschulte/

-----Original Message-----
From: David Rijsman [mailto:David.Rijsman at quintiq.com] 
Sent: Friday, November 04, 2011 2:54 PM
To: users at gecode.org; cschulte at kth.se
Subject: RE: [gecode-users] assert in propagator cast

Hi Christian,

in my case the dispose of the advisor is the one that cancels the
subscription to the variable.  The dispose of the propagator is the one that
disposes the council (and the council disposes the advisors still in the
council). So I think I dispose (and cancel) enough. The assert was raised
when I only disposed 4 (any subset) out of 5 of the advisors related to a
task for which the boolean turned false. I fixed this to 5 and the problem
no longer happens. I just can not figure out why the assert was raised
especially it should not hurt to wait with disposing of an individual
advisor until the council disposes. I will keep searching and post when I
find something,

David Rijsman

>>> 
From: 	"Christian Schulte" <cschulte at kth.se>
To:	"'David Rijsman'" <David.Rijsman at quintiq.com>, <users at gecode.org>
Date: 	11/4/2011 12:50 PM
Subject: 	RE: [gecode-users] assert in propagator cast

Hi David,

Ok, let's see: when the Boolean variable becomes assigned you dispose the
advisors. But do you also cancel the subscriptions?

As you correctly observed, some advisors have a dispose function that also
does the cancel. If an advisor has a dispose function that does not cancel,
then the cancel has to be done manually.

For assigned views, subscriptions do not need to be cancelled but advisors
still must be disposed. You might do that in the advise() function or in the
dispose() function but have to be careful to only do it once!

Please let me know whether this helps.

Best
Christian

--
Christian Schulte, www.ict.kth.se/~cschulte/ 


-----Original Message-----
From: users-bounces at gecode.org [mailto:users-bounces at gecode.org] On Behalf
Of David Rijsman
Sent: Friday, November 04, 2011 11:44 AM
To: users at gecode.org; cschulte at kth.se
Subject: Re: [gecode-users] assert in propagator cast

Hi Christian,

a little bit delayed but yes you are pretty close with your guessing. I do
step 1 and step 2 I do cancel the subscription. Also in the dispose method
of the propagator I invoke the dispose method of the council. 

Should I also cancel all the subscriptions of the variables to the advisors
in the propagators dispose although I invoke the dispose on the council? I
checked the dispose of the council and it also invokes the dispose of the
advisors which in my case do cancel the subscriptions.

In the example  in gecode/int/bool/or.hpp you are using the advisor type
Advisor in which the cancellation does not take place (in my case it does in
the specialized implementation of dispose) so I understand the need to
explicitly do it in the dispose of the propagator in your case. But I do not
see it in my case....

To give you a little more background, I have a propagator working on tasks,
each task has five variables of which one is a boolean. When the boolean
becomes false I want to dispose all the advisors on all the five variables
associated with this task. When the boolean becomes false, in the advise of
the propagator I iterate over all the advisors in the council, cast them to
my advisor type, ask the advisor if it belongs to the same task as the
boolean, if so it is disposed. I had made an optimization which would stop
iterating over the advisors once it disposed  four, this is a mistake as it
could have found the advisor of the boolean itself and dispose it, now if I
exclude the explicit disposal of the advisor of the boolean variable the
problem no longer occurs. I am a little puzzled here how this is related to
the assert being raised (a double disposal also raises an assert and I do
not see this), I will continue my search but if you have any suggestions
that would be great,

Another question for my understanding, who is (responsible for) disposing
the advisor when a variable becomes assigned?

thanks,

David Rijsman

>>> 
From: 	"Christian Schulte" <cschulte at kth.se>
To:	"'David Rijsman'" <David.Rijsman at quintiq.com>, <users at gecode.org>
Date: 	10/25/2011 5:48 PM
Subject: 	Re: [gecode-users] assert in propagator cast

Hi David,

Let me do some guessing here:

1) You are using a propagator that uses advisors.
2) The dispose method of your advisors does not unsubscribe the advisor from
the view.
3) The propagator's dispose method disposes the advisors' council without
deleting the advisors subscriptions

Bang! Is that correct?

If yes, there are two ways to fix it:
a) The dispose method of the advisors also unsubscribes, or
b) In the propagator's dispose method you iterate over all advisors and
unsubscribe (The iterator is called Advisors<A> where A is the type of the
advisor). You might want to search for Advisors in gecode/int/bool/or.hpp
for an example.

I hope that helps!

Best
Christian

PS: Sorry for the delay, I was travelling.

--
Christian Schulte, KTH, web.it.kth.se/~cschulte/


-----Original Message-----
From: users-bounces at gecode.org [mailto:users-bounces at gecode.org] On Behalf
Of David Rijsman
Sent: Monday, October 24, 2011 3:34 PM
To: users at gecode.org
Subject: [gecode-users] assert in propagator cast

I need some help with an assert being thrown by Gecode, hopefully by an
error I made in a propagator I have created. Is there an obvious candidate
for an error I made in my propagator when this assert is thrown?

The assert is thrown in core.hpp

  forceinline Propagator&
  Advisor::propagator(void) const {
    assert(!disposed());
    return *Propagator::cast(ActorLink::prev());
  }

as a result of an invocation of  Advisor::cast(*a)->propagator().afc() in:


  template<class VIC>
  forceinline double
  VarImp<VIC>::afc(void) const {
    if (degree() == 0)
      return 0.0;
    double d = degree();
    // Count the afc of each propagator
    {
      ActorLink** a = const_cast<VarImp<VIC>*>(this)->actor(0);
      ActorLink** e =
const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
      while (a < e) {
        d += Propagator::cast(*a)->afc(); a++;
      }
    }
    // Count the afc of each advisor's propagator
    {
      ActorLink** a =
const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
      ActorLink** e = const_cast<VarImp<VIC>*>(this)->base+entries;
      while (a < e) {
        d += Advisor::cast(*a)->propagator().afc(); a++;
      }
    }
    return d;
  }

thanks,

David Rijsman


_______________________________________________
Gecode users mailing list
users at gecode.org
https://www.gecode.org/mailman/listinfo/gecode-users 


_______________________________________________
Gecode users mailing list
users at gecode.org 
https://www.gecode.org/mailman/listinfo/gecode-users 


_______________________________________________
Gecode users mailing list
users at gecode.org 
https://www.gecode.org/mailman/listinfo/gecode-users 






More information about the users mailing list