From Undecidability Require Import TM.Prelim.
From Undecidability Require Import TM TM.Compound.MoveToSymbol.
Require Import ssrbool Lia.
Lemma last_not_default X (d d':X) A :
A <> [] -> last A d = last A d'.
Proof. induction A. easy. destruct A;cbn. easy. intros ?. now apply IHA. Qed.
Lemma removelast_as_tail X (x:list X): removelast x = rev (tail (rev x)).
Proof.
rewrite tl_rev. now autorewrite with list.
Qed.
Local Arguments removelast : simpl nomatch.
Local Arguments last : simpl nomatch.
From Undecidability Require Import TM TM.Compound.MoveToSymbol.
Require Import ssrbool Lia.
Lemma last_not_default X (d d':X) A :
A <> [] -> last A d = last A d'.
Proof. induction A. easy. destruct A;cbn. easy. intros ?. now apply IHA. Qed.
Lemma removelast_as_tail X (x:list X): removelast x = rev (tail (rev x)).
Proof.
rewrite tl_rev. now autorewrite with list.
Qed.
Local Arguments removelast : simpl nomatch.
Local Arguments last : simpl nomatch.
TIPP: Look in ./Copy.v I have no Idea anymore why i called this nicer ...
Definition MoveToSymbol_Rel_nice (sig':finType) (f:sig' -> bool) (g:sig' -> sig') t t' :=
((current t = None /\ t = t')
\/ (exists t__L c t__R1 t__R2,
t = midtape t__L c (t__R1++t__R2)
/\ (forall x, x el (removelast (c::t__R1)) -> f x = false)
/\ f (last (c::t__R1) c) = ssrbool.isSome (current t')
/\ (t' = midtape (rev (map g (removelast (c::t__R1)))++t__L) (g (last (c::t__R1) c)) t__R2
\/ (t' = rightof (g (last (c::t__R1) c)) (rev (map g (removelast (c::t__R1)))++t__L) /\ t__R2 = [])))).
Lemma MoveToSymbol_Fun_nice (sig':finType) (f:sig' -> bool) (g:sig' -> sig') t t' :
MoveToSymbol_Fun f g t = t' <-> MoveToSymbol_Rel_nice f g t t'.
Proof.
remember (tape_local t) as A eqn:eqA.
revert t t' eqA. unfold MoveToSymbol_Rel_nice.
induction A using (size_induction (f:=@length sig'));intros t t' eqA.
rewrite MoveToSymbol_Fun_equation. destruct current eqn:eq.
2:{ split. now left. intros [ | H']. easy. destruct H' as (?&?&?&?&->&?). easy. }
destruct f eqn:Hf.
{ destruct t;inv eq. all:cbn. split.
-intros <-. right. eexists _,_,[],_.
repeat split;eauto.
-intros [ | (t__L&c&t__R1&t__R2&[= -> -> -> ]&Hfalse&Hc&H'')];[ easy | ].
destruct t__R1 as [ | c__R t__R1].
2:{exfalso. cbn in *. rewrite Hfalse in Hf;auto. }
cbn in *.
destruct H'' as [-> | [-> -> ]]. all:cbn in *;now eauto + congruence.
}
destruct t. all:inv eq. destruct l0. all:cbn - [removelast].
all:rewrite H;[ | | reflexivity];[cbn | cbn;nia].
- cbn. split.
+intros [(_&<-)| (?&?&?&?&[=]&?)];[]. right.
eexists _,_,[],[]. split;[reflexivity| ]. split;[easy| ]. unfold last, removelast;cbn. eauto.
+intros [([=]&?)|(t__L&c&t__R1&t__R2&[= <- <- H__nil]&Hfalse&Hc&H'')];[].
destruct t__R1;[ |now inv H__nil]. destruct t__R2;[ |now inv H__nil]. clear H__nil.
cbn in H''|-*. destruct H'' as [-> | [-> _ ]]. 2:now left. now unfold last in Hc;cbn in Hc;congruence.
-eapply Morphisms_Prop.or_iff_morphism. easy.
split. all:intros (t__L&c&t__R1&t__R2&Heq&Hfalse&Hc&H');revert Heq.
+intros [= <- -> ->]. eexists _,_,(_::_),_. split. reflexivity.
cbn. split. now intros ? [-> | ];eauto.
autorewrite with list in |-*;cbn. erewrite last_not_default. split;now eauto. easy.
+intros [= -> -> Heq]. destruct t__R1.
{cbn in *. destruct H' as [ -> | [-> ->]]. all: now cbn in *;congruence. }
revert Heq;intros [= -> ->].
eexists (_::_),_,_,_. split. reflexivity. cbn in *.
split. now eauto. autorewrite with list in H';cbn. erewrite last_not_default. 2:easy. split;now eauto.
Qed.
Lemma MoveToSymbol_Fun_is_rel (sig':finType) (f:sig' -> bool) (g:sig' -> sig') t :
MoveToSymbol_Rel_nice f g t (MoveToSymbol_Fun f g t).
Proof.
now rewrite <- MoveToSymbol_Fun_nice.
Qed.