(* ** 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.

(* A convienient lemma to convert constant-time realisation to a Hoare triple. Note that the reverse doesn't hold. *)
Lemma RealiseIn_TripleT {sig : finType} {n : nat} {F : Type} (P : Assert sig n) k (pM : pTM sig F n) (Q : F -> Assert sig n) (R : pRel sig F n) :
pM ⊨c(k) R ->
(forall tin yout tout, R tin (yout, tout) -> P tin -> Q yout tout) ->
TripleT P k pM Q.