(* ** Abstract specification using Hoare triples *)
From Undecidability.TM Require Import TM Util.TM_facts.
(* Abstract Assertions over Tapes *)
Definition Assert (sig : Type) (n : nat) : Type := tapes sig n -> Prop.
(* [{P} pM {fun c => Q c}] means that whenever [pM] starts with tapes that satisfy [P] and terminates in label [c] and tapes [tp'] that satisfy [Q c]. *)
Definition Triple_Rel {sig : finType} {n : nat} {F : Type} (P : Assert sig n) (Q : F -> Assert sig n) : pRel sig F n :=
fun tin '(yout, tout) => P tin -> Q yout tout.
Inductive Triple {sig : finType} {n : nat} {F : Type} P (pM : pTM sig F n) Q :=
TripleI : pM ⊨ Triple_Rel P Q -> Triple P pM Q.

Lemma Realise_TripleT {sig : finType} {n : nat} {F : Type} (P : Assert sig n) (k : nat) (pM : pTM sig F n) (Q : F -> Assert sig n) (R : pRel sig F n) (T : tRel sig n) :
pM ⊨ R ->
projT1 pM ↓ T ->
(forall tin yout tout, R tin (yout, tout) -> P tin -> Q yout tout) ->
(forall tin k', P tin -> k <= k' -> T tin k') ->
TripleT P k pM Q.