+%{2} % [| % [ % | whd >copy_char_q0_q1 // ]]
+qed.
+
+definition obj ≝ (0:DeqNat).
+definition cfg ≝ (1:DeqNat).
+definition prg ≝ (2:DeqNat).
+
+definition obj_to_cfg ≝
+ mmove cfg FSUnialpha 2 L ·
+ (ifTM ?? (inject_TM ? (test_null ?) 2 obj)
+ (copy_char obj cfg FSUnialpha 2 ·
+ mmove cfg FSUnialpha 2 L ·
+ mmove obj FSUnialpha 2 L)
+ (inject_TM ? (write FSUnialpha null) 2 cfg)
+ tc_true) ·
+ inject_TM ? (move_to_end FSUnialpha L) 2 cfg ·
+ mmove cfg FSUnialpha 2 R.
+
+definition R_obj_to_cfg ≝ λt1,t2:Vector (tape FSUnialpha) 3.
+ ∀c,ls.
+ nth cfg ? t1 (niltape ?) = mk_tape FSUnialpha (c::ls) (None ?) [ ] →
+ (∀lso,x,rso.nth obj ? t1 (niltape ?) = midtape FSUnialpha lso x rso →
+ t2 = change_vec ?? t1
+ (mk_tape ? [ ] (option_hd ? (reverse ? (x::ls))) (tail ? (reverse ? (x::ls)))) cfg) ∧
+ (current ? (nth obj ? t1 (niltape ?)) = None ? →
+ t2 = change_vec ?? t1
+ (mk_tape ? [ ] (option_hd FSUnialpha (reverse ? (null::ls)))
+ (tail ? (reverse ? (null::ls)))) cfg).
+
+axiom accRealize_to_Realize :
+ ∀sig,n.∀M:mTM sig n.∀Rtrue,Rfalse,acc.
+ M ⊨ [ acc: Rtrue, Rfalse ] → M ⊨ Rtrue ∪ Rfalse.
+
+lemma eq_mk_tape_rightof :
+ ∀alpha,a,al.mk_tape alpha (a::al) (None ?) [ ] = rightof ? a al.
+#alpha #a #al %
+qed.
+
+definition option_cons ≝ λsig.λc:option sig.λl.
+ match c with [ None ⇒ l | Some c0 ⇒ c0::l ].
+
+lemma tape_move_mk_tape_R :
+ ∀sig,ls,c,rs.
+ (c = None ? → ls = [ ] ∨ rs = [ ]) →
+ tape_move ? (mk_tape sig ls c rs) R =
+ mk_tape ? (option_cons ? c ls) (option_hd ? rs) (tail ? rs).
+#sig * [ * [ * | #c * ] | #l0 #ls0 * [ *
+[| #r0 #rs0 #H @False_ind cases (H (refl ??)) #H1 destruct (H1) ] | #c * ] ]
+normalize //
+qed.
+
+lemma eq_vec_change_vec : ∀sig,n.∀v1,v2:Vector sig n.∀i,t,d.
+ nth i ? v2 d = t →
+ (∀j.i ≠ j → nth j ? v1 d = nth j ? v2 d) →
+ v2 = change_vec ?? v1 t i.
+#sig #n #v1 #v2 #i #t #d #H1 #H2 @(eq_vec … d)
+#i0 #Hlt cases (decidable_eq_nat i0 i) #Hii0
+[ >Hii0 >nth_change_vec //
+| >nth_change_vec_neq [|@sym_not_eq //] @sym_eq @H2 @sym_not_eq // ]
+qed.
+
+lemma sem_obj_to_cfg : obj_to_cfg ⊨ R_obj_to_cfg.
+@(sem_seq_app FSUnialpha 2 ????? (sem_move_multi ? 2 cfg L ?)
+ (sem_seq ??????
+ (sem_if ??????????
+ (sem_test_null_multi ?? obj ?)
+ (sem_seq ?????? (sem_copy_char …)
+ (sem_seq ?????? (sem_move_multi ? 2 cfg L ?)
+ (sem_move_multi ? 2 obj L ?)))
+ (sem_inject ???? cfg ? (sem_write FSUnialpha null)))
+ (sem_seq ?????? (sem_inject ???? cfg ? (sem_move_to_end_l ?))
+ (sem_move_multi ? 2 cfg R ?)))) //
+#ta #tb *
+#tc * whd in ⊢ (%→?); #Htc *
+#td * *
+[ * #te * * #Hcurtc #Hte
+ * destruct (Hte) #te * whd in ⊢ (%→?); #Hte
+ cut (∃x.current ? (nth obj ? tc (niltape ?)) = Some ? x)
+ [ cases (current ? (nth obj ? tc (niltape ?))) in Hcurtc;
+ [ * #H @False_ind /2/ | #x #_ %{x} % ] ] * #x #Hcurtc'
+(* [ whd in ⊢ (%→%→?); * #x * #y * * -Hcurtc #Hcurtc1 #Hcurtc2 #Hte *)
+ * #tf * whd in ⊢ (%→%→?); #Htf #Htd
+ * #tg * * * whd in ⊢ (%→%→%→%→?); #Htg1 #Htg2 #Htg3 #Htb
+ #c #ls #Hta1 %
+ [ #lso #x0 #rso #Hta2 >Hta1 in Htc; >eq_mk_tape_rightof
+ whd in match (tape_move ???); #Htc
+ cut (tg = change_vec ?? td (mk_tape ? [ ] (None ?) (reverse ? ls@[x])) cfg)
+ [ lapply (eq_vec_change_vec ??????? (Htg2 ls x [ ] ?) Htg3) //
+ >Htd >nth_change_vec_neq // >Htf >nth_change_vec //
+ >Hte >Hcurtc' >nth_change_vec // >Htc >nth_change_vec // ]
+ -Htg1 -Htg2 -Htg3 #Htg destruct
+ >change_vec_change_vec >change_vec_change_vec
+ >change_vec_commute // >change_vec_change_vec
+ >change_vec_commute [|@sym_not_eq //] >change_vec_change_vec
+ >change_vec_commute // >change_vec_change_vec
+ >nth_change_vec // >nth_change_vec_neq [|@sym_not_eq //]
+ >nth_change_vec // >nth_change_vec_neq [|@sym_not_eq //]
+ >change_vec_commute [|@sym_not_eq //] @eq_f3 //
+ [ >Hta2 cases rso in Hta2; whd in match (tape_move_mono ???);
+ [ #Hta2 whd in match (tape_move ???); <Hta2 @change_vec_same
+ | #r1 #rs1 #Hta2 whd in match (tape_move ???); <Hta2 @change_vec_same ]
+ | >tape_move_mk_tape_R [| #_ % %] >reverse_cons
+ >nth_change_vec_neq in Hcurtc'; [|@sym_not_eq //] >Hta2
+ normalize in ⊢ (%→?); #H destruct (H) %