//
// Copyright (c) 2009 Froduald Kabanza and the Université de Sherbrooke.
// Use of this software is permitted for non-commercial research purposes, and
// it may be copied or applied only for that use. All copies must include this
// copyright message.
// 
// This is a research prototype that has not gone through intensive tests and
// is delivered as is. It may still contain bugs. Froduald Kabanza and the
// Université de Sherbrooke disclaim any responsibility for damage that may be
// caused by using it.
//
// Please note that this file was inspired in part by the PDDL4J library:
// http://www.math-info.univ-paris5.fr/~pellier/software/software.php 
//
// Implementation: Daniel Castonguay
// Project Manager: Froduald Kabanza
//

#include "stdafx.h"
#include "TemporalImplyExp.h"
#include "TemporalNotExp.h"

using namespace planning;

TemporalImplyExp::TemporalImplyExp(const ITemporalExp* antecedent, const ITemporalExp* consequent)
  : TemporalOrExp(new TemporalNotExp(antecedent), consequent), m_antecedent(antecedent), m_consequent(consequent)
{
  m_antecedent->acquire(this);
  m_consequent->acquire(this);

  INITIALIZE_HASH_CODE();
}

TemporalImplyExp::~TemporalImplyExp()
{
  m_antecedent->release(this);
  m_consequent->release(this);
}

//ProgressionValue TemporalImplyExp::progress(const IDurativeClosedWorld* world, const Bindings* bindings) const
//{
//  // return ~m_antecedent.Progress(world, bindings) || m_consequent.Progress(world, bindings);
//
//  ProgressionValue antecedentSuffix = m_antecedent->progress(world, bindings);
//  if (antecedentSuffix.isFalse())
//    return ProgressionValue(true);
//  else if (antecedentSuffix.isTrue())
//    return m_consequent->progress(world, bindings);
//  else
//  {
//    ProgressionValue consequentSuffix = m_consequent->progress(world, bindings);
//    if (consequentSuffix.isTrue())
//      return ProgressionValue(true);
//    else if (consequentSuffix.isFalse())
//      return ProgressionValue(new TemporalNotExp(antecedentSuffix.getExp()));   
//    else
//      return ProgressionValue(new TemporalImplyExp(antecedentSuffix.getExp(), consequentSuffix.getExp()));
//  }
//}
//
//bool TemporalImplyExp::evaluateIdle(const IDurativeClosedWorld* world, const Bindings* bindings) const
//{
//  // return ~m_antecedent.EvaluateIdle(idleWorld, bindings) || m_consequent.EvaluateIdle(idleWorld, bindings);
//
//  return !m_antecedent->evaluateIdle(world, bindings) || m_consequent->evaluateIdle(world, bindings);
//}

const IExp* TemporalImplyExp::_internalApply(const Bindings* bindings) const
{
  return new TemporalImplyExp(m_antecedent->apply(bindings), m_consequent->apply(bindings));
}

void TemporalImplyExp::_output(std::ostream& out) const
{
  out << "(implies " << *m_antecedent << " " << *m_consequent << ")";
}

int TemporalImplyExp::_internalCompareTo(const IExp& other) const
{
  const TemporalImplyExp& exp = dynamic_cast<const TemporalImplyExp&>(other);

  COMPARE(m_antecedent, exp.m_antecedent);

  COMPARE(m_consequent, exp.m_consequent);

  return 0;
}
