1
-
Removed:
(* Minimal stubs only; implementation deferred until after the review gate. *)
2
-
Removed:
3
1
module Plan = struct
4
-
Removed:
type t = unit
2
+
Added:
type t = { name : string; prescriptions : Prescription.t list }
5
3
type error = Empty_plan
6
4
7
-
Removed:
let make ~name:_ ~prescriptions:_ = failwith "TODO"
8
-
Removed:
let name _ = failwith "TODO"
9
-
Removed:
let prescriptions _ = failwith "TODO"
10
-
Removed:
let pp _ _ = failwith "TODO"
5
+
Added:
let make ~name ~prescriptions =
6
+
Added:
match prescriptions with
7
+
Added:
| [] -> Error Empty_plan
8
+
Added:
| _ -> Ok { name; prescriptions }
9
+
Added:
10
+
Added:
let name t = t.name
11
+
Added:
let prescriptions t = t.prescriptions
12
+
Added:
13
+
Added:
let pp fmt t =
14
+
Added:
Format.fprintf fmt "%s: %a" t.name
15
+
Added:
(Format.pp_print_list
16
+
Added:
~pp_sep:(fun fmt () -> Format.fprintf fmt ", ")
17
+
Added:
Prescription.pp)
18
+
Added:
t.prescriptions
11
19
end
12
20
13
-
Removed:
type t = unit
21
+
Added:
type t = {
22
+
Added:
name : string;
23
+
Added:
plans : Plan.t list;
24
+
Added:
recovery_base : Recovery.duration;
25
+
Added:
}
26
+
Added:
14
27
type error = Empty_routine
15
28
16
-
Removed:
let make ~name:_ ~plans:_ = failwith "TODO"
17
-
Removed:
let name _ = failwith "TODO"
18
-
Removed:
let plans _ = failwith "TODO"
19
-
Removed:
let next_plan _ ~completed_workouts:_ = failwith "TODO"
20
-
Removed:
let recovery_base _ = failwith "TODO"
21
-
Removed:
let pp _ _ = failwith "TODO"
22
-
Removed:
let ideal_routine = ()
23
-
Removed:
let consolidation_routine = ()
29
+
Added:
let make ~name ~plans =
30
+
Added:
match plans with
31
+
Added:
| [] -> Error Empty_routine
32
+
Added:
| _ -> Ok { name; plans; recovery_base = Recovery.days 4 }
33
+
Added:
34
+
Added:
let name t = t.name
35
+
Added:
let plans t = t.plans
36
+
Added:
37
+
Added:
let next_plan t ~completed_workouts =
38
+
Added:
let n = List.length t.plans in
39
+
Added:
List.nth t.plans (((completed_workouts mod n) + n) mod n)
40
+
Added:
41
+
Added:
let recovery_base t = t.recovery_base
42
+
Added:
43
+
Added:
let pp fmt t =
44
+
Added:
Format.fprintf fmt "%s (%d workouts)" t.name (List.length t.plans)
45
+
Added:
46
+
Added:
(* {1 Heavy Duty presets} *)
47
+
Added:
48
+
Added:
let by_name n =
49
+
Added:
match
50
+
Added:
List.find_opt (fun ex -> String.equal (Exercise.name ex) n) Exercise.catalog
51
+
Added:
with
52
+
Added:
| Some ex -> ex
53
+
Added:
| None -> invalid_arg (Printf.sprintf "no catalog exercise named %s" n)
54
+
Added:
55
+
Added:
let ok = function
56
+
Added:
| Ok v -> v
57
+
Added:
| Error _ -> invalid_arg "invalid preset definition"
58
+
Added:
59
+
Added:
let band lo hi =
60
+
Added:
ok
61
+
Added:
(Units.Rep_range.make
62
+
Added:
~min:(ok (Units.Reps.of_int lo))
63
+
Added:
~max:(ok (Units.Reps.of_int hi)))
64
+
Added:
65
+
Added:
let prescribe ?(substitutes = []) exercise_name lo hi =
66
+
Added:
ok
67
+
Added:
(Prescription.make ~exercise:(by_name exercise_name)
68
+
Added:
~target_reps:(band lo hi)
69
+
Added:
~allowed_substitutes:(List.map by_name substitutes))
70
+
Added:
71
+
Added:
let plan name prescriptions = ok (Plan.make ~name ~prescriptions)
72
+
Added:
73
+
Added:
(* Mentzer's Ideal Routine: a three-way split built around pre-exhaustion
74
+
Added:
supersets — an isolation movement immediately preceding the compound for
75
+
Added:
the same target, so the larger muscle is the limiting factor. *)
76
+
Added:
let ideal_routine =
77
+
Added:
let workout_a =
78
+
Added:
plan "Workout A: Chest, Shoulders, Triceps"
79
+
Added:
[
80
+
Added:
prescribe "Chest Flye" 6 8;
81
+
Added:
prescribe "Barbell Bench Press" 6 8
82
+
Added:
~substitutes:[ "Dumbbell Bench Press" ];
83
+
Added:
prescribe "Lateral Raise" 6 8;
84
+
Added:
prescribe "Overhead Press" 6 8
85
+
Added:
~substitutes:[ "Dumbbell Shoulder Press" ];
86
+
Added:
prescribe "Triceps Pushdown" 6 8 ~substitutes:[ "Skullcrusher" ];
87
+
Added:
]
88
+
Added:
in
89
+
Added:
let workout_b =
90
+
Added:
plan "Workout B: Back, Biceps"
91
+
Added:
[
92
+
Added:
prescribe "Pulldown" 6 8 ~substitutes:[ "Pull-Up" ];
93
+
Added:
prescribe "Barbell Row" 6 8
94
+
Added:
~substitutes:[ "Dumbbell Row"; "Seated Cable Row" ];
95
+
Added:
prescribe "Barbell Curl" 6 8 ~substitutes:[ "Dumbbell Curl" ];
96
+
Added:
]
97
+
Added:
in
98
+
Added:
let workout_c =
99
+
Added:
plan "Workout C: Legs"
100
+
Added:
[
101
+
Added:
prescribe "Leg Extension" 6 8;
102
+
Added:
prescribe "Back Squat" 6 8 ~substitutes:[ "Leg Press" ];
103
+
Added:
prescribe "Leg Curl" 6 8;
104
+
Added:
prescribe "Calf Raise" 6 8;
105
+
Added:
]
106
+
Added:
in
107
+
Added:
{
108
+
Added:
name = "Ideal Routine";
109
+
Added:
plans = [ workout_a; workout_b; workout_c ];
110
+
Added:
recovery_base = Recovery.days 4;
111
+
Added:
}
112
+
Added:
113
+
Added:
(* The Consolidation Routine: the minimalist variant — a handful of compound
114
+
Added:
movements, one working set each, trained infrequently. *)
115
+
Added:
let consolidation_routine =
116
+
Added:
let workout_a =
117
+
Added:
plan "Workout A"
118
+
Added:
[
119
+
Added:
prescribe "Back Squat" 6 8 ~substitutes:[ "Leg Press" ];
120
+
Added:
prescribe "Pulldown" 6 8;
121
+
Added:
]
122
+
Added:
in
123
+
Added:
let workout_b =
124
+
Added:
plan "Workout B"
125
+
Added:
[
126
+
Added:
prescribe "Barbell Bench Press" 6 8
127
+
Added:
~substitutes:[ "Dumbbell Bench Press" ];
128
+
Added:
prescribe "Deadlift" 6 8;
129
+
Added:
]
130
+
Added:
in
131
+
Added:
{
132
+
Added:
name = "Consolidation Routine";
133
+
Added:
plans = [ workout_a; workout_b ];
134
+
Added:
recovery_base = Recovery.days 7;
135
+
Added:
}