(* QuickChick Prelude *)
Set Warnings "-extraction-opaque-accessed,-extraction".
Set Warnings "-notation-overridden,-parsing".
Set Bullet Behavior "Strict Subproofs".
(* End prelude *)
Definition Assertion := state -> Prop.
Definition assert_implies (P Q : Assertion) : Prop :=
forall st, P st -> Q st.
Notation "P ->> Q" := (assert_implies P Q)
(at level 80) : hoare_spec_scope.
Open Scope hoare_spec_scope.
Notation "P <<->> Q" :=
(P ->> Q /\ Q ->> P) (at level 80) : hoare_spec_scope.
Definition hoare_triple
(P:Assertion) (c:com) (Q:Assertion) : Prop :=
forall st st',
c / st \\ st'  ->
P st  ->
Q st'.
Notation "{{ P }}  c  {{ Q }}" :=
(hoare_triple P c Q) (at level 90, c at next level)
: hoare_spec_scope.
Admitted. (* Higher Order *)
Admitted. (* Higher Order *)
Definition assn_sub X a P : Assertion :=
fun (st : state) =>
P (t_update st X (aeval st a)).
Notation "P [ X |-> a ]" := (assn_sub X a P) (at level 10).
Admitted. (* Higher Order *)

Theorem hoare_asgn_fwd :
(forall {X Y: Type} {f g : X -> Y},
(forall (x: X), f x = g x) ->  f = g) ->
forall m a P,
{{fun st => P st /\ t_lookup st X = m}}
X ::= a
{{fun st => P (t_update st X m)
/\ t_lookup st X = aeval (t_update st X m) a }}.