Hi Gustavo,

Gustavo Gutierrez wrote:

I am working on merging a space SC in a S. For this to work i need to
create all actors available in SC into S. This is fine as the Space
class has method to return an iterator on space actors.

Now that's an application of reflection that I hadn't thought of yet. Nice.

I think the
following code will do the job (SC is the source and S is the target):

---- inside the queens class

VarMap * exportVars(void) {
   VarMap *vmp = new VarMap();
   Support::Symbol symb("root",true);
   //vmp->registerArray(this,q,symb);
   vmp->putArray(this,q,symb);
   return vmp;
 }
----

--- outside the class
void merge(Queens *target, Queens *source) {
 // Print some useful information
 std::cout << "Number of propagators in trget " <<
target->propagators() << std::endl;
 std::cout << "Number of propagators in source " <<
source->propagators() << std::endl;

 // Ask source to build a Map of its variables
 VarMap *vmp = target->exportVars();

 // Create an iterator over home's actors
 Reflection::SpecIter si = source->actorSpecs(*vmp);

Gecode::Serialization::Deserializer *ds = new Deserializer(target, *vmp);

 while (si()) {
   ds->post(si.actor());
   ++si;
 }

 // Test the number of actors in target
 std::cout << "Number of propagators in trget " <<
target->propagators() << std::endl;
}
----

Is it right or did i miss something?

It's nearly right. You need a fresh VarMap for the Deserializer. The idea is that the correspondence between variables in source and target is purely by name. So the code could look like this:

void merge(Queens *target, Queens *source) {
  VarMap *vmp = target->exportVars();
  Reflection::SpecIter si = source->actorSpecs(*vmp);

  VarMap vm_target;
  Gecode::Serialization::Deserializer ds(target, vm_target);

  while (si()) {
    ds.post(si.actor());
    ++si;
  }
}

The other step is to create all variables in SC in S. For this part i
have reading the documenttion and found that IntView and SetView
classes have a method called spec that returns an specification of a
variable. For the Queens problem this would be fine as all variables
are IntVars so creating IntView is easy. The problem raises when i
have a collection of variables of different types (an array of
VarBase*) and need to get the specification for each one. Is there any
way to do this?. Note that i don't know each variable's type so
creating the corresponding view is not possible.

After iterating all the actors, vmp will contain all variables in source, and you can iterate them using a VarMapIter. For each variable, you get a VarSpec that tells you what type the variable has. Furthermore, you can use the spec you get to recreate the variable in target:

for (VarMapIter vmi(*vmp); vmi(); ++vmi) {
  ds.var(vmi.var());
}

If you want to link the variables you create to existing variables in target, you just have to put the variables from target into vm_target before iterating vmp. Remember, variables are only identified by the name you give them.

I prefer to ask this before doing some changes to my design, so sorry
if my question sounds a little lazy.By the way, is there some example
that use space serialization or reflection mechanisms?

You can have a look at the file test/int.cc, the cloneWithReflection function might help you. Please keep in mind that the reflection API is still experimental, the interface might change. In fact, if you find things that don't work as you expect, or would like to have additional functionality, please let us know!

Cheers,
        Guido

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
Gecode users mailing list
[EMAIL PROTECTED]
https://www.gecode.org/mailman/listinfo/gecode-users

Reply via email to