(* ** Definition of Rewrite Rules Simulating a Transition **)
Definition get_rules_left (q1 q2: states T) (old new: option sig) : list (list rsig * list rsig):=
match old,new with
|None,None => List.map (fun c => ([sym c; state q1; $], [state q2; sym c; $])) (elem sig)
|None,Some b => List.map (fun c => ([sym c; state q1; $], [state q2; sym c; sym b; $])) (elem sig)
|Some a,None => List.map (fun c => ([sym c; state q1; sym a], [state q2; sym c; sym a])) (elem sig)
|Some a,Some b => List.map (fun c => ([sym c; state q1; sym a], [state q2; sym c; sym b])) (elem sig)
end.
Definition get_rules_right (q1 q2: states T) : list (list rsig * list rsig) :=
List.map (fun a => ([state q1; #; sym a],[#; state q2; sym a])) (elem sig).
Definition get_rules (q1 q2: states T) (old new: option sig) (m: move) :
list (list rsig * list rsig) :=
match old,new,m with
|None,None,L => [([state q1; #],[state q2; #])] ++ (get_rules_left q1 q2 None None)
|None,None,N => [([state q1; #],[state q2; #]);([state q1; $],[state q2; $])]
|None,None,R => [([state q1; #;$],[state q2; #;$]); ([state q1; $],[state q2; $])]
++ (get_rules_right q1 q2)
|None,Some b,L => [([state q1; #],[state q2; #; sym b])] ++ (get_rules_left q1 q2 None (Some b))
|None,Some b,N => [([state q1; #],[#; state q2; sym b]); ([state q1; $],[state q2; sym b; $])]
|None,Some b,R => [([state q1; #],[#; sym b; state q2]); ([state q1; $],[sym b; state q2; $])]
|Some a,None,L => [([#;state q1; sym a],[state q2; #; sym a])]
++ (get_rules_left q1 q2 (Some a) None)
|Some a,None,N => [([state q1; sym a],[state q2; sym a])]
|Some a,None,R => [([state q1; sym a],[sym a; state q2])]
|Some a,Some b,L => [([#; state q1; sym a],[state q2; #; sym b])]
++ (get_rules_left q1 q2 (Some a) (Some b))
|Some a,Some b,N => [([state q1; sym a],[state q2; sym b])]
|Some a,Some b,R => [([state q1; sym a],[sym b; state q2])]
end.
Definition TMrules : list (list rsig * list rsig) :=
List.concat ((List.map (fun q1 => match trans (q1,None) with
|(q2,(o,m)) => get_rules q1 q2 None o m
end) not_halting_states) ++
(List.map (fun (P: states T * sig) => let (q1,s) := P in match trans (q1,Some s) with
|(q2,(o,m)) => get_rules q1 q2 (Some s) o m
end)
(list_prod not_halting_states (elem sig)))).
(* ** Correctness Proof **)

Lemma get_rules_el_TMrules (q1 q2: states T) (old new: option sig) (m: move) :
halt q1 = false -> (trans (q1,old) = (q2,(new,m)))
-> get_rules q1 q2 old new m <<= TMrules.