Ltac get_global_function'' _f :=
eapply (semax_fun_id'' _f); try reflexivity.
(* revised start_function that mostly works for dependent specs *)
Ltac start_dep_function :=
match goal with |- semax_body ?V ?G ?F ?spec =>
let s := fresh "spec" in
pose (s:=spec); hnf in s;
match goal with
| s :=  (DECLARE _ WITH _ : globals
PRE  [] main_pre _ nil _
POST [ tint ] main_post _ nil _) |- _ => idtac
| s := ?spec' |- _ => check_canonical_funspec spec'
end;
change (semax_body V G F s); subst s
end;
let DependedTypeList := fresh "DependedTypeList" in
match goal with |- semax_body _ _ _ (pair _ (mk_funspec _ _ _ ?Pre _ _ _)) =>
match Pre with
| (fun x => match _ with (a,b) => _ end) => intros Espec DependedTypeList [a b]
| (fun i => _) => intros Espec DependedTypeList i
end;
simpl fn_body; simpl fn_params; simpl fn_return
end;
simpl functors.MixVariantFunctor._functor in *;
simpl rmaps.dependent_type_functor_rec;
repeat match goal with |- @semax _ _ _ (match ?p with (a,b) => _ end * _) _ _ =>
destruct p as [a b]
end;
simplify_func_tycontext;
repeat match goal with
| |- context [Sloop (Ssequence (Sifthenelse ?e Sskip Sbreak) ?s) Sskip] =>
fold (Swhile e s)
| |- context [Ssequence ?s1 (Sloop (Ssequence (Sifthenelse ?e Sskip Sbreak) ?s2) ?s3) ] =>
match s3 with
| Sset ?i _ => match s1 with Sset ?i' _ => unify i i' | Sskip => idtac end
end;
fold (Sfor s1 e s2 s3)
end;
try expand_main_pre;
process_stackframe_of;
repeat change_mapsto_gvar_to_data_at;  (* should really restrict this to only in main,
but it needs to come after process_stackframe_of *)
repeat rewrite <- data_at__offset_zero;
try apply start_function_aux1;
repeat (apply semax_extract_PROP;
match goal with
| |- _ ?sh -> _ =>
match type of sh with
| share => intros ?SH
| Share.t => intros ?SH
| _ => intro
end
| |- _ => intro
end);
first [ eapply eliminate_extra_return'; [ reflexivity | reflexivity | ]
| eapply eliminate_extra_return; [ reflexivity | reflexivity | ]
| idtac];
abbreviate_semax.
(* Notations for dependent funspecs *)
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2) =>
match x with (x1,x2) => P%assert end)
(fun (ts: list Type) (x: t1*t2) =>
match x with (x1,x2) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3) =>
match x with (x1,x2,x3) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3) =>
match x with (x1,x2,x3) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4) =>
match x with (x1,x2,x3,x4) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4) =>
match x with (x1,x2,x3,x4) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5) =>
match x with (x1,x2,x3,x4,x5) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5) =>
match x with (x1,x2,x3,x4,x5) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
x5 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 , x6 : t6 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6) =>
match x with (x1,x2,x3,x4,x5,x6) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6) =>
match x with (x1,x2,x3,x4,x5,x6) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
x5 at level 0, x6 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 , x6 : t6 , x7 : t7 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7) =>
match x with (x1,x2,x3,x4,x5,x6,x7) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7) =>
match x with (x1,x2,x3,x4,x5,x6,x7) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
x5 at level 0, x6 at level 0, x7 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 , x6 : t6 , x7 : t7 , x8 : t8 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
x5 at level 0, x6 at level 0, x7 at level 0, x8 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 , x6 : t6 , x7 : t7 , x8 : t8 , x9 : t9 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
x5 at level 0, x6 at level 0, x7 at level 0, x8 at level 0, x9 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 , x6 : t6 , x7 : t7 , x8 : t8 , x9 : t9 , x10 : t10 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
x5 at level 0, x6 at level 0, x7 at level 0, x8 at level 0, x9 at level 0, x10 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 , x6 : t6 , x7 : t7 , x8 : t8 , x9 : t9 , x10 : t10 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
x5 at level 0, x6 at level 0, x7 at level 0, x8 at level 0, x9 at level 0, x10 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 , x6 : t6 , x7 : t7 , x8 : t8 , x9 : t9 , x10 : t10 , x11 : t11 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10*t11) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10*t11) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
x5 at level 0, x6 at level 0, x7 at level 0, x8 at level 0, x9 at level 0,
x10 at level 0, x11 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 , x6 : t6 , x7 : t7 , x8 : t8 , x9 : t9 , x10 : t10 , x11 : t11 , x12 : t12 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10*t11*t12) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10*t11*t12) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
x5 at level 0, x6 at level 0, x7 at level 0, x8 at level 0, x9 at level 0,
x10 at level 0, x11 at level 0, x12 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 , x6 : t6 , x7 : t7 , x8 : t8 , x9 : t9 , x10 : t10 , x11 : t11 , x12 : t12 , x13 : t13 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10*t11*t12*t13) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10*t11*t12*t13) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
x5 at level 0, x6 at level 0, x7 at level 0, x8 at level 0, x9 at level 0,
x10 at level 0, x11 at level 0, x12 at level 0, x13 at level 0,
P at level 100, Q at level 100).
Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 , x6 : t6 , x7 : t7 , x8 : t8 , x9 : t9 , x10 : t10 , x11 : t11 , x12 : t12 , x13 : t13 , x14 : t14 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10*t11*t12*t13*t14) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5*t6*t7*t8*t9*t10*t11*t12*t13*t14) =>
match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14) => Q%assert end) _ _)
(at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
x5 at level 0, x6 at level 0, x7 at level 0, x8 at level 0, x9 at level 0,
x10 at level 0, x11 at level 0, x12 at level 0, x13 at level 0, x14 at level 0,
P at level 100, Q at level 100).
(* automation for dependent funspecs *)
Definition call_setup2'
(cs: compspecs) Qtemp Qvar GV a Delta P Q R R'
fs argsig retty cc ts (A: rmaps.TypeTree)  Pre Post NEPre NEPost
(bl: list expr) (vl : list val)
(Qactuals : PTree.t _)
(witness: functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts A) mpred)
(Frame: list mpred)
(Ppre: list Prop) (Qpre : list localdef) (Rpre: list mpred)
(Qpre_temp : PTree.t _) GV' :=
call_setup1 cs Qtemp Qvar GV a Delta P Q R R' fs argsig retty cc A Pre Post NEPre NEPost bl vl Qactuals /\
Pre ts witness = PROPx Ppre (LOCALx Qpre (SEPx Rpre)) /\
local2ptree Qpre = (Qpre_temp, PTree.empty _, nil, GV') /\
ENTAIL Delta, PROPx P (LOCALx Q (SEPx R))
|-- !! Forall (check_one_temp_spec Qactuals) (PTree.elements Qpre_temp) /\
check_gvars_spec GV GV' /\
fold_right_sepcon R |-- fold_right_sepcon Rpre * fold_right_sepcon Frame.

(* Specifications: *)
Lemma call_setup2'_i:
forall  (cs: compspecs) Qtemp Qvar GV a Delta P Q R R'
fs argsig retty cc ts (A: rmaps.TypeTree) Pre Post NEPre NEPost
(bl: list expr) (vl : list val)
(Qactuals : PTree.t _)
(SETUP1: call_setup1 cs Qtemp Qvar GV a Delta P Q R R' fs argsig retty cc A Pre Post NEPre NEPost bl vl Qactuals)
(witness': functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts A) mpred)
(Frame: list mpred)
(Ppre: list Prop) (Qpre : list localdef) (Rpre: list mpred)
(Qpre_temp : PTree.t _) GV',
Pre ts witness' = PROPx Ppre (LOCALx Qpre (SEPx Rpre)) ->
local2ptree Qpre = (Qpre_temp, PTree.empty _, nil, GV') ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx R))
|-- !! Forall (check_one_temp_spec Qactuals) (PTree.elements Qpre_temp) ->
check_gvars_spec GV GV' ->
fold_right_sepcon R |-- fold_right_sepcon Rpre * fold_right_sepcon Frame ->
call_setup2' cs Qtemp Qvar GV a Delta P Q R R' fs argsig retty cc ts A Pre Post NEPre NEPost bl vl Qactuals
witness' Frame Ppre Qpre Rpre Qpre_temp GV'.