Definition superprecise {A}  {JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A} (P: pred A) :=
forall w1 w2, P w1 -> P w2 -> comparable w1 w2 -> w1=w2.

(* Specifications: *)
Lemma modus_ewand {A}  {JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A} :  forall P Q, superprecise P -> P * (ewand P Q) |-- Q.
Lemma exists_expand_sepcon {A}  {JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A}:
forall B (p: B -> pred A) q, (exp p * q)%pred = (exp (fun x => p x * q))%pred.
Lemma exists_expand_sepcon' {A}  {JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A}:
forall B p (q: B -> pred A), (p * exp q)%pred = (exp (fun x => p * q x))%pred.
Lemma exists_expand_and {A}  {JA: Join A}:
forall B (p: B -> pred A) q, (exp p && q)%pred = (exp (fun x => p x && q))%pred.
Lemma exists_expand_and' {A} {JA: Join A}:
forall B p (q: B -> pred A), (p && exp q)%pred = (exp (fun x => p && q x))%pred.
Lemma allp_derives_right {A} : forall B p (q: B -> pred A),
((p |-- allp q) <-> (forall x, p |-- q x)).
Lemma wand_exists {A} {JA: Join A}{PA: Perm_alg A}:
forall B P Q,  (EX x: B, P -* Q x) |-- (P -* EX x : B, Q x).
Lemma modus_wand {A} {JA: Join A}{PA: Perm_alg A}:
forall P Q,  P * (P -* Q) |-- Q.
Lemma distrib_sepcon_andp {A} {JA: Join A}{PA: Perm_alg A}:
forall P Q R, P * (Q && R) |-- (P * Q) && (P * R).
Lemma andp_r {A: Type} : forall (P Q R: pred A), P |-- Q -> P |-- R -> P |-- Q && R.
Definition list_sepcon {A} {JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A} : list (pred A) -> pred A := fold_right sepcon emp.
Lemma sepcon_andp_prop {A} {JA: Join A}{PA: Perm_alg A}: forall P Q R, P * (!!Q && R) = !!Q && (P * R).
Lemma exactly_i {A} : forall x: A, exactly x x.
Hint Resolve @exactly_i.
Lemma superprecise_exactly {A} {JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A}: forall x, superprecise (exactly x).
Hint Resolve @superprecise_exactly.
Lemma find_overlap {A} {JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A}:
Cross_alg A ->
forall S P Q R, (S * P) && (Q * R) |--
EX SQ:_, EX SR:_, EX PQ:_, EX PR:_,
(((SQ* SR) && S)*((PQ* PR) && P)) &&
(((SQ* PQ) && Q)*((SR* PR) && R)) &&
!! (superprecise SQ /\ superprecise SR /\ superprecise PQ /\ superprecise PR).
Lemma modus_ponens {A} : forall (X P Q:pred A),
X |-- P ->
X |-- (P --> Q) ->
X |-- Q.
Lemma and_intro {A}  : forall (X P Q:pred A),
X |-- P ->
X |-- Q ->
X |-- P && Q.
Lemma and1 {A}  : forall (X P Q:pred A),
X |-- P && Q --> P.
Lemma and2 {A}  : forall (X P Q:pred A),
X |-- P && Q --> Q.
Lemma and3 {A}  : forall (X P Q R:pred A),
X |-- (P --> Q) --> (P --> R) --> (P --> Q && R).
Lemma or1 {A}  : forall (X P Q:pred A),
X |-- P --> P || Q.
Lemma or2 {A}  : forall (X P Q:pred A),
X |-- Q --> P || Q.
Lemma or3 {A}  : forall (X P Q R:pred A),
X |-- (P --> R) --> (Q --> R) --> (P || Q --> R).
Lemma TTrule {A}  : forall X (P: pred A),
X |-- P --> TT.
Lemma FFrule {A}  : forall X (P: pred A),
X |-- FF --> P.
Lemma distribution {A}  : forall (X P Q R:pred A),
X |-- P && (Q || R) --> (P && Q) || (P && R).
Lemma wand_sepcon_adjoint {A} {JA: Join A}{PA: Perm_alg A} : forall (P Q R:pred A),
((P * Q) |-- R) = (P |-- (Q -* R)).
Lemma ewand_sepcon {A} {JA: Join A}{PA: Perm_alg A}: forall P Q R,
(ewand (P * Q) R = ewand P (ewand Q R))%pred.
Lemma andp_right {A}  : forall (X P Q:pred A),
X |-- P ->
X |-- Q ->
X |-- P && Q.
Lemma andp_left1{A}: forall P Q R: pred A,  P |-- R -> P && Q |-- R.
Lemma andp_left2{A}: forall P Q R: pred A,  Q |-- R -> P && Q |-- R.
Lemma orp_left{A}: forall P Q R: pred A,  P |-- R -> Q |-- R -> P || Q |-- R.
Lemma orp_right1{A}: forall P Q R: pred A,  P |-- Q -> P |-- Q || R.
Lemma orp_right2{A}: forall P Q R: pred A,  P |-- R -> P |-- Q || R.
Lemma exp_right:
forall {B A: Type}(x:B) p (q: B -> pred A),
p |-- q x ->
p |-- exp q.
Lemma exp_left:
forall {B A: Type}(p: B -> pred A) q,
(forall x, p x |-- q) ->
exp p |-- q.
Lemma allp_right {B A: Type}:
forall (P: pred A) (Q: B -> pred A),
(forall v, P |-- Q v) ->
P |-- allp Q.
Lemma allp_left {B}{A}:
forall (P: B -> pred A) x Q, P x |-- Q -> allp P |-- Q.
Lemma imp_andp_adjoint {A}  : forall (P Q R:pred A),
(P && Q) |-- R <-> P |-- (Q --> R).
Lemma exp_andp1 {A} :
forall B (p: B -> pred A) q, (exp p && q)%pred = (exp (fun x => p x && q))%pred.
Lemma exp_sepcon1 {A}  {JA: Join A}{PA: Perm_alg A}:
forall T (P: T ->  pred A) Q,  (exp P * Q = exp (fun x => P x * Q))%pred.