/**
 * 最初の著者:: トゥイー
 * リポジトリ情報:: $Id: ConditionalVariable.hpp 11 2011-05-14 02:11:18Z yutaka_at_home $
 * 著作権:: Copyright (C) Ownway.info, 2011. All rights reserved.
 * ライセンス:: CPL(Common Public Licence)
 */

#ifndef _TOPS_CONDITIONAL_VARIABLE_HPP_
#define _TOPS_CONDITIONAL_VARIABLE_HPP_

#include "tops/value/Value.hpp"
#include "tops/value/Variable.hpp"

namespace tops {

	/**
	 * 比較演算子の種類を示す列挙形です。
	 */
	enum COMPARATOR_ID {
	    EQUALS_COMPARATOR,
	    NOT_EQUALS_COMPARATOR,
	    LESS_THAN_COMPARATOR,
	    GREATER_THAN_COMPARATOR,
	    LESS_THAN_AND_EQUALS_COMPARATOR,
	    GREATER_THAN_AND_EQUALS_COMPARATOR,

	    UNKOWN_COMPARATOR,
	};

	/**
	 * 条件付き変数です。
	 *
	 * @author トゥイー
	 */
	class ConditionalVariable : public Value {
	public:
		VariablePtr m_variable;
		COMPARATOR_ID m_comparator;
		ValuePtr m_value;

	public:
		/**
		 * 条件付き変数を構築します。
		 *
		 * @param variable 変数を指定します。
		 * @param comparator 変数と値との間の比較演算子を指定します。
		 * @param value 値を指定します。
		 */
		ConditionalVariable(const VariablePtr& variable, COMPARATOR_ID comparator, const ValuePtr& value);

	public:
		/**
		 * 指定された定数と単一化を行います。
		 *
		 * @param value 単一化対象となる定数を指定します。
		 * @param variables 単一化に使用する変数表を指定します。
		 * @return 単一化に成功したらtrueを、失敗したらfalseを返します。
		 */
		bool unificate(const Constant& value, Variables& variables) const;

		/**
		 * 値を具体化します。
		 * <p>
		 * メモ：通常、条件付き変数は具体化することは無いので、このメソッドは呼び出されない。
		 * しかし、このメソッドが確実に呼び出されないことをコンパイラに実証させることは面倒なため、
		 * 文法レベルでこのメソッドが呼び出されないことを保証する。
		 * 間違ってこのメソッドが呼び出された場合、プログラムはassert文によって停止する。
		 * </p>
		 */
		ConstantPtr instantiate(const Variables& variables) const;

	public:
		/**
		 * ストリームに出力します。
		 */
		void print(std::ostream& stream) const;
	};

}  // namespace tops

#endif
