Section Univ.
(* Actually, we build a Universal Turing Machine for each alphabet [sigM] *)
Variable (sigM : finType).
Notation sigGraph := (sigList (sigPair (sigPair (option sigM) sigState) (sigPair (option sigM * move) sigState))).
(* We need to import all the Variables and Instances from the other file *)
(* The alphabet of [Univ] *)
Variable (sig : finType).
Variable (retr_sigGraph_sig : Retract sigGraph sig).
Variable (retr_sigTape_sig : Retract sigM sig).
(* Encoding of the current state number *)
Local Existing Instance LowLevel.retr_sigCurrentStateNumber_sigGraph.
Local Existing Instance LowLevel.retr_sigCurrentStateNumber_sig.
(* Encoding of the current state (= halt bit + number) *)
Local Existing Instance LowLevel.retr_sigCurrentState_sigGraph.
Local Existing Instance LowLevel.retr_sigCurrentState_sig.
(* Encoding of final bit of the current state *)
Local Existing Instance LowLevel.retr_sigCurrentStateFinal_sigGraph.
Local Existing Instance LowLevel.retr_sigCurrentStateFinal_sig.
(* Encoding of the next state *)
Local Existing Instance LowLevel.retr_sigNextState_sigGraph.
Local Existing Instance LowLevel.retr_sigNextState_sig.
(* Encoding the current symbol *)
Local Existing Instance LowLevel.retr_sigCurrentSymbol_sigGraph.
Local Existing Instance LowLevel.retr_sigCurrentSymbol_sig.
(* Encoding of actions *)
Local Existing Instance LowLevel.retr_act_sigGraph.
Local Existing Instance LowLevel.retr_act_sig.
(* Encoding of the keys for [Lookup] ([option sig * Q]) *)
Local Existing Instance LowLevel.retr_key_sigGraph.
Local Existing Instance LowLevel.retr_key_sig.
(* Encoding of the value for [Lookup] ([option sig * Q]) *)
Local Existing Instance LowLevel.retr_value_sigGraph.
Local Existing Instance LowLevel.retr_value_sig.
Local Existing Instance LowLevel.Encode_graph.
Local Existing Instance LowLevel.Encode_optSigM.
Local Existing Instance LowLevel.Encode_action.
(* We have to define a [RegSpec] for [containsWorkingTape] *)
Definition ContainsWorkingTape (tp : tape sigM) : RegSpec sig :=
Custom (fun t => containsWorkingTape _ t tp).
(* The first high-level rule *)
Definition DoAction'_size (a : option sigM * move) : Vector.t (nat->nat) 2 :=
[| (*0*) id; (*1*) DoAction_size a |]. (* The entry for (*0*) is irrelevant, since it is a [Custom]. *)
(* The low-level machines are still verified using Realisation. The Hoare-framework doesn't make sense for low-level machines. Thus, we just convert the relations to Hare triples. *)
Notation "'ContainsState' q" :=
(Contains (LowLevel.retr_sigCurrentState_sig _) (halt q, index q)) (at level 0).
Notation "'ContainsState_size' q s" :=
(Contains_size (LowLevel.retr_sigCurrentState_sig _) (halt q, index q) s) (at level 0).
Definition IsFinal_size' : Vector.t (nat->nat) 2 :=
[| (*0*) id; IsFinal_size |].
Definition ReadCurrent'_size : Vector.t (nat->nat) 2 :=
[| (*0*) id; ReadCurrent_size |].

Lemma ReadCurrent'_SpecT_space (tp : tape sigM) ss :
TripleT (≃≃([],withSpace ([|ContainsWorkingTape tp; Void|]) ss))
(ReadCurrent'_steps) (ReadCurrent' _ _)
(fun _ => ≃≃([],withSpace ([|ContainsWorkingTape tp; Contains (LowLevel.retr_sigCurrentSymbol_sig _) (current tp)|])
(appSize ReadCurrent'_size ss))).