(* * Constructors and Deconstructors for Comens *)
From Undecidability.TM.L Require Import Alphabets.
Definition CaseCom : pTM sigCom^+ (option ACom) 1 :=
If (CaseSum _ _)
(Return Nop None)
(Relabel (ChangeAlphabet (CaseFin (FinType(EqType(ACom))) ) _) Some).
Definition CaseCom_size (t : Tok) : nat -> nat :=
match t with
| varT n => S
| _ => S >> S >> S
end.
Definition CaseCom_Rel : pRel sigCom^+ (FinType (EqType (option ACom))) 1 :=
fun tin '(yout, tout) =>
forall (t : Tok) (s : nat),
tin[@Fin0] ≃(;s) t ->
match yout with
| Some c =>
isVoid_size tout[@Fin0] (CaseCom_size t s) /\ ACom2Com c = t
| None => exists n, t = varT n /\ tout[@Fin0] ≃(;CaseCom_size t s) n
end.
Definition CaseCom_steps := 11.
(* Constructors *)
(* Use [WriteValue] for [appT], [lamT], and [retT] *)
Definition Constr_ACom (t : ACom) : pTM sigCom^+ unit 1 := WriteValue (ACom2Com t).
Definition Constr_ACom_Rel (t : ACom) : pRel sigCom^+ unit 1 :=
Mk_R_p (ignoreParam (fun tin tout => isVoid tin -> tout ≃ ACom2Com t)).
Definition Constr_ACom_steps := 7.
Definition Constr_varT : pTM sigCom^+ unit 1 := Constr_inl _ _.
Definition Constr_varT_Rel : pRel sigCom^+ (FinType (EqType unit)) 1 :=
Mk_R_p (ignoreParam (fun tin tout => forall (x : nat) (s : nat), tin ≃(;s) x -> tout ≃(;pred s) varT x)).
Definition Constr_varT_steps := 3.
Arguments CaseCom : simpl never.
Arguments Constr_ACom : simpl never.
Arguments Constr_varT : simpl never.

Lemma CaseCom_SpecT_size (t : Tok) (ss : Vector.t nat 1) :
TripleT
≃≃([], withSpace  [|Contains _ t |] ss)
CaseCom_steps
CaseCom
(fun yout => ≃≃([match yout with Some c => t = ACom2Com c | None => exists n, t = varT n end]
,withSpace ([|match Com_to_sum t with inr _ => Void | inl n => Contains _ n end|]) (appSize ([|CaseCom_size t|]) ss))).