(** Plans for stimuli, workouts, and routines. *) module Rep_range : sig type t type error = | Invalid_order of { min : int; max : int } | Outside_limits of { min : int; max : int } exception Invalid of error val limits : int * int (** HD1's 6-12 calibration limits. *) val make : min:int -> max:int -> t (** Raises [Invalid] for an invalid range. *) val bounds : t -> int * int end (** One prescribed drive to failure. *) module Stimulus : sig type t type delivery = | Single of Exercise.t | Pre_exhaust of { isolation : Exercise.t; compound : Exercise.t } (** No pause between movements. *) type error = | Not_a_pre_exhaust of { isolation : Exercise.id; compound : Exercise.id } | Substitute_not_permitted of Exercise.id val pp_error : Format.formatter -> error -> unit exception Invalid of error val make : delivery:delivery -> rep_range:Rep_range.t -> allowed_substitutes:Exercise.t list -> t (** Raises [Invalid] for an invalid pairing or substitution. *) val delivery : t -> delivery val rep_range : t -> Rep_range.t val allowed_substitutes : t -> Exercise.t list val exercises : t -> Exercise.t list (** Performance order. *) val permits : t -> Exercise.t -> bool val pp : Format.formatter -> t -> unit end (** Ordered prescribed stimuli. *) module Workout : sig type t type error = Empty_workout exception Invalid of error val make : name:string -> stimuli:Stimulus.t list -> t (** Raises [Invalid Empty_workout] for an empty workout. *) val name : t -> string val stimuli : t -> Stimulus.t list val pp : Format.formatter -> t -> unit end (** A workout cycle and its recovery intervals. *) module Routine : sig type t type error = Empty_routine exception Invalid of error val make : name:string -> workouts:Workout.t list -> t (** Raises [Invalid Empty_routine] for an empty routine. *) val name : t -> string val workouts : t -> Workout.t list (** Cycle order. *) val workout_after : t -> Workout.t -> Workout.t (** Wraps; unknown workouts fall back to the first. *) val pp : Format.formatter -> t -> unit val training_interval : Recovery.duration (** 48h. *) val cycle_rest : Recovery.duration (** 72h after the final workout. *) val recovery_after : t -> Workout.t -> Recovery.duration val ideal : t (** The supplied Heavy Duty I routine. *) end