[OCaml] High Intensity Training Online
refactor Key exercises structurally
Key opaque catalog entries by equipment, movement, and variation. Keep stable string IDs only for serialization and boundary lookup while using structured keys for relationships and supplied routines.
Changed files
ARCHITECTURE.md
@@ -83,9 +83,11 @@
83
83
anatomically; both are here because a compound must have something able to
84
84
serve the muscle it pre-exhausts. Deliberately minimal otherwise: nothing but
85
85
pre-exhaust validation consults it.
86
Removed:
- **Exercise** — the curated catalog, each movement carrying a mechanic
87
Removed:
(isolation or compound) and the muscles it works. Substitutions come from HD1's
88
Removed:
own "or" lists, grouped so symmetry is structural.
86
Added:
- **Exercise** — the curated catalog. Each opaque entry is keyed by
87
Added:
equipment × movement × variation, while a stable string ID serves only
88
Added:
external serialization. Each entry carries a mechanic and worked muscles.
89
Added:
Substitutions come from HD1's own "or" lists, grouped so symmetry is
90
Added:
structural.
89
91
90
92
### Normative — the plan
91
93
lib/core/exercise.ml
@@ -17,55 +17,190 @@
17
17
let equal = ( = )
18
18
end
19
19
20
Added:
type equipment =
21
Added:
| Barbell
22
Added:
| Cable
23
Added:
| Dumbbell
24
Added:
| Machine
25
Added:
| Bodyweight
26
Added:
| Unspecified
27
Added:
28
Added:
type movement =
29
Added:
| Fly
30
Added:
| Crossover
31
Added:
| Pec_deck
32
Added:
| Press
33
Added:
| Lateral_raise
34
Added:
| French_press
35
Added:
| Pressdown
36
Added:
| Dip
37
Added:
| Pullover
38
Added:
| Pulldown
39
Added:
| Row
40
Added:
| Chin
41
Added:
| Shrug
42
Added:
| Hyperextension
43
Added:
| Deadlift
44
Added:
| Curl
45
Added:
| Leg_extension
46
Added:
| Leg_press
47
Added:
| Squat
48
Added:
| Leg_curl
49
Added:
| Calf_raise
50
Added:
| Sit_up
51
Added:
52
Added:
type variation =
53
Added:
| Standard
54
Added:
| Incline
55
Added:
| Bent_over
56
Added:
| Rear_delt
57
Added:
| Lying
58
Added:
| Triceps
59
Added:
| Close_grip_palms_up
60
Added:
| Straight_arm
61
Added:
| Preacher
62
Added:
63
Added:
type key = { equipment : equipment; movement : movement; variation : variation }
20
64
type id = string
21
65
type mechanic = Isolation | Compound
22
66
23
67
type t = {
68
Added:
key : key;
24
69
id : id;
25
70
name : string;
26
71
mechanic : mechanic;
27
72
muscles : Muscle.t list;
28
73
}
29
74
75
Added:
let make_key ~equipment ~movement ~variation =
76
Added:
{ equipment; movement; variation }
77
Added:
78
Added:
let key_equal = ( = )
79
Added:
let key t = t.key
30
80
let id t = t.id
31
81
let name t = t.name
32
Removed:
let equal a b = String.equal a.id b.id
82
Added:
let equal a b = key_equal a.key b.key
33
83
let pp ppf t = Format.pp_print_string ppf t.name
34
84
35
Removed:
let iso id name muscle =
36
Removed:
{ id; name; mechanic = Isolation; muscles = [ muscle ] }
85
Added:
let iso ~key ~id ~name muscle =
86
Added:
{ key; id; name; mechanic = Isolation; muscles = [ muscle ] }
37
87
38
Removed:
let comp id name muscles = { id; name; mechanic = Compound; muscles }
88
Added:
let comp ~key ~id ~name muscles =
89
Added:
{ key; id; name; mechanic = Compound; muscles }
39
90
40
91
(* The movements HD1 names, in the order its Ideal Routine introduces them.
41
Removed:
Compound muscle lists put the chiefly-worked muscle first, followed by the
42
Removed:
assisting muscles that HD1's weak-link discussion identifies. *)
92
Added:
The stable [id] preserves external serialization. The structured [key] is the
93
Added:
catalog identity. [Unspecified] records where HD1 names no equipment. *)
94
Added:
let dumbbell_flyes =
95
Added:
make_key ~equipment:Dumbbell ~movement:Fly ~variation:Standard
96
Added:
97
Added:
let cable_crossovers =
98
Added:
make_key ~equipment:Cable ~movement:Crossover ~variation:Standard
99
Added:
100
Added:
let pec_deck =
101
Added:
make_key ~equipment:Machine ~movement:Pec_deck ~variation:Standard
102
Added:
103
Added:
let incline_presses =
104
Added:
make_key ~equipment:Unspecified ~movement:Press ~variation:Incline
105
Added:
106
Added:
let laterals =
107
Added:
make_key ~equipment:Unspecified ~movement:Lateral_raise ~variation:Standard
108
Added:
109
Added:
let bent_over_laterals =
110
Added:
make_key ~equipment:Dumbbell ~movement:Lateral_raise ~variation:Bent_over
111
Added:
112
Added:
let reverse_pec_deck =
113
Added:
make_key ~equipment:Machine ~movement:Pec_deck ~variation:Rear_delt
114
Added:
115
Added:
let lying_french_presses =
116
Added:
make_key ~equipment:Unspecified ~movement:French_press ~variation:Lying
117
Added:
118
Added:
let pressdowns =
119
Added:
make_key ~equipment:Cable ~movement:Pressdown ~variation:Standard
120
Added:
121
Added:
let triceps_machine =
122
Added:
make_key ~equipment:Machine ~movement:Press ~variation:Triceps
123
Added:
124
Added:
let dips = make_key ~equipment:Bodyweight ~movement:Dip ~variation:Standard
125
Added:
126
Added:
let pullovers =
127
Added:
make_key ~equipment:Unspecified ~movement:Pullover ~variation:Standard
128
Added:
129
Added:
let straight_arm_pulldowns =
130
Added:
make_key ~equipment:Cable ~movement:Pulldown ~variation:Straight_arm
131
Added:
132
Added:
let close_grip_pulldowns =
133
Added:
make_key ~equipment:Cable ~movement:Pulldown ~variation:Close_grip_palms_up
134
Added:
135
Added:
let bent_over_rows =
136
Added:
make_key ~equipment:Barbell ~movement:Row ~variation:Bent_over
137
Added:
138
Added:
let chins = make_key ~equipment:Bodyweight ~movement:Chin ~variation:Standard
139
Added:
let shrugs = make_key ~equipment:Unspecified ~movement:Shrug ~variation:Standard
140
Added:
141
Added:
let hyperextensions =
142
Added:
make_key ~equipment:Bodyweight ~movement:Hyperextension ~variation:Standard
143
Added:
144
Added:
let deadlifts =
145
Added:
make_key ~equipment:Barbell ~movement:Deadlift ~variation:Standard
146
Added:
147
Added:
let curls = make_key ~equipment:Barbell ~movement:Curl ~variation:Standard
148
Added:
149
Added:
let preacher_curls =
150
Added:
make_key ~equipment:Barbell ~movement:Curl ~variation:Preacher
151
Added:
152
Added:
let leg_extensions =
153
Added:
make_key ~equipment:Machine ~movement:Leg_extension ~variation:Standard
154
Added:
155
Added:
let leg_presses =
156
Added:
make_key ~equipment:Machine ~movement:Leg_press ~variation:Standard
157
Added:
158
Added:
let squats = make_key ~equipment:Barbell ~movement:Squat ~variation:Standard
159
Added:
160
Added:
let leg_curls =
161
Added:
make_key ~equipment:Machine ~movement:Leg_curl ~variation:Standard
162
Added:
163
Added:
let calf_raises =
164
Added:
make_key ~equipment:Unspecified ~movement:Calf_raise ~variation:Standard
165
Added:
166
Added:
let sit_ups =
167
Added:
make_key ~equipment:Bodyweight ~movement:Sit_up ~variation:Standard
168
Added:
43
169
let catalog =
44
170
[
45
Removed:
(* Day 1 — pecs, delts, triceps *)
46
Removed:
iso "dumbbell-flyes" "Dumbbell Flyes" Muscle.Pecs;
47
Removed:
iso "cable-crossovers" "Cable Crossovers" Muscle.Pecs;
48
Removed:
iso "pec-deck" "Pec Deck" Muscle.Pecs;
49
Removed:
comp "incline-press" "Incline Presses"
171
Added:
iso ~key:dumbbell_flyes ~id:"dumbbell-flyes" ~name:"Dumbbell Flyes"
172
Added:
Muscle.Pecs;
173
Added:
iso ~key:cable_crossovers ~id:"cable-crossovers" ~name:"Cable Crossovers"
174
Added:
Muscle.Pecs;
175
Added:
iso ~key:pec_deck ~id:"pec-deck" ~name:"Pec Deck" Muscle.Pecs;
176
Added:
comp ~key:incline_presses ~id:"incline-press" ~name:"Incline Presses"
50
177
[ Muscle.Pecs; Muscle.Delts; Muscle.Triceps ];
51
Removed:
iso "laterals" "Laterals" Muscle.Delts;
52
Removed:
iso "bent-over-laterals" "Bent-over Dumbbell Laterals" Muscle.Delts;
53
Removed:
iso "reverse-pec-deck" "Pec Deck (rear delts)" Muscle.Delts;
54
Removed:
iso "lying-french-press" "Lying French Presses" Muscle.Triceps;
55
Removed:
iso "pressdowns" "Pressdowns" Muscle.Triceps;
56
Removed:
iso "triceps-machine" "Triceps Machine" Muscle.Triceps;
57
Removed:
comp "dips" "Dips" [ Muscle.Triceps; Muscle.Pecs; Muscle.Delts ];
58
Removed:
(* Day 2 — lats, traps, erectors, biceps *)
59
Removed:
iso "pullovers" "Pullovers" Muscle.Lats;
60
Removed:
iso "straight-arm-pulldowns" "Straight-Arm Pulldowns" Muscle.Lats;
61
Removed:
comp "close-grip-pulldowns" "Close-grip, palms-up Pulldowns"
178
Added:
iso ~key:laterals ~id:"laterals" ~name:"Laterals" Muscle.Delts;
179
Added:
iso ~key:bent_over_laterals ~id:"bent-over-laterals"
180
Added:
~name:"Bent-over Dumbbell Laterals" Muscle.Delts;
181
Added:
iso ~key:reverse_pec_deck ~id:"reverse-pec-deck"
182
Added:
~name:"Pec Deck (rear delts)" Muscle.Delts;
183
Added:
iso ~key:lying_french_presses ~id:"lying-french-press"
184
Added:
~name:"Lying French Presses" Muscle.Triceps;
185
Added:
iso ~key:pressdowns ~id:"pressdowns" ~name:"Pressdowns" Muscle.Triceps;
186
Added:
iso ~key:triceps_machine ~id:"triceps-machine" ~name:"Triceps Machine"
187
Added:
Muscle.Triceps;
188
Added:
comp ~key:dips ~id:"dips" ~name:"Dips"
189
Added:
[ Muscle.Triceps; Muscle.Pecs; Muscle.Delts ];
190
Added:
iso ~key:pullovers ~id:"pullovers" ~name:"Pullovers" Muscle.Lats;
191
Added:
iso ~key:straight_arm_pulldowns ~id:"straight-arm-pulldowns"
192
Added:
~name:"Straight-Arm Pulldowns" Muscle.Lats;
193
Added:
comp ~key:close_grip_pulldowns ~id:"close-grip-pulldowns"
194
Added:
~name:"Close-grip, palms-up Pulldowns"
62
195
[ Muscle.Lats; Muscle.Biceps; Muscle.Forearms ];
63
Removed:
comp "bent-over-rows" "Bent-over Barbell Rows"
196
Added:
comp ~key:bent_over_rows ~id:"bent-over-rows" ~name:"Bent-over Barbell Rows"
64
197
[ Muscle.Lats; Muscle.Biceps; Muscle.Forearms; Muscle.Erectors ];
65
Removed:
comp "chins" "Chins" [ Muscle.Lats; Muscle.Biceps; Muscle.Forearms ];
66
Removed:
iso "shrugs" "Shrugs" Muscle.Traps;
67
Removed:
iso "hyperextensions" "Hyperextensions" Muscle.Erectors;
68
Removed:
comp "deadlifts" "Deadlifts"
198
Added:
comp ~key:chins ~id:"chins" ~name:"Chins"
199
Added:
[ Muscle.Lats; Muscle.Biceps; Muscle.Forearms ];
200
Added:
iso ~key:shrugs ~id:"shrugs" ~name:"Shrugs" Muscle.Traps;
201
Added:
iso ~key:hyperextensions ~id:"hyperextensions" ~name:"Hyperextensions"
202
Added:
Muscle.Erectors;
203
Added:
comp ~key:deadlifts ~id:"deadlifts" ~name:"Deadlifts"
69
204
[
70
205
Muscle.Erectors;
71
206
Muscle.Glutes;
@@ -73,43 +208,48 @@
73
208
Muscle.Quadriceps;
74
209
Muscle.Traps;
75
210
];
76
Removed:
iso "curls" "Curls" Muscle.Biceps;
77
Removed:
iso "preacher-curls" "Preacher Curls" Muscle.Biceps;
78
Removed:
(* Day 3 — legs, abs *)
79
Removed:
iso "leg-extensions" "Leg Extensions" Muscle.Quadriceps;
80
Removed:
comp "leg-presses" "Leg Presses"
211
Added:
iso ~key:curls ~id:"curls" ~name:"Curls" Muscle.Biceps;
212
Added:
iso ~key:preacher_curls ~id:"preacher-curls" ~name:"Preacher Curls"
213
Added:
Muscle.Biceps;
214
Added:
iso ~key:leg_extensions ~id:"leg-extensions" ~name:"Leg Extensions"
215
Added:
Muscle.Quadriceps;
216
Added:
comp ~key:leg_presses ~id:"leg-presses" ~name:"Leg Presses"
81
217
[ Muscle.Quadriceps; Muscle.Glutes; Muscle.Hamstrings ];
82
Removed:
comp "squats" "Squats"
218
Added:
comp ~key:squats ~id:"squats" ~name:"Squats"
83
219
[ Muscle.Quadriceps; Muscle.Glutes; Muscle.Hamstrings; Muscle.Erectors ];
84
Removed:
iso "leg-curls" "Leg Curls" Muscle.Hamstrings;
85
Removed:
iso "calf-raises" "Calf Raises" Muscle.Calves;
86
Removed:
iso "sit-ups" "Sit-Ups" Muscle.Abdominals;
220
Added:
iso ~key:leg_curls ~id:"leg-curls" ~name:"Leg Curls" Muscle.Hamstrings;
221
Added:
iso ~key:calf_raises ~id:"calf-raises" ~name:"Calf Raises" Muscle.Calves;
222
Added:
iso ~key:sit_ups ~id:"sit-ups" ~name:"Sit-Ups" Muscle.Abdominals;
87
223
]
88
224
89
Removed:
let find sought = List.find_opt (fun e -> String.equal e.id sought) catalog
225
Added:
let find sought =
226
Added:
List.find_opt (fun exercise -> key_equal exercise.key sought) catalog
90
227
91
Removed:
(* Mutually substitutable movements. Grouping guarantees symmetry: every member
92
Removed:
of a group may stand in for every other. Each group is one of HD1's own
93
Removed:
"or" lists. *)
228
Added:
let find_id sought =
229
Added:
List.find_opt (fun exercise -> String.equal exercise.id sought) catalog
230
Added:
231
Added:
(* Mutually substitutable catalog keys. Grouping guarantees symmetry: every
232
Added:
member of a group may stand in for every other. Each group is one of HD1's
233
Added:
own "or" lists. *)
94
234
let substitution_groups =
95
235
[
96
Removed:
[ "dumbbell-flyes"; "cable-crossovers"; "pec-deck" ];
97
Removed:
[ "lying-french-press"; "pressdowns"; "triceps-machine" ];
98
Removed:
[ "bent-over-laterals"; "reverse-pec-deck" ];
99
Removed:
[ "pullovers"; "straight-arm-pulldowns" ];
100
Removed:
[ "close-grip-pulldowns"; "bent-over-rows"; "chins" ];
101
Removed:
[ "hyperextensions"; "deadlifts" ];
102
Removed:
[ "curls"; "preacher-curls" ];
103
Removed:
[ "leg-presses"; "squats" ];
236
Added:
[ dumbbell_flyes; cable_crossovers; pec_deck ];
237
Added:
[ lying_french_presses; pressdowns; triceps_machine ];
238
Added:
[ bent_over_laterals; reverse_pec_deck ];
239
Added:
[ pullovers; straight_arm_pulldowns ];
240
Added:
[ close_grip_pulldowns; bent_over_rows; chins ];
241
Added:
[ hyperextensions; deadlifts ];
242
Added:
[ curls; preacher_curls ];
243
Added:
[ leg_presses; squats ];
104
244
]
105
245
106
Removed:
let group_of e =
107
Removed:
List.find_opt (fun group -> List.mem e.id group) substitution_groups
246
Added:
let group_of exercise =
247
Added:
List.find_opt (List.exists (key_equal exercise.key)) substitution_groups
108
248
|> Option.value ~default:[]
109
249
110
Removed:
let permitted_substitutes e =
111
Removed:
group_of e
112
Removed:
|> List.filter (fun id -> not (String.equal id e.id))
250
Added:
let permitted_substitutes exercise =
251
Added:
group_of exercise
252
Added:
|> List.filter (fun key -> not (key_equal key exercise.key))
113
253
|> List.filter_map find
114
254
115
255
let may_substitute ~original ~candidate =
lib/core/exercise.mli
@@ -1,13 +1,64 @@
1
1
(** Curated exercises and their permitted relationships. *)
2
2
3
Added:
type equipment =
4
Added:
| Barbell
5
Added:
| Cable
6
Added:
| Dumbbell
7
Added:
| Machine
8
Added:
| Bodyweight
9
Added:
| Unspecified
10
Added:
11
Added:
type movement =
12
Added:
| Fly
13
Added:
| Crossover
14
Added:
| Pec_deck
15
Added:
| Press
16
Added:
| Lateral_raise
17
Added:
| French_press
18
Added:
| Pressdown
19
Added:
| Dip
20
Added:
| Pullover
21
Added:
| Pulldown
22
Added:
| Row
23
Added:
| Chin
24
Added:
| Shrug
25
Added:
| Hyperextension
26
Added:
| Deadlift
27
Added:
| Curl
28
Added:
| Leg_extension
29
Added:
| Leg_press
30
Added:
| Squat
31
Added:
| Leg_curl
32
Added:
| Calf_raise
33
Added:
| Sit_up
34
Added:
35
Added:
type variation =
36
Added:
| Standard
37
Added:
| Incline
38
Added:
| Bent_over
39
Added:
| Rear_delt
40
Added:
| Lying
41
Added:
| Triceps
42
Added:
| Close_grip_palms_up
43
Added:
| Straight_arm
44
Added:
| Preacher
45
Added:
46
Added:
type key = { equipment : equipment; movement : movement; variation : variation }
47
Added:
(** The catalog identity: equipment × movement × variation. *)
48
Added:
3
49
type t
4
Removed:
(** Only obtainable by lookup. *)
50
Added:
(** An opaque catalog entry, only obtainable by lookup. *)
5
51
6
52
type id = private string
53
Added:
(** A stable serialized identifier for external boundaries. *)
7
54
8
Removed:
val find : string -> t option
9
Removed:
(** Looks up an exercise by its identifier. *)
55
Added:
val find : key -> t option
56
Added:
(** Looks up an exercise by structured identity. *)
10
57
58
Added:
val find_id : string -> t option
59
Added:
(** Looks up an exercise by stable serialized identifier. *)
60
Added:
61
Added:
val key : t -> key
11
62
val id : t -> id
12
63
val name : t -> string
13
64
val equal : t -> t -> bool
lib/core/prescription.ml
@@ -142,25 +142,124 @@
142
142
143
143
(* {1 The Ideal Routine} *)
144
144
145
Removed:
let movement id =
146
Removed:
match Exercise.find id with
147
Removed:
| Some e -> e
148
Removed:
| None -> invalid_arg (Format.sprintf "Routine preset: no exercise %S" id)
145
Added:
open Exercise
149
146
147
Added:
let exercise key =
148
Added:
match Exercise.find key with
149
Added:
| Some exercise -> exercise
150
Added:
| None -> invalid_arg "Ideal Routine references an absent catalog key"
151
Added:
152
Added:
let dumbbell_flyes =
153
Added:
exercise { equipment = Dumbbell; movement = Fly; variation = Standard }
154
Added:
155
Added:
let cable_crossovers =
156
Added:
exercise { equipment = Cable; movement = Crossover; variation = Standard }
157
Added:
158
Added:
let pec_deck =
159
Added:
exercise { equipment = Machine; movement = Pec_deck; variation = Standard }
160
Added:
161
Added:
let incline_presses =
162
Added:
exercise { equipment = Unspecified; movement = Press; variation = Incline }
163
Added:
164
Added:
let laterals =
165
Added:
exercise
166
Added:
{
167
Added:
equipment = Unspecified;
168
Added:
movement = Lateral_raise;
169
Added:
variation = Standard;
170
Added:
}
171
Added:
172
Added:
let bent_over_laterals =
173
Added:
exercise
174
Added:
{ equipment = Dumbbell; movement = Lateral_raise; variation = Bent_over }
175
Added:
176
Added:
let reverse_pec_deck =
177
Added:
exercise { equipment = Machine; movement = Pec_deck; variation = Rear_delt }
178
Added:
179
Added:
let lying_french_presses =
180
Added:
exercise
181
Added:
{ equipment = Unspecified; movement = French_press; variation = Lying }
182
Added:
183
Added:
let pressdowns =
184
Added:
exercise { equipment = Cable; movement = Pressdown; variation = Standard }
185
Added:
186
Added:
let triceps_machine =
187
Added:
exercise { equipment = Machine; movement = Press; variation = Triceps }
188
Added:
189
Added:
let dips =
190
Added:
exercise { equipment = Bodyweight; movement = Dip; variation = Standard }
191
Added:
192
Added:
let pullovers =
193
Added:
exercise
194
Added:
{ equipment = Unspecified; movement = Pullover; variation = Standard }
195
Added:
196
Added:
let straight_arm_pulldowns =
197
Added:
exercise
198
Added:
{ equipment = Cable; movement = Pulldown; variation = Straight_arm }
199
Added:
200
Added:
let close_grip_pulldowns =
201
Added:
exercise
202
Added:
{
203
Added:
equipment = Cable;
204
Added:
movement = Pulldown;
205
Added:
variation = Close_grip_palms_up;
206
Added:
}
207
Added:
208
Added:
let bent_over_rows =
209
Added:
exercise { equipment = Barbell; movement = Row; variation = Bent_over }
210
Added:
211
Added:
let shrugs =
212
Added:
exercise { equipment = Unspecified; movement = Shrug; variation = Standard }
213
Added:
214
Added:
let hyperextensions =
215
Added:
exercise
216
Added:
{
217
Added:
equipment = Bodyweight;
218
Added:
movement = Hyperextension;
219
Added:
variation = Standard;
220
Added:
}
221
Added:
222
Added:
let deadlifts =
223
Added:
exercise { equipment = Barbell; movement = Deadlift; variation = Standard }
224
Added:
225
Added:
let curls =
226
Added:
exercise { equipment = Barbell; movement = Curl; variation = Standard }
227
Added:
228
Added:
let preacher_curls =
229
Added:
exercise { equipment = Barbell; movement = Curl; variation = Preacher }
230
Added:
231
Added:
let leg_extensions =
232
Added:
exercise
233
Added:
{ equipment = Machine; movement = Leg_extension; variation = Standard }
234
Added:
235
Added:
let leg_presses =
236
Added:
exercise { equipment = Machine; movement = Leg_press; variation = Standard }
237
Added:
238
Added:
let squats =
239
Added:
exercise { equipment = Barbell; movement = Squat; variation = Standard }
240
Added:
241
Added:
let leg_curls =
242
Added:
exercise { equipment = Machine; movement = Leg_curl; variation = Standard }
243
Added:
244
Added:
let calf_raises =
245
Added:
exercise
246
Added:
{ equipment = Unspecified; movement = Calf_raise; variation = Standard }
247
Added:
248
Added:
let sit_ups =
249
Added:
exercise { equipment = Bodyweight; movement = Sit_up; variation = Standard }
250
Added:
150
251
(* HD1's guideline window for every listed exercise. *)
151
252
let six_to_ten = Result.get_ok (Rep_range.make ~min:6 ~max:10)
152
253
153
254
let prescribe ?(substitutes = []) delivery =
154
255
Stimulus.make ~delivery ~rep_range:six_to_ten
155
Removed:
~allowed_substitutes:(List.map movement substitutes)
256
Added:
~allowed_substitutes:substitutes
156
257
157
Removed:
let single ?substitutes id =
158
Removed:
prescribe ?substitutes (Stimulus.Single (movement id))
258
Added:
let single ?substitutes exercise =
259
Added:
prescribe ?substitutes (Stimulus.Single exercise)
159
260
160
261
let pre_exhaust ?substitutes ~isolation ~compound () =
161
Removed:
prescribe ?substitutes
162
Removed:
(Stimulus.Pre_exhaust
163
Removed:
{ isolation = movement isolation; compound = movement compound })
262
Added:
prescribe ?substitutes (Stimulus.Pre_exhaust { isolation; compound })
164
263
165
264
let day ~name stimuli = Workout.make ~name ~stimuli
166
265
@@ -168,35 +267,34 @@
168
267
day ~name:"Day 1"
169
268
[
170
269
pre_exhaust
171
Removed:
~substitutes:[ "cable-crossovers"; "pec-deck" ]
172
Removed:
~isolation:"dumbbell-flyes" ~compound:"incline-press" ();
173
Removed:
single "laterals";
174
Removed:
single ~substitutes:[ "reverse-pec-deck" ] "bent-over-laterals";
270
Added:
~substitutes:[ cable_crossovers; pec_deck ]
271
Added:
~isolation:dumbbell_flyes ~compound:incline_presses ();
272
Added:
single laterals;
273
Added:
single ~substitutes:[ reverse_pec_deck ] bent_over_laterals;
175
274
pre_exhaust
176
Removed:
~substitutes:[ "pressdowns"; "triceps-machine" ]
177
Removed:
~isolation:"lying-french-press" ~compound:"dips" ();
275
Added:
~substitutes:[ pressdowns; triceps_machine ]
276
Added:
~isolation:lying_french_presses ~compound:dips ();
178
277
]
179
278
180
279
let ideal_day_two =
181
280
day ~name:"Day 2"
182
281
[
183
Removed:
pre_exhaust
184
Removed:
~substitutes:[ "straight-arm-pulldowns" ]
185
Removed:
~isolation:"pullovers" ~compound:"close-grip-pulldowns" ();
186
Removed:
single "bent-over-rows";
187
Removed:
single "shrugs";
188
Removed:
single ~substitutes:[ "deadlifts" ] "hyperextensions";
189
Removed:
single ~substitutes:[ "preacher-curls" ] "curls";
282
Added:
pre_exhaust ~substitutes:[ straight_arm_pulldowns ] ~isolation:pullovers
283
Added:
~compound:close_grip_pulldowns ();
284
Added:
single bent_over_rows;
285
Added:
single shrugs;
286
Added:
single ~substitutes:[ deadlifts ] hyperextensions;
287
Added:
single ~substitutes:[ preacher_curls ] curls;
190
288
]
191
289
192
290
let ideal_day_three =
193
291
day ~name:"Day 3"
194
292
[
195
Removed:
pre_exhaust ~substitutes:[ "squats" ] ~isolation:"leg-extensions"
196
Removed:
~compound:"leg-presses" ();
197
Removed:
single "leg-curls";
198
Removed:
single "calf-raises";
199
Removed:
single "sit-ups";
293
Added:
pre_exhaust ~substitutes:[ squats ] ~isolation:leg_extensions
294
Added:
~compound:leg_presses ();
295
Added:
single leg_curls;
296
Added:
single calf_raises;
297
Added:
single sit_ups;
200
298
]
201
299
202
300
let[@warning "-32"] ideal =
test/test_decode.ml
@@ -2,7 +2,7 @@
2
2
module Form = Dream_html.Form
3
3
4
4
let exercise id =
5
Removed:
match Exercise.find id with
5
Added:
match Exercise.find_id id with
6
6
| Some exercise -> exercise
7
7
| None -> Alcotest.failf "catalog is missing %S" id
8
8
test/test_evidence.ml
@@ -8,7 +8,7 @@
8
8
let ok = function Ok v -> v | Error _ -> Alcotest.fail "expected Ok"
9
9
10
10
let get id =
11
Removed:
match Exercise.find id with
11
Added:
match Exercise.find_id id with
12
12
| Some e -> e
13
13
| None -> Alcotest.failf "catalog is missing %S" id
14
14
test/test_exercise.ml
@@ -1,21 +1,54 @@
1
1
(** Unit tests for {!Exercise}, authored against the exercise.mli contract. *)
2
2
3
3
let get id =
4
Removed:
match Exercise.find id with
4
Added:
match Exercise.find_id id with
5
5
| Some e -> e
6
6
| None -> Alcotest.failf "catalog is missing %S" id
7
7
8
Added:
let dumbbell_flyes =
9
Added:
{
10
Added:
Exercise.equipment = Exercise.Dumbbell;
11
Added:
movement = Exercise.Fly;
12
Added:
variation = Exercise.Standard;
13
Added:
}
14
Added:
8
15
let lookup_tests =
9
16
[
10
Removed:
( "find locates curated entries and rejects unknown ids",
17
Added:
( "a structured key locates the curated exercise",
11
18
`Quick,
12
19
fun () ->
13
Removed:
Alcotest.(check string)
14
Removed:
"name" "Dumbbell Flyes"
15
Removed:
(Exercise.name (get "dumbbell-flyes"));
20
Added:
match Exercise.find dumbbell_flyes with
21
Added:
| Some exercise ->
22
Added:
Alcotest.(check string)
23
Added:
"name" "Dumbbell Flyes" (Exercise.name exercise);
24
Added:
Alcotest.(check bool)
25
Added:
"key round-trips" true
26
Added:
(Exercise.key exercise = dumbbell_flyes);
27
Added:
Alcotest.(check string)
28
Added:
"stable id" "dumbbell-flyes"
29
Added:
(Exercise.id exercise :> string)
30
Added:
| None -> Alcotest.fail "Dumbbell Flyes key is absent" );
31
Added:
( "an absent structured key is rejected",
32
Added:
`Quick,
33
Added:
fun () ->
16
34
Alcotest.(check bool)
17
Removed:
"unknown" true
18
Removed:
(Option.is_none (Exercise.find "jefferson-curl")) );
35
Added:
"no dumbbell press in HD1 catalog" true
36
Added:
(Option.is_none
37
Added:
(Exercise.find
38
Added:
{
39
Added:
Exercise.equipment = Exercise.Dumbbell;
40
Added:
movement = Exercise.Press;
41
Added:
variation = Exercise.Standard;
42
Added:
})) );
43
Added:
( "a stable identifier remains an external lookup boundary",
44
Added:
`Quick,
45
Added:
fun () ->
46
Added:
Alcotest.(check bool)
47
Added:
"stable id" true
48
Added:
(Option.is_some (Exercise.find_id "dumbbell-flyes"));
49
Added:
Alcotest.(check bool)
50
Added:
"unknown id" true
51
Added:
(Option.is_none (Exercise.find_id "jefferson-curl")) );
19
52
]
20
53
21
54
let pre_exhaust_tests =
test/test_prescription.ml
@@ -4,7 +4,7 @@
4
4
let ok = function Ok v -> v | Error _ -> Alcotest.fail "expected Ok"
5
5
6
6
let get id =
7
Removed:
match Exercise.find id with
7
Added:
match Exercise.find_id id with
8
8
| Some e -> e
9
9
| None -> Alcotest.failf "catalog is missing %S" id
10
10
test/test_progression.ml
@@ -6,7 +6,7 @@
6
6
let ok = function Ok v -> v | Error _ -> Alcotest.fail "expected Ok"
7
7
8
8
let get id =
9
Removed:
match Exercise.find id with
9
Added:
match Exercise.find_id id with
10
10
| Some e -> e
11
11
| None -> Alcotest.failf "catalog is missing %S" id
12
12
test/test_service.ml
@@ -8,7 +8,7 @@
8
8
let ok = function Ok v -> v | Error _ -> Alcotest.fail "expected Ok"
9
9
10
10
let get id =
11
Removed:
match Exercise.find id with
11
Added:
match Exercise.find_id id with
12
12
| Some e -> e
13
13
| None -> Alcotest.failf "catalog is missing %S" id
14
14