Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix Network Constant
[simgrid.git] / src / surf / solver.cpp
1 #include "solver.hpp"
2
3 #include "xbt/log.h"
4 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_maxmin, surf,
5                                 "Logging specific to SURF (maxmin)");
6
7 static int Global_debug_id = 1;
8 static int Global_const_debug_id = 1;
9
10 Solver::Solver(int selectiveUpdate)
11 {
12   VariablePtr var;
13   ConstraintPtr cnst;
14
15   m_modified = 0;
16   m_selectiveUpdateActive = selectiveUpdate;
17   m_visitedCounter = 1;
18
19   XBT_DEBUG("Setting selective_update_active flag to %d\n",
20          this->m_selectiveUpdateActive);
21
22   /*xbt_swag_init(&(l->variable_set),
23                 xbt_swag_offset(var, variable_set_hookup));
24   xbt_swag_init(&(l->constraint_set),
25                 xbt_swag_offset(cnst, constraint_set_hookup));
26
27   xbt_swag_init(&(l->active_constraint_set),
28                 xbt_swag_offset(cnst, active_constraint_set_hookup));
29
30   xbt_swag_init(&(l->modified_constraint_set),
31                 xbt_swag_offset(cnst, modified_constraint_set_hookup));
32   xbt_swag_init(&(l->saturated_variable_set),
33                 xbt_swag_offset(var, saturated_variable_set_hookup));
34   xbt_swag_init(&(l->saturated_constraint_set),
35                 xbt_swag_offset(cnst, saturated_constraint_set_hookup));
36
37   l->variable_mallocator = xbt_mallocator_new(65536,
38                                               lmm_variable_mallocator_new_f,
39                                               lmm_variable_mallocator_free_f,
40                                               lmm_variable_mallocator_reset_f);*/
41 }
42
43 ConstraintPtr Solver::createConstraint(void *id, double bound)
44 {
45   ConstraintPtr cnst = m_constraintAllocator.construct(id, bound);
46   m_constraintSet.push_back(cnst);
47   return cnst;
48 }
49
50 void Solver::destroyConstraint(Constraint* cnst)
51 {
52   m_constraintAllocator.destroy(cnst);
53 }
54
55
56 VariablePtr Solver::createVariable(void *id, double weight, double bound)
57 {
58   void *mem = m_variableAllocator.malloc();
59   VariablePtr var = new (mem) Variable(id, weight, bound, m_visitedCounter - 1);
60   var->m_visited = m_visitedCounter - 1;
61   if (weight)
62     m_variableSet.insert(m_variableSet.begin(), var);
63   else
64     m_variableSet.push_back(var);
65   return var;
66 }
67
68 void Solver::destroyVariable(Variable* var)
69 {
70   m_variableAllocator.destroy(var);
71 }
72
73 void Solver::destroyElement(Element* elem)
74 {
75   m_elementAllocator.destroy(elem);
76 }
77
78 void Solver::expand(ConstraintPtr cnst, VariablePtr var,  double value)
79 {
80   m_modified = 1;
81   
82   ElementPtr elem = m_elementAllocator.construct(cnst, var, value);
83   var->m_cnsts.push_back(elem);
84
85   if (var->m_weight)
86     cnst->m_elementSet.insert(cnst->m_elementSet.begin(), elem);
87   else
88     cnst->m_elementSet.push_back(elem);
89   if(!m_selectiveUpdateActive) {
90     activateConstraint(cnst);
91   } else if(value>0 || var->m_weight >0) {
92     activateConstraint(cnst);
93     updateModifiedSet(cnst);
94     if (var->m_cnsts.size() > 1)
95       updateModifiedSet(var->m_cnsts.front()->p_constraint);
96   }
97 }
98
99 void Solver::expandAdd(ConstraintPtr cnst, VariablePtr var,  double value)
100 {
101   m_modified = 1;
102
103   std::vector<ElementPtr>::iterator it;
104   for (it=var->m_cnsts.begin(); it!=var->m_cnsts.end(); ++it )
105     if ((*it)->p_constraint == cnst)
106       break;
107   
108   if (it != var->m_cnsts.end()) {
109     if (cnst->isShared())
110       (*it)->m_value += value;
111     else 
112       (*it)->m_value = MAX((*it)->m_value, value);
113     updateModifiedSet(cnst);
114   } else
115     expand(cnst, var, value);
116 }
117
118 void Solver::elementSetValue(ConstraintPtr cnst, VariablePtr var, double value)
119 {
120   std::vector<ElementPtr>::iterator it;
121   for (it=var->m_cnsts.begin(); it!=var->m_cnsts.end(); ++it ) {
122     ElementPtr elem = (*it);
123     if (elem->p_constraint == cnst) {
124       elem->m_value = value;
125       m_modified = 1;
126       updateModifiedSet(cnst);
127     }
128   }
129   if (it==var->m_cnsts.end()) {
130     DIE_IMPOSSIBLE;
131   }
132 }
133
134 //XBT_INLINE 
135 ConstraintPtr Variable::getCnst(int num)
136 {
137   if (num < m_cnsts.size())
138     return m_cnsts.at(num)->p_constraint;
139   else {
140     ConstraintPtr res;
141     return res;
142   }
143 }
144
145 //XBT_INLINE
146 double Variable::getCnstWeight(int num)
147 {
148   if (num < m_cnsts.size())
149     return (m_cnsts.at(num)->m_value);
150   else
151     return 0.0;
152 }
153
154 //XBT_INLINE 
155 int Variable::getNumberOfCnst()
156 {
157   return m_cnsts.size();
158 }
159
160 VariablePtr Constraint::getVar(ElementPtr elem)
161 {
162   vector<ElementPtr>::iterator it;
163   if (!elem)
164     elem = m_elementSet.front();
165   else
166     elem = *(++find(m_elementSet.begin(), m_elementSet.end(), elem));
167   if (elem)
168     return elem->p_variable;
169   else {
170     VariablePtr res;
171     return res;
172   }
173 }
174
175 //XBT_INLINE
176 void* Constraint::id()
177 {
178   return p_id;
179 }
180
181 //XBT_INLINE
182 void* Variable::id()
183 {
184   return p_id;
185 }
186
187 //static XBT_INLINE
188 void Solver::saturatedConstraintSetUpdate(double usage,
189                                   ConstraintLightPtr cnstLight,
190                                   vector<ConstraintLightPtr> saturatedConstraintSet,
191                                   double *minUsage)
192 {
193   xbt_assert(usage > 0,"Impossible");
194   
195   if (*minUsage < 0 || *minUsage > usage) {
196     *minUsage = usage;
197     saturatedConstraintSet.clear();
198     saturatedConstraintSet.push_back(cnstLight);
199     XBT_HERE(" min_usage=%f (cnst->remaining / cnst->usage =%f)", *minUsage, usage);
200   } else if (*minUsage == usage) {
201     saturatedConstraintSet.push_back(cnstLight);
202   }
203 }
204
205 //static XBT_INLINE
206 void Solver::saturatedVariableSetUpdate(vector<ConstraintLightPtr> cnstLightList,
207                                         vector<ConstraintLightPtr> saturatedCnstSet)
208 {
209   ConstraintLight* cnst = NULL;
210   Element* elem = NULL;
211   vector<ElementPtr>* elem_list;
212   std::vector<ConstraintLightPtr>::iterator it;
213   std::vector<ElementPtr>::iterator elemIt;
214   for (it=saturatedCnstSet.begin(); it!=saturatedCnstSet.end(); ++it) {
215     cnst = (*it);
216     elem_list = &(cnst->p_cnst->m_activeElementSet);
217     for (elemIt=elem_list->begin(); elemIt!=elem_list->end(); ++elemIt) {
218       elem = (*elemIt);
219       if (elem->p_variable->m_weight <= 0)
220         break;
221       if (elem->m_value >0)
222         m_saturatedVariableSet.push_back(elem->p_variable);
223     }
224   }
225 }
226
227 void Element::activate()
228 {
229   p_constraint->m_activeElementSet.push_back(this);
230 }
231
232 void Element::inactivate()
233 {
234   std::vector<ElementPtr>::iterator it;
235   vector<ElementPtr> elemSet = p_constraint->m_activeElementSet;  
236   it = find(elemSet.begin(), elemSet.end(), this);
237   if (it != elemSet.end())
238     elemSet.erase(it);
239 }
240
241 void Solver::activateConstraint(ConstraintPtr cnst)
242 {
243   m_activeConstraintSet.push_back(cnst);
244 }
245
246 void Solver::inactivateConstraint(ConstraintPtr cnst)
247 {
248   std::vector<ConstraintPtr>::iterator it;
249   it = find(m_activeConstraintSet.begin(), m_activeConstraintSet.end(), cnst);
250   if (it != m_activeConstraintSet.end())
251     m_activeConstraintSet.erase(it);
252   m_modifiedConstraintSet.erase(std::find(m_modifiedConstraintSet.begin(), m_modifiedConstraintSet.end(), cnst));
253 }
254
255 template <class T>
256 void vector_remove_first(vector<T> vec, T obj) {
257   typename vector<T>::iterator it;
258   for (it=vec.begin(); it != vec.end(); ++it) {
259     if ((*it) == (obj)) {
260       vec.erase(it);
261       break;
262     }
263   }
264 }
265
266 void Solver::print()
267 {
268   //TODO
269 }
270
271 void Solver::solve()
272 {
273   Variable* var = NULL;
274   Constraint* cnst = NULL;
275   Element* elem = NULL;
276   vector<ConstraintPtr>* cnstList = NULL;
277   std::vector<ConstraintPtr>::iterator cnstIt;
278   vector<VariablePtr>* varList = NULL;
279   std::vector<VariablePtr>::iterator varIt;    
280   vector<ElementPtr>* elemList = NULL;
281   std::vector<ElementPtr>::iterator elemIt;
282   vector<ElementPtr>* elemListB = NULL;
283   std::vector<ElementPtr>::iterator elemItB;
284   double minUsage = -1;
285   double minBound = -1;
286
287   if (!m_modified)
288     return;
289
290   XBT_IN("(sys=%p)", this);
291
292   /*
293    * Compute Usage and store the variables that reach the maximum.
294    */
295   cnstList = m_selectiveUpdateActive ? &m_modifiedConstraintSet :
296                                        &m_activeConstraintSet;
297
298   XBT_DEBUG("Active constraintsSolver : %d", cnstList->size());
299   /* Init: Only modified code portions */
300   
301   for (cnstIt=cnstList->begin(); cnstIt!=cnstList->end(); ++cnstIt) {
302     elemList = &((*cnstIt)->m_elementSet);
303     for (elemIt=elemList->begin(); elemIt!=elemList->end(); ++elemIt) {
304       var = ((*elemIt)->p_variable);
305       if (var->m_weight <= 0.0)
306         break;
307       var->m_value = 0.0;
308     }
309   }
310
311   vector<ConstraintLightPtr> cnstLightList;
312   std::vector<ConstraintLightPtr>::iterator cnstLightIt;
313
314   vector<ConstraintLightPtr> saturatedConstraintSet;
315   saturatedConstraintSet.reserve(5);
316   
317   for (cnstIt=cnstList->begin(); cnstIt!=cnstList->end(); ++cnstIt) {
318     /* INIT */
319     cnst = (*cnstIt);
320     if (cnst->m_remaining == 0)
321       continue;
322     cnst->m_usage = 0;
323     elemList = &(cnst->m_elementSet);
324     for (elemIt=elemList->begin(); elemIt!=elemList->end(); ++elemIt) {
325       /* 0-weighted elements (ie, sleep actions) are at the end of the swag and we don't want to consider them */
326       elem = (*elemIt);
327       if (elem->p_variable->m_weight <= 0)
328         break;
329       if ((elem->m_value > 0)) {
330         if (cnst->m_shared)
331           cnst->m_usage += elem->m_value / elem->p_variable->m_weight;
332         else if (cnst->m_usage < elem->m_value / elem->p_variable->m_weight)
333           cnst->m_usage = elem->m_value / elem->p_variable->m_weight;
334
335         elem->activate();
336         if (m_keepTrack.size()) //TODO: check good semantic
337           m_keepTrack.push_back(elem->p_variable->p_id);
338       }
339     }
340     XBT_DEBUG("Constraint Usage '%d' : %f", cnst->m_idInt, cnst->m_usage);
341     /* Saturated constraints update */
342     if(cnst->m_usage > 0) {
343       ConstraintLightPtr cnstLight (new ConstraintLight((*cnstIt), cnst->m_remaining / cnst->m_usage));
344       cnst->p_cnstLight = cnstLight;
345       saturatedConstraintSetUpdate(cnstLight->m_remainingOverUsage, cnstLight, saturatedConstraintSet, &minUsage);
346       cnstLightList.push_back(cnstLight);      
347     }
348   }
349
350   saturatedVariableSetUpdate(cnstLightList, saturatedConstraintSet);
351
352   /* Saturated variables update */
353   do {
354     /* Fix the variables that have to be */
355     varList = &m_saturatedVariableSet;
356
357     for (varIt=varList->begin(); varIt!=varList->end(); ++varIt) {
358       var = (*varIt);
359       if (var->m_weight <= 0.0) {
360         DIE_IMPOSSIBLE;
361       }
362       /* First check if some of these variables have reach their upper
363          bound and update min_usage accordingly. */
364       XBT_DEBUG
365           ("var=%d, var->bound=%f, var->weight=%f, min_usage=%f, var->bound*var->weight=%f",
366            var->m_idInt, var->m_bound, var->m_weight, minUsage,
367            var->m_bound * var->m_weight);
368
369       if ((var->m_bound > 0) && (var->m_bound * var->m_weight < minUsage)) {
370         if (minBound < 0)
371           minBound = var->m_bound;
372         else
373           minBound = MIN(minBound, var->m_bound);
374         XBT_DEBUG("Updated min_bound=%f", minBound);
375       }
376     }
377
378     while (varList->size()>0) {
379       var = varList->front();
380       int i;
381
382       if (minBound < 0) {
383         var->m_value = minUsage / var->m_weight;
384       } else {
385         if (minBound == var->m_bound)
386           var->m_value = var->m_bound;
387         else {
388           vector_remove_first(*varList, varList->front());
389           continue;
390         }
391       }
392       XBT_DEBUG("Min usage: %f, Var(%d)->weight: %f, Var(%d)->value: %f ",
393              minUsage, var->m_idInt, var->m_weight, var->m_idInt, var->m_value);
394
395       /* Update usage */
396
397       for (elemIt=var->m_cnsts.begin(); elemIt!=var->m_cnsts.end(); ++elemIt) {
398         elem = (*elemIt);
399         cnst = elem->p_constraint;
400         if (cnst->m_shared) {
401           double_update(&(cnst->m_remaining), elem->m_value * var->m_value);
402           double_update(&(cnst->m_usage), elem->m_value / var->m_weight);
403           if(cnst->m_usage<=0 || cnst->m_remaining<=0) {
404             if (cnst->p_cnstLight) {
405               // TODO: reformat message
406               XBT_DEBUG("index: %d \t cnst_light_num: %d \t || \t cnst: %p \t cnst->cnst_light: %p \t cnst_light_tab: %p ",
407                   elemIt - var->m_cnsts.begin(), var->m_cnsts.size(), cnst, cnst->p_cnstLight, &cnstLightList);
408               vector_remove_first(cnstLightList, cnst->p_cnstLight);
409               cnst->p_cnstLight = ConstraintLightPtr();
410             }
411           } else {
412             cnst->p_cnstLight->m_remainingOverUsage = cnst->m_remaining / cnst->m_usage;
413           }
414           elem->inactivate();
415         } else {
416           cnst->m_usage = 0.0;
417           elem->inactivate();
418           elemListB = &(cnst->m_elementSet);
419           for (elemItB=elemListB->begin(); elemItB!=elemListB->end(); ++elemItB) {
420             elem = (*elemItB);
421             if (elem->p_variable->m_weight <= 0 || elem->p_variable->m_value > 0)
422               break;
423             if (elem->m_value > 0)
424               cnst->m_usage = MAX(cnst->m_usage, elem->m_value / elem->p_variable->m_weight);
425           }
426           if (cnst->m_usage<=0 || cnst->m_remaining<=0) {
427             if(cnst->p_cnstLight) {
428               vector_remove_first(cnstLightList, cnst->p_cnstLight);
429               // TODO: reformat message       
430               XBT_DEBUG("index: %d \t cnst_light_num: %d \t || \t cnst: %p \t cnst->cnst_light: %p \t cnst_light_tab: %p ",
431                   elemIt - var->m_cnsts.begin(),  var->m_cnsts.size(), cnst, cnst->p_cnstLight, &cnstLightList);
432               cnst->p_cnstLight = ConstraintLightPtr();
433             }
434           } else {
435             cnst->p_cnstLight->m_remainingOverUsage = cnst->m_remaining / cnst->m_usage;
436           }
437         }
438       }
439       vector_remove_first(*varList, varList->front());
440     }
441
442     /* Find out which variables reach the maximum */
443     minUsage = -1;
444     minBound = -1;
445     m_saturatedConstraintSet.clear();
446
447     for (cnstLightIt=cnstLightList.begin(); cnstLightIt!=cnstLightList.end(); ++cnstLightIt)
448       saturatedConstraintSetUpdate((*cnstLightIt)->m_remainingOverUsage, 
449                                    (*cnstLightIt),
450                                     saturatedConstraintSet,
451                                     &minUsage);
452     saturatedVariableSetUpdate(cnstLightList, saturatedConstraintSet);
453
454   } while (cnstLightList.size() > 0);
455
456   m_modified = 0;
457
458   if (m_selectiveUpdateActive)
459     removeAllModifiedSet();
460   
461
462   if (m_selectiveUpdateActive)
463     removeAllModifiedSet();
464
465   if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
466     print();
467   }
468
469   /*TODO: xbt_free(saturated_constraint_set->data);
470   xbt_free(saturated_constraint_set);
471   xbt_free(cnst_light_tab);*/
472   XBT_OUT();
473 }
474
475 /* Not a O(1) function */
476
477 void Solver::update(ConstraintPtr cnst, VariablePtr var, double value)
478 {
479   std::vector<ElementPtr>::iterator it;
480   for (it=var->m_cnsts.begin(); it!=var->m_cnsts.end(); ++it )
481     if ((*it)->p_constraint == cnst) {
482       (*it)->m_value = value;
483       m_modified = true;
484       updateModifiedSet(cnst);
485       return;
486     }
487 }
488
489 /** \brief Attribute the value bound to var->bound.
490  * 
491  *  \param sys the lmm_system_t
492  *  \param var the lmm_variable_t
493  *  \param bound the new bound to associate with var
494  * 
495  *  Makes var->bound equal to bound. Whenever this function is called 
496  *  a change is  signed in the system. To
497  *  avoid false system changing detection it is a good idea to test 
498  *  (bound != 0) before calling it.
499  *
500  */
501 void Solver::updateVariableBound(VariablePtr var, double bound)
502 {
503   m_modified = 1;
504   var->m_bound = bound;
505
506   if (var->m_cnsts.size() > 0)
507     updateModifiedSet(var->m_cnsts.front()->p_constraint);
508 }
509
510 void Solver::updateVariableWeight(VariablePtr var, double weight)
511 {
512   int i;
513
514   if (weight == var->m_weight)
515     return;
516   XBT_IN("(sys=%p, var=%p, weight=%f)", this, var, weight);
517   m_modified = 1;
518   var->m_weight = weight;
519   vector_remove_first(m_variableSet, var);
520   if (weight) // TODO: use swap instead
521     m_variableSet.insert(m_variableSet.begin(), var);
522   else
523     m_variableSet.push_back(var);
524
525   vector<ElementPtr> elemList;
526   vector<ElementPtr>::iterator it;
527   for (it=var->m_cnsts.begin(); it!=var->m_cnsts.end(); ++it ) {
528     elemList = (*it)->p_constraint->m_elementSet;
529     vector_remove_first(elemList, (*it));
530     if (weight)
531       elemList.insert(elemList.begin(), *it);
532     else
533       elemList.push_back(*it);
534     if (it == var->m_cnsts.begin())
535       updateModifiedSet((*it)->p_constraint);
536   }
537   if (!weight)
538     var->m_value = 0.0;
539
540   XBT_OUT();
541 }
542
543 double Variable::getWeight()
544 { return m_weight; }
545
546 //XBT_INLINE
547 void Solver::updateConstraintBound(ConstraintPtr cnst, double bound)
548 {
549   m_modified = 1;
550   updateModifiedSet(cnst);
551   cnst->m_bound = bound;
552 }
553
554 //XBT_INLINE
555 bool Solver::constraintUsed(ConstraintPtr cnst)
556 {
557   return std::find(m_activeConstraintSet.begin(),
558                    m_activeConstraintSet.end(), cnst)!=m_activeConstraintSet.end();
559 }
560
561 //XBT_INLINE
562 ConstraintPtr Solver::getFirstActiveConstraint()
563 {
564   return m_activeConstraintSet.front();
565 }
566
567 //XBT_INLINE 
568 ConstraintPtr Solver::getNextActiveConstraint(ConstraintPtr cnst)
569 {
570   return *(++std::find(m_activeConstraintSet.begin(), m_activeConstraintSet.end(), cnst));
571 }
572
573 #ifdef HAVE_LATENCY_BOUND_TRACKING
574 //XBT_INLINE 
575 bool Variable::isLimitedByLatency()
576 {
577   return (double_equals(m_bound, m_value));
578 }
579 #endif
580
581 /** \brief Update the constraint set propagating recursively to
582  *  other constraints so the system should not be entirely computed.
583  *
584  *  \param sys the lmm_system_t
585  *  \param cnst the lmm_constraint_t affected by the change
586  *
587  *  A recursive algorithm to optimize the system recalculation selecting only
588  *  constraints that have changed. Each constraint change is propagated
589  *  to the list of constraints for each variable.
590  */
591 //static 
592 void Solver::updateModifiedSetRec(ConstraintPtr cnst)
593 {
594   std::vector<ElementPtr>::iterator elemIt;
595   for (elemIt=cnst->m_elementSet.begin(); elemIt!=cnst->m_elementSet.end(); ++elemIt) {
596     VariablePtr var = (*elemIt)->p_variable;
597     vector<ElementPtr> cnsts = var->m_cnsts;
598     std::vector<ElementPtr>::iterator cnstIt;
599     for (cnstIt=cnsts.begin(); var->m_visited != m_visitedCounter 
600         && cnstIt!=cnsts.end(); ++cnstIt){
601       if ((*cnstIt)->p_constraint != cnst
602           && std::find(m_modifiedConstraintSet.begin(),
603                    m_modifiedConstraintSet.end(), (*cnstIt)->p_constraint)
604              == m_modifiedConstraintSet.end()) {
605         m_modifiedConstraintSet.push_back((*cnstIt)->p_constraint);
606         updateModifiedSetRec((*cnstIt)->p_constraint);
607       }
608     }
609     var->m_visited = m_visitedCounter;
610   }
611 }
612
613 //static
614 void Solver::updateModifiedSet(ConstraintPtr cnst)
615 {
616   /* nothing to do if selective update isn't active */
617   if (m_selectiveUpdateActive
618       && std::find(m_modifiedConstraintSet.begin(),
619                    m_modifiedConstraintSet.end(), cnst)
620          == m_modifiedConstraintSet.end()) {
621     m_modifiedConstraintSet.push_back(cnst);
622     updateModifiedSetRec(cnst);
623   }
624 }
625
626 /** \brief Remove all constraints of the modified_constraint_set.
627  *
628  *  \param sys the lmm_system_t
629  */
630 //static 
631 void Solver::removeAllModifiedSet()
632 {
633   if (++m_visitedCounter == 1) {
634     /* the counter wrapped around, reset each variable->visited */
635     std::vector<VariablePtr>::iterator it;
636     for (it=m_variableSet.begin(); it!=m_variableSet.end(); ++it)
637       (*it)->m_visited = 0;
638   }
639   m_modifiedConstraintSet.clear();
640 }
641
642 inline void Solver::disableVariable(VariablePtr var)
643 {
644   int i;
645   bool m = false;
646
647   ElementPtr elem;
648
649   XBT_IN("(sys=%p, var=%p)", this, var);
650   m_modified = 1;
651   
652   std::vector<ElementPtr>::iterator varIt, elemIt;
653   for (varIt=var->m_cnsts.begin(); varIt!=var->m_cnsts.end();  ) {
654     vector<ElementPtr> elemSet = (*varIt)->p_constraint->m_elementSet;
655     elemSet.erase(std::find(elemSet.begin(), elemSet.end(), *varIt));
656     vector<ElementPtr> activeElemSet = (*varIt)->p_constraint->m_activeElementSet;
657     activeElemSet.erase(std::find(activeElemSet.begin(), activeElemSet.end(), *varIt));
658     if (elemSet.empty()) {
659       inactivateConstraint((*varIt)->p_constraint);
660       var->m_cnsts.erase(varIt);
661     } else {
662       ++varIt;
663       m = true;
664     }
665   }
666   if (m)
667     updateModifiedSet(var->m_cnsts.front()->p_constraint);
668   var->m_cnsts.clear();
669
670   XBT_OUT();
671 }
672
673 Constraint::Constraint(void *id, double bound): 
674   p_id(id), m_idInt(1), m_bound(bound), m_usage(0), m_shared(1),
675   m_elementsZeroWeight(0)
676 {
677   m_idInt = Global_const_debug_id++;
678 }
679
680 void Constraint::addElement(ElementPtr elem)
681 {
682   m_elementSet.push_back(elem);
683   if (elem->p_variable->m_weight<0)
684     std::swap(m_elementSet[m_elementSet.size()-1], m_elementSet[m_elementsZeroWeight++]);
685 }
686
687 void Constraint::shared() {
688   m_shared = 0;
689 }
690
691 bool Constraint::isShared() {
692   return m_shared;
693 }
694
695 Variable::Variable(void *id, double weight, double bound, int visited)
696 {
697   int i;
698
699   // TODO: reformat
700   XBT_IN("(sys=%p, id=%p, weight=%f, bound=%f, num_cons =%d)",
701            0, id, weight, bound, 0);
702
703   p_id = id;
704   m_idInt = Global_debug_id++;
705   
706   // TODO: optimize cache 
707
708   m_weight = weight;
709   m_bound = bound;
710   m_value = 0.0;
711   m_visited = visited;//sys->visited_counter - 1;
712   m_mu = 0.0;
713   m_newMu = 0.0;
714   //m_func_f = func_f_def;
715   //m_func_fp = func_fp_def;
716   //m_func_fpi = func_fpi_def;
717
718
719   XBT_OUT(" returns %p", this);
720 }
721
722 double Variable::value()
723 {
724   return m_value;
725 }
726
727 double Variable::bound()
728 {
729   return m_bound;
730 }
731
732 Element::Element(ConstraintPtr cnst, VariablePtr var, double value):
733   p_constraint(cnst), p_variable(var), m_value(value)
734 {}
735