os << endl << "           ?? -> ";
os << std::endl << "           ?? -> ";
ostream& operator<<(ostream& os, const Plan& p) {  const Step* init = NULL;  const Step* goal = NULL;  const Bindings* bindings = p.bindings();  vector<const Step*> ordered_steps;  hash_set<size_t> seen_steps;  for (const StepChain* sc = p.steps(); sc != NULL; sc = sc->tail) {    const Step& step = sc->head;    if (step.id() == 0) {      init = &step;    } else if (step.id() == Plan::GOAL_ID) {      goal = &step;    } else if (seen_steps.find(step.id()) == seen_steps.end()) {      seen_steps.insert(step.id());      ordered_steps.push_back(&step);    }  }  hash_map<size_t, float> start_times;  hash_map<size_t, float> end_times;  p.orderings().schedule(start_times, end_times);  sort(ordered_steps.begin(), ordered_steps.end(), StepSorter(start_times));  /*   * Now make sure that nothing scheduled at the same time is   * interfering.  This can only occur if there are link conditions on   * effects, and we can always resolve the threats by arbitrarily   * ordering the interfering steps.  Note, however, that this is not   * necessarily the if there are durative actions.  Because of this   * we never add link conditions when the `:durative-actions'   * requirement flag is present in the domain description, so we   * don't have to worry about it here.   */  const BinaryOrderings* orderings =    dynamic_cast<const BinaryOrderings*>(&p.orderings());  if (orderings != NULL) {    const Orderings& new_orderings =      disable_interference(ordered_steps, p.links(),			   *orderings, *p.bindings_);    if (&new_orderings != &p.orderings()) {      start_times.clear();      end_times.clear();      new_orderings.schedule(start_times, end_times);      sort(ordered_steps.begin(), ordered_steps.end(),	   StepSorter(start_times));    }  }  if (verbosity < 2) {    for (vector<const Step*>::const_iterator si = ordered_steps.begin();	 si != ordered_steps.end(); si++) {      if (verbosity > 0 || si != ordered_steps.begin()) {	os << endl;      }      const Step& s = **si;      os << start_times[s.id()] << ':';      s.action().print(os, s.id(), bindings);      if (s.action().durative()) {	os << '[' << (end_times[s.id()] - start_times[s.id()]) << ']';      }    }  } else {    os << "Initial  :";    const EffectList& effects = init->action().effects();    for (EffectListIter ei = effects.begin(); ei != effects.end(); ei++) {      const AtomList& atoms = (*ei)->add_list();      for (AtomListIter ai = atoms.begin(); ai != atoms.end(); ai++) {	os << ' ' << **ai;      }    }    ordered_steps.push_back(goal);    for (vector<const Step*>::const_iterator si = ordered_steps.begin();	 si != ordered_steps.end(); si++) {      const Step& step = **si;      if (step.id() == Plan::GOAL_ID) {	os << endl << endl << "Goal     : ";      } else {	os << endl << endl << "Step " << step.id();	if (step.id() < 100) {	  if (step.id() < 10) {	    os << ' ';	  }	  os << ' ';	}	os << " : ";	step.action().print(os, step.id(), bindings);      }      for (const LinkChain* lc = p.links(); lc != NULL; lc = lc->tail) {	const Link& link = lc->head;	if (link.to_id() == step.id()) {	  os << endl << "          " << link.from_id();	  if (link.from_id() < 100) {	    if (link.from_id() < 10) {	      os << ' ';	    }	    os << ' ';	  }	  os << " -> ";	  if (bindings != NULL) {	    link.condition().print(os, link.to_id(), *bindings);	  } else {	    os << link.condition();	  }	  for (const UnsafeChain* uc = p.unsafes();	       uc != NULL; uc = uc->tail) {	    const Unsafe& unsafe = uc->head;	    if (unsafe.link() == link) {	      os << " <" << unsafe.step_id() << ">";	    }	  }	}      }      for (const OpenConditionChain* occ = p.open_conds();	   occ != NULL; occ = occ->tail) {	const OpenCondition& open_cond = occ->head;	if (open_cond.step_id() == step.id()) {	  os << endl << "           ?? -> ";	  if (bindings != NULL) {	    open_cond.condition().print(os, open_cond.step_id(), *bindings);	  } else {	    os << open_cond.condition();	  }	}      }    }    os << endl << "orderings = " << p.orderings();    if (bindings != NULL) {      os << endl << "bindings = " << *bindings;    }  }  return os;}