Local Open Scope logic.
Definition NDfunspec_sub (f1 f2 : funspec) :=
let Delta := (funsig_tycontext (funsig_of_funspec f1)) in
match f1 with
| mk_funspec fsig1 cc1 (rmaps.ConstType A1) P1 Q1 _ _ =>
match f2 with
| mk_funspec fsig2 cc2 (rmaps.ConstType A2) P2 Q2 _ _ =>
fsig1 = fsig2 /\ cc1 = cc2 /\  forall x2,
ENTAIL Delta, P2 nil x2 |-- EX x1:_, EX F:mpred,
((`F * P1 nil x1) &&
(!! (ENTAIL (ret0_tycon Delta), `F * Q1 nil x1
|-- Q2 nil x2)))
| _ => False end
| _ => False end.
Definition is_NDfunspec (fs: funspec) :=
match fs with
| mk_funspec _ _ (rmaps.ConstType A) P Q _ _ =>
(forall ts, P ts = P nil /\ Q ts = Q nil)
| _ => False
end.
Inductive empty_type : Type := .
Definition withtype_of_NDfunspec fs := match fs with
mk_funspec _ _ (rmaps.ConstType A) _ _ _ _ => A | _ => empty_type end.
Definition withtype_of_funspec fs := match fs with
mk_funspec _ _ A _ _ _ _ => A end.

Lemma NDfunspec_sub_trans:
forall fsig1 cc1 A1 P1 Q1 fsig2 cc2 A2 P2 Q2 fsig3 cc3 A3 P3 Q3,
NDfunspec_sub (NDmk_funspec fsig1 cc1 A1 P1 Q1) (NDmk_funspec fsig2 cc2 A2 P2 Q2) ->
NDfunspec_sub (NDmk_funspec fsig2 cc2 A2 P2 Q2) (NDmk_funspec fsig3 cc3 A3 P3 Q3) ->
NDfunspec_sub (NDmk_funspec fsig1 cc1 A1 P1 Q1) (NDmk_funspec fsig3 cc3 A3 P3 Q3).