Instance andp_imp_CCC: forall A {ND : NatDed A}, CCCviaNatDed A andp imp.
Instance sepcon_wand_CCC: forall A {ND : NatDed A} {SL: SepLog A}, CCCviaNatDed A sepcon wand.

(* Specifications: *)
Lemma exp_unit: forall {A} `{NatDed A} (P: unit -> A),
exp P = P tt.
Lemma allp_unit: forall {A} `{NatDed A} (P: unit -> A),
allp P = P tt.
Lemma andp_is_allp {A}{ND: NatDed A}:
forall P Q, andp P Q = allp (fun x : bool => if x then P else Q).
Lemma orp_is_exp {A}{ND: NatDed A}:
forall P Q, orp P Q = exp (fun x : bool => if x then P else Q).
Lemma exp_prop: forall {B} {ND: NatDed B} A P, exp (fun x: A => prop (P x)) = prop (exists x: A, P x).
Lemma modus_ponens {A}{ND: NatDed A}: forall P Q: A, derives (andp P (imp P Q)) Q.
Lemma modus_ponens_wand {A}{ND: NatDed A}{SL: SepLog A}:
forall P Q: A, derives (sepcon P (wand P Q)) Q.
Lemma wand_sepcon_wand: forall {A} {NA: NatDed A} {SA: SepLog A} (P1 P2 Q1 Q2: A),
(P1 -* Q1) * (P2 -* Q2) |-- P1 * P2 -* Q1 * Q2.
Lemma sepcon_FF {A}{ND: NatDed A}{SL: SepLog A} :
forall P: A, sepcon P FF = FF.
Lemma FF_sepcon {A} {NA: NatDed A}{SA: SepLog A}: forall P: A, FF * P = FF.
Hint Rewrite @FF_sepcon @sepcon_FF : norm.
Lemma FF_andp {A}{NA: NatDed A}:  forall P: A, FF && P = FF.
Lemma andp_FF {A}{NA: NatDed A}:  forall P: A, P && FF = FF.
Hint Rewrite @FF_andp @andp_FF : norm.
Lemma FF_orp: forall {A: Type} `{NatDed A} (P: A), FF || P = P.
Lemma orp_FF {A}{NA: NatDed A}:
forall Q, Q || FF = Q.
Lemma orp_TT {A}{NA: NatDed A}:
forall Q, Q || TT = TT.
Lemma TT_orp {A}{NA: NatDed A}:
forall Q, TT || Q = TT.
Lemma allp_forall: forall {A B: Type} `{NatDed A} P Q (x:B), (forall x:B, (P x = Q)) -> (allp P = Q).
Lemma allp_derives:
forall {A: Type}  {NA: NatDed A} (B: Type) (P Q: B -> A),
(forall x:B, P x |-- Q x) -> (allp P |-- allp Q).
Lemma allp_congr:
forall {A: Type}  {NA: NatDed A} (B: Type) (P Q: B -> A),
(forall x:B, P x = Q x) -> (allp P = allp Q).
Lemma allp_uncurry: forall {A} `{NatDed A} (S T: Type) (P: S -> T -> A),
allp (allp P) = allp (fun st => P (fst st) (snd st)).
Lemma allp_depended_uncurry': forall {A} `{NatDed A} {S: Type} {T: S -> Type} (P: forall s: S, T s -> A),
ALL s: S, (ALL t: T s, P s t) = ALL st: sigT T, P (projT1 st) (projT2 st).
Lemma allp_uncurry': forall {A} `{NatDed A} (S T: Type) (P: S -> T -> A),
ALL s: S, (ALL t: T, P s t) = ALL st: prod S T, P (fst st) (snd st).
Lemma allp_curry: forall {A} `{NatDed A} (S T: Type) (P: S * T -> A),
allp P = allp (fun s => allp (fun t => P (s, t))).
Lemma exp_derives {A}{NA: NatDed A}{B}:
forall F G: B -> A, (forall x, F x |-- G x) -> exp F |-- exp G.
Lemma exp_congr:
forall A NA T X Y,
(forall v, X v = Y v) -> @exp A NA T X = @exp A NA T Y.
Lemma exp_uncurry:
forall {T} {ND: NatDed T} A B F, (@exp T ND A (fun a => @exp T ND B (fun b => F a b)))
= @exp T ND (A*B) (fun ab => F (fst ab) (snd ab)).
Lemma exp_trivial {A}{NA: NatDed A}:
forall {T: Type} (any: T) (P: A), exp (fun x:T => P) = P.
Lemma allp_andp: forall {A B: Type} `{NatDed A} (P Q: B -> A), allp (P && Q) = allp P && allp Q.
Lemma distrib_andp_orp: forall {A : Type} {ND : NatDed A} (P Q R : A),
(P && Q) || R = (P || R) && (Q || R).
Lemma prop_derives {A}{ND: NatDed A}:
forall (P Q: Prop), (P -> Q) -> prop P |-- prop Q.
Lemma ND_prop_ext {A}{ND: NatDed A}: forall P Q, (P <-> Q) -> !! P = !! Q.
Lemma prop_True_right {A}{NA: NatDed A}: forall P:A, P |-- !! True.
Lemma derives_refl' {A}{NA: NatDed A}: forall P Q: A, P=Q -> P |-- Q.
Lemma distrib_orp_andp {A}{ND: NatDed A}:
forall (P Q R : A), andp (orp P Q) R = orp (andp P R) (andp Q R).
Lemma exp_andp1 {A}{ND: NatDed A}:  forall B (p: B -> A) q, andp (exp p) q = (exp (fun x => andp (p x) q)).
Lemma exp_sepcon1 {A}{ND: NatDed A} {SL: SepLog A}:
forall T (P: T ->  A) Q, sepcon (exp P) Q = exp (fun x => sepcon (P x) Q).
Lemma distrib_orp_sepcon {A}{ND: NatDed A}{SL: SepLog A}:
forall (P Q R : A), sepcon (P || Q) R = sepcon P R || sepcon Q R.
Lemma distrib_orp_sepcon2 {A}{ND: NatDed A}{SL: SepLog A}:
forall P Q R: A,
R * (P || Q) = R * P || R * Q.
Lemma exp_sepcon2 {A}{NA: NatDed A}{SA: SepLog A}:
forall T (P: A) (Q: T -> A),  P * exp Q = exp (fun x => P * Q x).
Lemma allp_sepcon1 {A}{ND: NatDed A} {SL: SepLog A}:
forall T (P: T ->  A) Q, sepcon (allp P) Q |-- allp (fun x => sepcon (P x) Q).
Lemma allp_sepcon2 {A}{ND: NatDed A} {SL: SepLog A}:
forall T P (Q: T ->  A), sepcon P (allp Q) |-- allp (fun x => sepcon P (Q x)).
Lemma exp_andp2  {A}{NA: NatDed A}:
forall B (p: A) (q: B -> A) , (p && exp q) = exp (fun x => p && q x).
Lemma imp_derives {A} {NA: NatDed A}:
forall P P' Q Q' : A,
P' |-- P ->
Q |-- Q' ->
P --> Q |-- P' --> Q'.
Lemma imp_right2: forall {A} {NA: NatDed A} (P Q : A), P |-- Q --> P.
Lemma  distrib_sepcon_andp {A}{ND: NatDed A}{SL: SepLog A}:
forall P Q R, sepcon P (andp Q R) |-- andp (sepcon P Q) (sepcon P R).
Lemma later_derives {A}{ND: NatDed A}{IA: Indir A}:
forall P Q: A, P |-- Q -> later P |-- later Q.
Lemma later_andp  {A}{ND: NatDed A}{IA: Indir A}:
forall P Q: A, later (P && Q) = later P && later Q.
Lemma later_orp  {A}{ND: NatDed A}{IA: Indir A}:
forall P Q: A, later (P || Q) = later P || later Q.
Lemma later_left2 {T}{ND: NatDed T}{IT: Indir T}:
forall A B C : T, A && B |-- C -> A && |> B |-- |>C.
Lemma andp_dup {A}{ND: NatDed A}: forall P: A, P && P = P.
Lemma andp_TT {A}{NA: NatDed A}: forall (P: A), P && TT = P.
Proof with norm.