Section Translate.
Variable (sig : finType).
Variable (sigX X : Type) (cX : codable sigX X).
Variable (I1 I2 : Retract sigX sig).
Definition translate : sig^+ -> sig^+ :=
fun t => match t with
| inl _ => t
| inr x => match Retr_g (Retract := I1) x with
| Some y => inr (Retr_f (Retract := I2) y)
| None => inl UNKNOWN
end
end.
Definition Translate' := MoveToSymbol (@isStop sig) translate.
Definition Translate'_Rel : pRel sig^+ unit 1 :=
ignoreParam (
fun tin tout =>
forall (x : X) (s : nat),
tin[@Fin0] ≃(I1; s) x ->
tout[@Fin0] ≂(I2; s) x
).
Definition Translate'_steps {sigX X : Type} {cX : codable sigX X} (x:X) := 8 + 4 *size x.
Definition Translate := Translate';; MoveLeft _.
Definition Translate_Rel : pRel sig^+ unit 1 :=
ignoreParam (
fun tin tout =>
forall (x : X) (s : nat),
tin[@Fin0] ≃(I1; s) x ->
tout[@Fin0] ≃(I2; s) x
).
Definition Translate_steps {sigX:Type} {cX : codable sigX X} (x : X) := 17 + 8 *size x.
Definition Translate_T : tRel sig^+ 1 :=
fun tin k => exists x, tin[@Fin0] ≃(I1) x /\ Translate_steps x <= k.
End Translate.
Arguments Translate_steps {X sigX cX}.
(* no size *)
(* The exact retracts can be instantiated later, during the relation-inclusion proof *)
Ltac smpl_TM_Copy :=
once lazymatch goal with
| [ |- Translate _ _ ⊨ _] => notypeclasses refine (@Translate_Realise _  _ _ _ _ _);shelve
| [ |- projT1 (Translate _ _) ↓ _] => notypeclasses refine (@Translate_Terminates _ _ _ _ _ _);shelve
| [ |- Reset _ ⊨ _] => notypeclasses refine (@Reset_Realise _ _ _ _ _);shelve
| [ |- projT1 (Reset _) ↓ _] => notypeclasses refine (@Reset_Terminates _ _ _ _ _);shelve
| [ |- CopyValue _ ⊨ _] => notypeclasses refine (@CopyValue_Realise _ _ _ _ _);shelve
| [ |- projT1 (CopyValue _) ↓ _] => notypeclasses refine (@CopyValue_Terminates _ _ _ _ _);shelve
| [ |- MoveValue _ ⊨ _] => notypeclasses refine (@MoveValue_Realise _ _ _ _ _ _ _ _ _);shelve
| [ |- projT1 (MoveValue _) ↓ _] => notypeclasses refine (@MoveValue_Terminates _ _ _ _ _ _ _ _ _);shelve
end.
Smpl Add smpl_TM_Copy : TM_Correct.
(* We give all rule variants here, because automation is forbidden for these machines *)
(* TODO: [CopyValue_size] should be renamed, and this function should be moved to [Code.v] *)
Definition CopyValue_sizefun {sigX X : Type} {cX : codable sigX X} (x : X) : Vector.t (nat->nat) 2 := [|id; CopyValue_size x|].

Lemma CopyValue_SpecT (sig : finType) (sigX X : Type) (cX : codable sigX X) (I : Retract sigX sig) (x : X) :
TripleT (≃≃([],[|Contains _ x; Void|])) (CopyValue_steps x) (CopyValue sig) (fun _ => ≃≃([],[|Contains _ x; Contains _ x|])).