(************************************************************
 *
 *                       IMITATOR
 * 
 * Laboratoire Spécification et Vérification (ENS Cachan & CNRS, France)
 * Université Sorbonne Paris Nord, LIPN, CNRS, France
 * Université de Lorraine, CNRS, Inria, LORIA, Nancy, France
 * 
 * Module description: Timed counter, that depends on a level of verbosity (the counter will only update when the global verbose_mode is larger or equal to that of the counter). Also maintains a list of all counters, for obtaining statistics easily.
 * 
 * File contributors : Étienne André
 * Created           : 2014/04/27
 * Fork from         : Counter.mli
 * Fork date         : 2016/05/17
 *
 ************************************************************)

(************************************************************)
(************************************************************)
(* Type *)
(************************************************************)
(************************************************************)

type counterCategory =
	(* Algorithm functions *)
	| Algorithm_counter
	
	(* Cache counters *)
	| Cache_counter
	
	(* The global counter *)
	(*** TODO: prevent more than one such counter to be created ***)
	| Global_counter
	
	(* Everything related to graphics generation *)
	| Graphics_counter
	
	(* Lexing and parsing *)
	| Parsing_counter

	(* All calls to PPL *)
	| PPL_counter

	(* States computations *)
	| States_counter
	


(************************************************************)
(************************************************************)
(* Class definition for time counters *)
(************************************************************)
(************************************************************)
class virtual counter : string -> counterCategory -> ImitatorUtilities.verbose_mode ->
	object
		
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Get the name *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method name : string
		
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Get the level *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method level : ImitatorUtilities.verbose_mode
		
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Get the category *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method category : counterCategory
		
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Get the counter's value in the form of a string *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method virtual string_of_value : string

(************************************************************)
(************************************************************)
end
(************************************************************)
(************************************************************)


(************************************************************)
(************************************************************)
(* Class definition for time counters *)
(************************************************************)
(************************************************************)
class timeCounter : string -> counterCategory -> ImitatorUtilities.verbose_mode ->
	object inherit counter

		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Start the counter *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method start : unit
			
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Stop the counter *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method stop : unit
			
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Reset the counter *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method reset : unit

		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Get the counter's continuous value *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method value : float
		
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Get the counter's value in the form of a string *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method string_of_value : string

(************************************************************)
(************************************************************)
end
(************************************************************)
(************************************************************)


(************************************************************)
(************************************************************)
(* Class definition for discrete counters *)
(************************************************************)
(************************************************************)
class discreteCounter : string -> counterCategory -> ImitatorUtilities.verbose_mode ->
	object inherit counter
		
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Increment the discrete part *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method increment : unit
		
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Increment the discrete counter by some integer *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method increment_by : int -> unit
		
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Get the counter's discrete value *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method discrete_value : int

		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Get the counter's value in the form of a string *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method string_of_value : string

(************************************************************)
(************************************************************)
end
(************************************************************)
(************************************************************)


(************************************************************)
(************************************************************)
(* Class definition for hybrid counters (discrete increment + time counters) *)
(************************************************************)
(************************************************************)
class hybridCounter : string -> counterCategory -> ImitatorUtilities.verbose_mode ->
	object inherit timeCounter
		
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Increment the discrete part *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method increment : unit
		
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Get the counter's discrete value *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
(* 		method discrete_value : int *)
		
(************************************************************)
(************************************************************)
end
(************************************************************)
(************************************************************)



(************************************************************)
(************************************************************)
(* Class definition for data *)
(************************************************************)
(************************************************************)
class data_recorder : string -> counterCategory -> ImitatorUtilities.verbose_mode ->
	object inherit counter

		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Add data *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method add_data : string -> unit
			
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		(** Get the available data *)
		(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
		method string_of_value : string

(************************************************************)
(************************************************************)
end
(************************************************************)
(************************************************************)



(************************************************************)
(************************************************************)
(* Class-independent functions *)
(************************************************************)
(************************************************************)

(** Shortcut: create new counter and register it *)
val create_time_counter_and_register     : string -> counterCategory -> ImitatorUtilities.verbose_mode -> timeCounter
val create_discrete_counter_and_register : string -> counterCategory -> ImitatorUtilities.verbose_mode -> discreteCounter
val create_hybrid_counter_and_register   : string -> counterCategory -> ImitatorUtilities.verbose_mode -> hybridCounter

val create_data_recorder_and_register    : string -> counterCategory -> ImitatorUtilities.verbose_mode -> data_recorder

(** Enable all counters (past and future), independently of their verbose level; typicaly, this function will be called if -statistics option is enabled *)
val enable_all_counters : unit -> unit


(** Get all counters values with a pretty-printed string *)
val string_of_all_counters : unit -> string

