(* ** 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 **)

(* Specifications: *)
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.
Lemma rewrite_step_conf (c1: conf) :
(halt (cstate c1) = false) -> rew' TMrules (mk_srconf c1) (mk_srconf (step c1)).
Lemma state_eqlist A B C D q1 q2:
A ++(state q1)::B = C++(state q2)::D
-> (exists (E F: list rsig'), C = List.map symb E /\ D = List.map symb F)
-> A = C /\ B = D /\ q1 = q2.