Module DSolver.
Local Existing Instances Deep.L Deep.minL Deep.pL Deep.GP Deep.minAX Deep.ipG.
Instance Adj : Adjointness _ _ andp impp.
Instance Comm : Commutativity _ _ andp.
Instance Mono : Monotonicity _ _ andp.
Instance Assoc : Associativity _ _ andp.
Instance LUnit : LeftUnit _ _ truep andp.
Instance RUnit : RightUnit _ _ truep andp.
Fixpoint flatten_imp (e : expr) : list expr * expr :=
match e with
| Deep.impp p q => let (cxt, fq) := flatten_imp q in (p :: cxt, fq)
| _ => (nil, e)
end.
Definition flatten_imp_inv (p : list Deep.expr * Deep.expr) :=
let (ctx, r) := p in multi_imp ctx r.
Fixpoint flatten_and (e : expr) : list expr :=
match e with
| Deep.andp p q => (flatten_and p ++ flatten_and q)
| s => s :: nil
end.
Definition flatten_and_inv (es : list expr) := List.fold_left andp es truep.
Definition flatten (e : expr) : list expr * list expr :=
let (ctx, r) := flatten_imp e in
(List.flat_map flatten_and ctx, flatten_and r).
Definition AllInContext (es1 es2 : list expr) : Prop :=
Forall (fun e => In e es1) es2.

Lemma flatten_inv_All :
forall es r, AllInContext (List.flat_map flatten_and es) (flatten_and r) ->
provable (flatten_imp_inv (es, r)).