#ifndef _AP_VALIDATOR_H_
#define _AP_VALIDATOR_H_

#include "ap_validate_inc.h"
#include "ap_result.h"

double rel_diff(double x1, double x2);
double abs_diff(double x1, double x2);
bool has_roughly_equal_signal(vector< ap_signal> const & p1, ap_signal const & p2);
bool strongly_similar(vector< ap_signal> const & p1, vector< ap_signal> const & p2);
bool weakly_similar(vector< ap_signal> const & p1, vector< ap_signal> const & p2);


class ap_checkset : public track_mem<ap_checkset> {
private:

	struct validate_stats : public track_mem<validate_stats> {
		int nstrong_compare;
		int nstrong;
		int nweak_compare;
		int nweak;
		int bad_results;
		void print()
		{
			printf("Strongly similar: %d out of %d\n", nstrong,
				nstrong_compare);
			printf("Weakly similar: %d out of %d\n", nweak, nweak_compare);
		};
		validate_stats() : track_mem<validate_stats>("validate_stats"),
		  nstrong_compare(0), nstrong(0),
		  nweak_compare(0), nweak(0),
		  bad_results(0) 
	            { };
		validate_stats(const validate_stats &v) :
		  track_mem<validate_stats>("validate_stats (copy)"), 
		  nstrong_compare(v.nstrong_compare),
		  nstrong(v.nstrong),
		  nweak_compare(v.nweak_compare),
		  nweak(v.nweak),
		  bad_results(v.bad_results) {};
	};

public:
	int canonical_id;
	double granted_credit;
	bool has_canonical_result;
	bool retry;

	validate_stats stats;

	void init(vector< RESULT>& result_vec, int min_quorum);
	ap_checkset() : track_mem<ap_checkset>("ap_checkset") {};
	ap_checkset(const ap_checkset &a) :
	  track_mem<ap_checkset>("ap_checkset (copy)") ,
	  canonical_id(a.canonical_id),
	  granted_credit(a.granted_credit),
	  has_canonical_result(a.has_canonical_result),
	  retry(a.retry),
	  stats(a.stats) 
              { };
	ap_checkset(vector< RESULT>& result_vec, WORKUNIT& wu);
};

class ap_checkpair : public track_mem<ap_checkpair> {
public:
	bool retry;
	bool has_weakly_similar;

	int init(RESULT& result_new, RESULT const & result_conanical);
	ap_checkpair() : track_mem<ap_checkpair>("ap_checkpair"),
          retry(false),
          has_weakly_similar(false)
            {};
	ap_checkpair(const ap_checkpair &a) :
	  track_mem<ap_checkpair>("ap_checkpair (copy)") ,
	  retry(a.retry),
	  has_weakly_similar(a.has_weakly_similar)
              { };
	ap_checkpair(RESULT& result_new, RESULT const & result_conanical);
};

#endif
