(* ** 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.
Inductive Entails (sig : Type) (n : nat) (P1 P2 : Assert sig n) :=
EntailsI : (forall tin, P1 tin -> P2 tin) -> Entails P1 P2.
Instance TripleT_Entails_Proper sig n F: Proper (Entails --> le ==> eq ==> pointwise_relation F Entails ==> Basics.impl) (@TripleT sig n F).

Lemma TripleT_eta_pre {sig : finType} {n : nat} {F : Type} (pM : pTM sig F n)
(P : Assert sig n) (Q : F -> Assert sig n) k :
TripleT P k pM Q ->
TripleT (fun tin => P tin) k pM Q.