From ChargeCore.Logics Require Import ILogic ILInsts ILEmbed.
Set Implicit Arguments.
Unset Strict Implicit.
Set Maximal Implicit Insertion.
Section LaterSect.
Context {A : Type}.
Context `{ILOps: ILogicOps A}.
Class ILLOperators (A : Type) : Type := {
illater : A -> A
}.
Class ILLater {ILLOps: ILLOperators A} : Type := {
illogic :> ILogic A;
spec_lob P : illater P |-- P -> |-- P;
spec_later_weaken P : P |-- illater P;
spec_later_impl P Q : illater (P -->> Q) -|- (illater P) -->> (illater Q);
spec_later_forall {T} (F : T -> A) : illater (Forall x:T, F x) -|- Forall x:T, illater (F x);
spec_later_exists {T} (F : T -> A) : Exists x : T, illater (F x) |-- illater (Exists x : T, F x);
spec_later_exists_inhabited {T} (F : T -> A) : inhabited T -> illater (Exists x : T, F x) |-- Exists x : T, illater (F x)
}.
End LaterSect.
Arguments ILLater _ _ _ : clear implicits.
Arguments ILLater _ {ILLOps ILOps} : rename.
Notation "'|>' a"  := (illater a) (at level 71).
Section ILogicLaterCoreRules.
Context {A} `{IL: ILLater A}.
Global Instance spec_later_entails:
Proper (lentails ==> lentails) illater.
Global Instance spec_later_equiv:
Proper (lequiv ==> lequiv) illater.

(* Specifications: *)
Lemma spec_later_and P P': |>(P //\\ P') -|- |>P //\\ |>P'.
Lemma spec_later_or P P': |>(P \\// P') -|- |>P \\// |>P'.
Lemma spec_later_true : |>ltrue -|- ltrue.
End ILogicLaterCoreRules.