Section MM2_CM1.
Variable (P: list mm2_instr). (* MM2 program *)
Variables (a0 b0: nat). (* MM2 initial counters *)
(* encode start counters *)
Definition encode_init : list CM1.Instruction :=
(map (fun i => (1+i, 0)) (seq 0 (a0 + b0))) ++ (* a0+b0 times 2/1 *)
(map (fun i => (1+i, 1)) (seq (a0 + b0) b0)). (* b0 times 3/2 *)
(* instruction index map *)
Definition fs (i: nat) : CM1.State :=
if i is S i then i*6 + a0 + b0 + b0 else (length P)*6 + a0 + b0 + b0.
(* encode instruction mmi at position i using index map fs for current cm1 state p *)
Definition encode_instruction (mmi: mm2_instr) (i: nat) : list CM1.Instruction :=
let p := fs i in
match mmi with
| mm2_inc_a =>
[(fs (1+i), 0)] ++ (* 2/1, goto i+1 *)
[(0, 0); (0, 0); (0, 0); (0, 0); (0, 0)] (* filler *)
| mm2_inc_b =>
[(1+p, 0); (fs (1+i), 1)] ++ (* 2/1; 3/2, goto i+1 *)
[(0, 0); (0, 0); (0, 0); (0, 0)] (* filler *)
| mm2_dec_a j =>
[(4+p, 1)] ++ (* 3/2 *)
[(2+p, 0); (3+p, 0); (fs (1+i), 3)] ++ (* fail: 2/1; 2/1; 5/4 goto i+1 *)
[(5+p, 2); (fs j, 3)] (* success: 4/3; 5/4 goto j *)
| mm2_dec_b j => [(4+p, 2)] ++ (* 4/3 *)
[(2+p, 0); (3+p, 0); (fs (1+i), 3)] ++ (* fail: 2/1; 2/1; 5/4 goto i+1 *)
[(fs j, 3)] ++ (* success: 5/4 goto j *)
[(0, 0)] (* filler *)
end.
(* one counter machine encoding P in start cofiguration (1, (a0, b0)) *)
Definition M : list CM1.Instruction :=
encode_init ++ flat_map (fun '(a, i) => encode_instruction a i) (combine P (seq 1 (length P))).

(* M has denominators of at most 4 *)
Lemma M_capped : Forall (fun '(_, n) => n < 4) M.