// -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; -*-
////////////////////////////////////////////////////////////////////
//
// $Id: search_engine.h 815 2011-09-10 12:57:27Z Sebastian Kupferschmid $
//
////////////////////////////////////////////////////////////////////

#ifndef SEARCH_SEARCH_ENGINE_H
#define SEARCH_SEARCH_ENGINE_H

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

#include "system/constraint.h"

class Task;
class State;
class OpenList;
class ClosedList;
class Heuristic;
class Normalizer;
class Options;
class Trace;
class Useless;
class SuccessorGenerator;

class SearchEngine {
public:
    enum status_t { UNSAT=0, SAT };
protected:
    const Task* task;
    const Options* opts;
public:
    const State* goal;

    OpenList* open;
    ClosedList* closed;
    Heuristic* heur;
    Normalizer* norm;

    status_t stat;
    uint32_t exploredStates;
    uint32_t generatedStates;
protected:
    int32_t indep_size;
    std::vector<const Constraint*> removed_target_constraints;
    
    virtual std::ostream& printProgress(std::ostream&) const;
    virtual std::ostream& printTrace(std::ostream&) const;
    virtual void generateTrace(Trace& trace, const State* goal) const;    
    virtual void insert(State* succ);
    virtual void prepareExploration(const SuccessorGenerator& succgen, State* initial);
public:    
    SearchEngine(const Task* task, const Options* opts);
    
    virtual void init(OpenList*, ClosedList*, Heuristic*, Normalizer*);
    virtual void explore(State* initial);
    virtual std::ostream& report(std::ostream&) const;
};

////////////////////////////////////////////////////////////////////

class UTSearchEngine : public SearchEngine {
protected:
    Useless* useless;
public:
    UTSearchEngine(const Task* task, const Options* opts) : 
	SearchEngine(task, opts) {}
    virtual void init(OpenList*, ClosedList*, Heuristic*, Normalizer*);
    virtual void insert(State* succ);    
};

////////////////////////////////////////////////////////////////////

class UTIPSearchEngine : public UTSearchEngine {
private:
    int32_t interference_level;
public:
    UTIPSearchEngine(const Task* task, const Options* opts);
    virtual void insert(State* succ);    
};

////////////////////////////////////////////////////////////////////

class IPSearchEngine : public SearchEngine {
private:
    int32_t interference_level;
public:
    IPSearchEngine(const Task* task, const Options* opts);
    virtual void insert(State* succ);    
};

////////////////////////////////////////////////////////////////////

class GraphvizEngine : public SearchEngine {
private:
    uint32_t diff_states;    
    int32_t id;
    void label(State* s, FILE* file);
public:
    GraphvizEngine(const Task* task, const Options* opts);
    virtual void explore(State* initial);
};

#endif /* SEARCH_SEARCH_ENGINE_H */
