// -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; -*-
////////////////////////////////////////////////////////////////////
//
// $Id: dtg.h 819 2011-09-23 16:32:07Z Sebastian Kupferschmid $
//
////////////////////////////////////////////////////////////////////

// dtg.h contains the domain transition graph data structure from Fast
// Downward that is used for the search part after building the
// domainTransitionGraph structure, it is translated to this dtg
// structure
//
// TDOD: unify domainTransitionGraph and dtg structure

#ifndef DTG_H
#define DTG_H

#include <iosfwd>
#include <map>
#include <vector>
#include <inttypes.h>

namespace cg {
    class DomainTransitionGraph;
    class CGHeuristic;
    class CGOperator;

    class ValueNode;
    class ValueTransition;
    class ValueTransitionLabel;
    class DTG;
    
    // Note: We do not use references but pointers to refer to the "parents" of
    // transitions and nodes. This is because these structures could not be
    // put into vectors otherwise.
    
    typedef std::multimap<int32_t, ValueNode *> Heap;
    
    struct PrevailCondition {
	DTG* prev_dtg;
	int32_t local_var, value;
	PrevailCondition(DTG *prev, int32_t var, int32_t val)
	    : prev_dtg(prev), local_var(var), value(val) {}
    };
    
    struct ValueTransitionLabel {
	CGOperator* op;
	std::vector<PrevailCondition> prevail;
	
	ValueTransitionLabel(CGOperator* theOp, const std::vector<PrevailCondition> &prev)
	    : op(theOp), prevail(prev) {}
	void dump() const;
    };
    
    struct ValueTransition {
	ValueNode* target;
	std::vector<ValueTransitionLabel> labels;
	
	ValueTransition(ValueNode* targ)
	    : target(targ) {}
	void simplify();
	void dump() const;
    };
    
    struct ValueNode {
	DTG* parent_graph;
	int32_t value;
	std::vector<ValueTransition> transitions;
	
	std::vector<int32_t> distances;               // cg; empty vector if not yet requested
	std::vector<ValueTransitionLabel *> helpful_transitions;
	// cg; empty vector if not requested
	Heap::iterator pos_in_heap;          // cg
	std::vector<int32_t> children_state;          // cg
	ValueNode* reached_from;             // cg
	ValueTransitionLabel* reached_by;    // cg
	
	ValueNode(DTG* parent, int32_t val)
	    : parent_graph(parent), value(val), reached_from(0), reached_by(0) {}
	void dump() const;
    };
    
    class DTG {
	friend class CGHeuristic;
	friend class ValueNode;
	friend class ValueTransition;
	friend class Transition;
    public:
	const CGVariable* cgvar;	
    private:
	int32_t var;
	std::vector<ValueNode> nodes;
	
	int32_t last_helpful_transition_extraction_time; // cg heuristic; "dirty bit"
	
	std::vector<int32_t> local_to_global_child;
	// used for mapping variables in conditions to their global index 
	// (only needed for initializing child_state for the start node?)
	
	DTG(const DTG& other); // copying forbidden
    public:
	explicit DTG(const CGVariable* cgvar);
	
	void get_successors(int32_t value, std::vector<int32_t> &result) const;
	// Build vector of values v' such that there is a transition from value to v'.
	
	void construct_transitions(DomainTransitionGraph* graph, std::vector<DTG*>& g_transition_graphs, std::vector<CGOperator*>& operators);
	std::ostream& display(std::ostream& o) const;
	bool is_strongly_connected();
	bool uses_only_these_vars(std::vector<CGVariable*>& some_variables);	
    };

    inline std::ostream& operator<<(std::ostream& o, const DTG& dtg) {
	return dtg.display(o);
    }    
}

#endif
