(* ** 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 TripleT_TerminatesIn {sig : finType} {n : nat} {F : Type} (P : Assert sig n) (k : nat) (pM : pTM sig F n) (Q : F -> Assert sig n):
TripleT P k pM Q ->
projT1 pM ↓ (fun tin k' => P tin /\ k <= k').