+record normalTM : Type[0] ≝
+{ no_states : nat;
+ pos_no_states : (0 < no_states);
+ ntrans : trans_source no_states → trans_target no_states;
+ nhalt : initN no_states → bool
+}.
+
+definition normalTM_to_TM ≝ λM:normalTM.
+ mk_TM FinBool (initN (no_states M))
+ (ntrans M) (mk_Sig ?? 0 (pos_no_states M)) (nhalt M).
+
+coercion normalTM_to_TM.
+
+definition nconfig ≝ λn. config FinBool (initN n).
+
+(*
+definition normalTM ≝ λn,t,h.
+ λk:0<n.mk_TM FinBool (initN n) t (mk_Sig ?? 0 k) h. *)
+
+definition low_config: ∀M:normalTM.nconfig (no_states M) → tape STape ≝
+λM:normalTM.λc.
+ let n ≝ no_states M in
+ let h ≝ nhalt M in
+ let t ≝ntrans M in
+ let q ≝ cstate … c in
+ let q_low ≝ m_bits_of_state n h q in
+ let current_low ≝ match current … (ctape … c) with [ None ⇒ null | Some b ⇒ bit b] in
+ let low_left ≝ map … (λb.〈bit b,false〉) (left … (ctape …c)) in
+ let low_right ≝ map … (λb.〈bit b,false〉) (right … (ctape …c)) in
+ let table ≝ flatten ? (tuples_of_pairs n h (graph_enum ?? t)) in
+ let right ≝ q_low@〈current_low,false〉::〈grid,false〉::table@〈grid,false〉::low_right in
+ mk_tape STape (〈grid,false〉::low_left) (option_hd … right) (tail … right).
+
+lemma low_config_eq: ∀t,M,c. t = low_config M c →
+ ∃low_left,low_right,table,q_low_hd,q_low_tl,c_low.
+ low_left = map … (λb.〈bit b,false〉) (left … (ctape …c)) ∧
+ low_right = map … (λb.〈bit b,false〉) (right … (ctape …c)) ∧
+ table = flatten ? (tuples_of_pairs (no_states M) (nhalt M) (graph_enum ?? (ntrans M))) ∧
+ 〈q_low_hd,false〉::q_low_tl = m_bits_of_state (no_states M) (nhalt M) (cstate … c) ∧
+ c_low = match current … (ctape … c) with [ None ⇒ null| Some b ⇒ bit b] ∧
+ t = midtape STape (〈grid,false〉::low_left) 〈q_low_hd,false〉 (q_low_tl@〈c_low,false〉::〈grid,false〉::table@〈grid,false〉::low_right).
+#t #M #c #eqt
+ @(ex_intro … (map … (λb.〈bit b,false〉) (left … (ctape …c))))
+ @(ex_intro … (map … (λb.〈bit b,false〉) (right … (ctape …c))))
+ @(ex_intro … (flatten ? (tuples_of_pairs (no_states M) (nhalt M) (graph_enum ?? (ntrans M)))))
+ @(ex_intro … (\fst (hd ? (m_bits_of_state (no_states M) (nhalt M) (cstate … c)) 〈bit true,false〉)))
+ @(ex_intro … (tail ? (m_bits_of_state (no_states M) (nhalt M) (cstate … c))))
+ @(ex_intro … (match current … (ctape … c) with [ None ⇒ null| Some b ⇒ bit b]))
+% [% [% [% [% // | // ] | // ] | // ] | >eqt //]
+qed.
+
+let rec to_bool_list (l: list (unialpha×bool)) ≝
+ match l with
+ [ nil ⇒ nil ?
+ | cons a tl ⇒
+ match \fst a with
+ [bit b ⇒ b::to_bool_list tl
+ |_ ⇒ nil ?
+ ]
+ ].
+
+definition high_c ≝ λc:unialpha×bool.
+ match \fst c with
+ [ null ⇒ None ?
+ | bit b ⇒ Some ? b
+ | _ ⇒ None ?].
+
+definition high_tape ≝ λls,c,rs.
+ mk_tape FinBool (to_bool_list ls) (high_c c) (to_bool_list rs).
+
+lemma high_tape_eq : ∀ls,c,rs. high_tape ls c rs =
+ mk_tape FinBool (to_bool_list ls) (high_c c) (to_bool_list rs).
+// qed.
+
+definition high_tape_from_tape ≝ λt:tape STape.
+ match t with
+ [niltape ⇒ niltape ?
+ |leftof a l ⇒ match \fst a with
+ [bit b ⇒ leftof ? b (to_bool_list l)
+ |_ ⇒ niltape ?
+ ]
+ |rightof a r ⇒ match \fst a with
+ [bit b ⇒ rightof ? b (to_bool_list r)
+ |_ ⇒ niltape ?
+ ]
+ |midtape l c r ⇒ high_tape l c r
+ ].
+
+lemma high_tape_of_lift : ∀ls,c,rs. legal_tape ls c rs →
+ high_tape ls c rs =
+ high_tape_from_tape (lift_tape ls c rs).
+#ls * #c #b #rs * #H cases c //
+>high_tape_eq
+* [ * [#H @False_ind /2/
+ | #Heq >Heq cases rs // * #a #b1 #tl
+ whd in match (lift_tape ???); cases a //
+ ]
+ |#Heq >Heq cases ls // * #a #b1 #tl
+ whd in match (lift_tape ???); cases a //
+ ]
+qed.
+
+lemma bool_embedding: ∀l.
+ to_bool_list (map ?? (λb.〈bit b,false〉) l) = l.
+#l elim l // #a #tl #Hind normalize @eq_f @Hind
+qed.
+
+lemma current_embedding: ∀c.
+ high_c (〈match c with [None ⇒ null | Some b ⇒ bit b],false〉) = c.
+ * normalize // qed.
+
+lemma tape_embedding: ∀ls,c,rs.
+ high_tape
+ (map ?? (λb.〈bit b,false〉) ls)
+ (〈match c with [None ⇒ null | Some b ⇒ bit b],false〉)
+ (map ?? (λb.〈bit b,false〉) rs) = mk_tape ? ls c rs.
+#ls #c #rs >high_tape_eq >bool_embedding >bool_embedding
+>current_embedding %
+qed.
+
+definition high_move ≝ λc,mv.
+ match c with
+ [ bit b ⇒ Some ? 〈b,move_of_unialpha mv〉
+ | _ ⇒ None ?
+ ].
+
+(* lemma high_of_lift ≝ ∀ls,c,rs.
+ high_tape ls c rs = *)
+
+definition map_move ≝
+ λc,mv.match c with [ null ⇒ None ? | _ ⇒ Some ? 〈c,false,move_of_unialpha mv〉 ].
+
+(* axiom high_tape_move : ∀t1,ls,c,rs, c1,mv.
+ legal_tape ls c rs →
+ t1 = lift_tape ls c rs →
+ high_tape_from_tape (tape_move STape t1 (map_move c1 mv)) =
+ tape_move FinBool (high_tape_from_tape t1) (high_move c1 mv). *)
+
+definition low_step_R_true ≝ λt1,t2.
+ ∀M:normalTM.
+ ∀c: nconfig (no_states M).
+ t1 = low_config M c →
+ halt ? M (cstate … c) = false ∧
+ t2 = low_config M (step ? M c).
+
+definition low_tape_aux : ∀M:normalTM.tape FinBool → tape STape ≝
+λM:normalTM.λt.
+ let current_low ≝ match current … t with
+ [ None ⇒ None ? | Some b ⇒ Some ? 〈bit b,false〉] in
+ let low_left ≝ map … (λb.〈bit b,false〉) (left … t) in
+ let low_right ≝ map … (λb.〈bit b,false〉) (right … t) in
+ mk_tape STape low_left current_low low_right.
+
+lemma left_of_low_tape: ∀M,t.
+ left ? (low_tape_aux M t) = map … (λb.〈bit b,false〉) (left … t).
+#M * //
+qed.
+
+lemma right_of_low_tape: ∀M,t.
+ right ? (low_tape_aux M t) = map … (λb.〈bit b,false〉) (right … t).
+#M * //
+qed.
+
+definition low_move ≝ λaction:option (bool × move).
+ match action with
+ [None ⇒ None ?
+ |Some act ⇒ Some ? (〈〈bit (\fst act),false〉,\snd act〉)].
+
+(* simulation lemma *)
+lemma low_tape_move : ∀M,action,t.
+ tape_move STape (low_tape_aux M t) (low_move action) =
+ low_tape_aux M (tape_move FinBool t action).
+#M * // (* None *)
+* #b #mv #t cases mv cases t //
+ [#ls #c #rs cases ls //|#ls #c #rs cases rs //]
+qed.
+
+lemma left_of_lift: ∀ls,c,rs. left ? (lift_tape ls c rs) = ls.
+#ls * #c #b #rs cases c // cases ls // cases rs //
+qed.
+
+lemma right_of_lift: ∀ls,c,rs. legal_tape ls c rs →
+ right ? (lift_tape ls c rs) = rs.
+#ls * #c #b #rs * #_ cases c // cases ls cases rs // #a #tll #b #tlr
+#H @False_ind cases H [* [#H1 /2/ |#H1 destruct] |#H1 destruct]
+qed.
+
+
+lemma current_of_lift: ∀ls,c,b,rs. legal_tape ls 〈c,b〉 rs →
+ current STape (lift_tape ls 〈c,b〉 rs) =
+ match c with [null ⇒ None ? | _ ⇒ Some ? 〈c,b〉].
+#ls #c #b #rs cases c // whd in ⊢ (%→?); * #_
+* [* [#Hnull @False_ind /2/ | #Hls >Hls whd in ⊢ (??%%); cases rs //]
+ |#Hrs >Hrs whd in ⊢ (??%%); cases ls //]
+qed.
+
+lemma current_of_lift_None: ∀ls,c,b,rs. legal_tape ls 〈c,b〉 rs →
+ current STape (lift_tape ls 〈c,b〉 rs) = None ? →
+ c = null.
+#ls #c #b #rs #Hlegal >(current_of_lift … Hlegal) cases c normalize
+ [#b #H destruct |// |3,4,5:#H destruct ]
+qed.
+
+lemma current_of_lift_Some: ∀ls,c,c1,rs. legal_tape ls c rs →
+ current STape (lift_tape ls c rs) = Some ? c1 →
+ c = c1.
+#ls * #c #cb #b #rs #Hlegal >(current_of_lift … Hlegal) cases c normalize
+ [#b1 #H destruct // |#H destruct |3,4,5:#H destruct //]
+qed.
+
+lemma current_of_low_None: ∀M,t. current FinBool t = None ? →
+ current STape (low_tape_aux M t) = None ?.
+#M #t cases t // #l #b #r whd in ⊢ ((??%?)→?); #H destruct
+qed.
+
+lemma current_of_low_Some: ∀M,t,b. current FinBool t = Some ? b →
+ current STape (low_tape_aux M t) = Some ? 〈bit b,false〉.
+#M #t cases t
+ [#b whd in ⊢ ((??%?)→?); #H destruct
+ |#b #l #b1 whd in ⊢ ((??%?)→?); #H destruct
+ |#b #l #b1 whd in ⊢ ((??%?)→?); #H destruct
+ |#c #c1 #l #r whd in ⊢ ((??%?)→?); #H destruct %
+ ]
+qed.
+
+lemma current_of_low:∀M,tape,ls,c,rs. legal_tape ls c rs →
+ lift_tape ls c rs = low_tape_aux M tape →
+ c = 〈match current … tape with
+ [ None ⇒ null | Some b ⇒ bit b], false〉.
+#M #tape #ls * #c #cb #rs #Hlegal #Hlift
+cut (current ? (lift_tape ls 〈c,cb〉 rs) = current ? (low_tape_aux M tape))
+ [@eq_f @Hlift] -Hlift #Hlift
+cut (current … tape = None ? ∨ ∃b.current … tape = Some ? b)
+ [cases (current … tape) [%1 // | #b1 %2 /2/ ]] *
+ [#Hcurrent >Hcurrent normalize
+ >(current_of_low_None …Hcurrent) in Hlift; #Hlift
+ >(current_of_lift_None … Hlegal Hlift)
+ @eq_f cases Hlegal * * #Hmarks #_ #_ #_ @(Hmarks 〈c,cb〉) @memb_hd
+ |* #b #Hcurrent >Hcurrent normalize
+ >(current_of_low_Some …Hcurrent) in Hlift; #Hlift
+ @(current_of_lift_Some … Hlegal Hlift)
+ ]
+qed.