Module Transform.
Definition basic (op: Instruction) : bool :=
match op with
| (([], [a], _), ([b], [], _)) => true
| (([a], [], _), ([], [b], _)) => true
| _ => false
end.
Definition weight_Instruction (op: Instruction) : nat :=
if basic op then 0 else
match op with
| ((l, r, _), (l', _, _)) => 1 + length (l ++ l' ++ l ++ r)
end.
Definition weight (M: SMN) : nat :=
fold_right (fun op w => w + weight_Instruction op) 0 M.
Fixpoint fresh_State (M: SMN) : State :=
match M with
| [] => 1
| ((_, _, x), (_, _, y)) :: M => 1 + x + y + fresh_State M
end.

(* from any confluent and length preserving SMN construct a boundedness-equivalent, confluent, length preserving SMN with only rules of weight 0 *)
Theorem minimize_weight (M: SMN) :
confluent M -> length_preserving M ->
{ M' : SMN | weight M' = 0 /\ (confluent M' /\ length_preserving M' /\ ((exists NM, bounded M NM) <-> (exists NM', bounded M' NM'))) }.