intros.
eapply semax_seq'; eauto.
Qed.
Definition skip_lemma : my_lemma.
reify_lemma reify_vst
@semax_skip.
Defined.
Definition seq_lemma (s1 s2: statement)  : my_lemma.
reify_lemma reify_vst (semax_seq_reif s1 s2).
Defined.
Definition replace_set (e : expr typ func) : expr typ func :=
match e with
| App (App (App (App (App (Inj (inr (Smx fsemax))) es)
Delta) pre) s) post =>
let newpre :=
match pre with
|  App (App (App (Inj (inr (Smx fassertD))) P)
(App (App (Inj (inr (Smx flocalD)))
T1) T2)) R =>
let newT1 := match T1 with
| App (App
(Inj (inr (Data (fset tyval n))))
val) T1' =>
get_set_reif.set_reif n val T1' tyval
| _ => T1
end in
App (App (App (Inj (inr (Smx fassertD))) P)
(App (App (Inj (inr (Smx flocalD)))
newT1) T2)) R
| _ => pre
end in
App (App (App (App (App (Inj (inr (Smx fsemax))) es)
Delta) newpre) s) post
| _ => e
end.
Definition SIMPL_SET : rtac typ (ExprCore.expr typ func) :=
SIMPLIFY (fun _ _ _ _ => replace_set).
Definition update_tycon_tac (l : list (option (expr typ func)))
(e : expr typ func) (args : list (expr typ func))
: expr typ func :=
match e with
| (Inj (inr (Smx (fupdate_tycon)))) =>
match args with
| [App (Inj (inr (Smx (ftycontext t v r gt)))) gs; (Inj (inr (Smx (fstatement s))))] =>
App (Inj (inr (Smx (ftycontext (update_temp t s) v r gt)))) gs
| _ =>  AppN.apps e args
end
| _ => AppN.apps e args
end.
Definition SIMPL_DELTA : rtac typ (ExprCore.expr typ func) :=
SIMPLIFY (fun _ _ _ _=>beta_all update_tycon_tac).
Definition INTROS := (REPEAT 10 (INTRO typ func)).
Definition APPLY_SKIP :=  (APPLY typ func  skip_lemma).
Definition run_tac (t: rtac typ (ExprCore.expr typ func)) e :=
t nil nil 0%nat 0%nat (CTop nil nil) (ctx_empty (expr := expr typ func)) e.
Definition run_tac_intros e :=
run_tac (THEN INTROS e).
Definition APPLY_SEQ' s1 s2 := (EAPPLY typ func (seq_lemma s1 s2)).
Definition APPLY_SEQ s1 s2 := THEN (APPLY_SEQ' s1 s2) (SIMPL_DELTA).
(* Definition APPLY_SET' id e t v r gt:= EAPPLY typ func  (set_lemma id e t v r gt). *)
Definition FORWARD_SET Delta Pre s :=
let _HLIP :=
match compute_hlip_arg (Delta, Pre, s) with
| (temp, var, ret, gt, s, R) => HLIP tbl temp var ret gt R s
end in
let _APPLY_SET :=
match compute_set_arg (Delta, Pre, s) with
| Some (temp, var, ret, gt, i, e0, ty) =>
THEN (EAPPLY typ func (set_lemma temp var ret gt i e0 ty))
(TRY (FIRST [REFLEXIVITY_OP_CTYPE tbl;
REFLEXIVITY_MSUBST tbl;
REFLEXIVITY_BOOL tbl;
AFTER_SET_LOAD tbl;
REFLEXIVITY tbl]))
| _ => FAIL
end in
THEN _HLIP _APPLY_SET.
Definition FORWARD_LOAD Struct_env Delta Pre s :=
let _HLIP :=
match compute_hlip_arg (Delta, Pre, s) with
| (temp, var, ret, gt, s, R) => HLIP tbl temp var ret gt R s
end in
let _APPLY_LOAD :=
match compute_load_arg (Delta, Pre, s) with
| Some (t, v, r, gt, i, ty, t_root, e0, e1, efs, tts, lr, n) =>
(THEN (EAPPLY typ func (load_lemma t v r gt i ty t_root e0 e1 efs tts Struct_env lr n))
(THEN (TRY (FIRST [REFLEXIVITY_OP_CTYPE tbl;
REFLEXIVITY_BOOL tbl;
REFLEXIVITY_CEXPR tbl;
AFTER_SET_LOAD tbl;
REFLEXIVITY tbl;
REFLEXIVITY_MSUBST tbl;
REFLEXIVITY_MSUBST_EFIELD tbl;
REFLEXIVITY_NTH_ERROR tbl]))
(TRY (THEN INTROS
(THEN (EAPPLY typ func reify_prop_right)
(REFLEXIVITY tbl))))))
| _ => FAIL
end in
THEN _HLIP _APPLY_LOAD.
Definition FORWARD_STORE Struct_env Delta Pre s :=
let _HLIP :=
match compute_hlip_arg (Delta, Pre, s) with
| (temp, var, ret, gt, s, R) => HLIP tbl temp var ret gt R s
end in
let _APPLY_STORE :=
match compute_store_arg (Delta, Pre, s) with
| Some (t, v, r, gt, ty, t_root, e0, e1, e2, efs, tts, lr, n) =>
(THEN (EAPPLY typ func (store_lemma t v r gt ty t_root e0 e1 e2 efs tts Struct_env lr n))
(THEN (TRY (FIRST [REFLEXIVITY_CTYPE tbl;
REFLEXIVITY_BOOL tbl;
REFLEXIVITY_CEXPR tbl;
AFTER_STORE tbl;
REFLEXIVITY tbl;
FIRST [APPLY typ func writable_Tsh_lemma; APPLY typ func writable_Ews_lemma];
REFLEXIVITY_MSUBST tbl;
REFLEXIVITY_MSUBST_EFIELD tbl;
REFLEXIVITY_NTH_ERROR tbl]))
(TRY (THEN INTROS
(THEN (EAPPLY typ func reify_prop_right)
(REFLEXIVITY tbl))))))
| _ => FAIL
end in
THEN _HLIP _APPLY_STORE.
Definition SYMEXE_STEP Struct_env
: rtac typ (expr typ func)  :=
THEN' (INSTANTIATE typ func)
(Then.THEN (AT_GOAL
(fun c s e =>
match (get_arguments e) with
| (Some Delta, Some Pre, Some s) =>
match compute_forward_rule s with
| Some ForwardSkip => APPLY_SKIP
| Some (ForwardSeq s1 s2) => APPLY_SEQ s1 s2
| Some ForwardSet => FORWARD_SET Delta Pre s
| Some ForwardLoad => FORWARD_LOAD Struct_env Delta Pre s
| Some ForwardStore => FORWARD_STORE Struct_env Delta Pre s
| _ => FAIL
end
| _ => FAIL
end)) (@RTac.Minify.MINIFY typ (expr typ func) _)).
Existing Instance func_defs.Expr_ok_fs.
Definition SYMEXE_TAC_n :=
Then.THEN (
THEN
(THEN INTROS
(THEN (EAPPLY typ func reify_semax_post')
(TRY (AT_GOAL
(fun c s e =>
match (get_arguments e) with
| (Some (A, B, C, D, _), _, _) =>
(REPEAT n (SYMEXE_STEP (compute_type_id_env (mk_tycontext A B C D (PTree.empty funspec)))))
| _ => FAIL
end)))))
(TRY (THEN INTROS (EAPPLY typ func reify_derives_refl)))) (@RTac.Minify.MINIFY typ (expr typ func) _).
(*Definition SYMEXE_TAC := SYMEXE_TAC_n 1000.  Definition SYMEXE1_TAC := SYMEXE_TAC_n 1.*)
Definition rreflexivity e :=
run_tac (REFLEXIVITY tbl) e.
Definition test_lemma :=
@lemmaD typ (expr typ func) RType_typ ExprD.Expr_expr (expr typ func)
(fun tus tvs e => ExprDsimul.ExprDenote.exprD' tus tvs typrop e)
_
nil nil.
Fixpoint is_pure (e : expr typ func) :=
match e with
| App e1 e2 => is_pure e1
| (Inj (inr (Sep fprop))) => true
| _ => false
end.
Definition CANCEL e := run_tac (THEN INTROS (CANCELLATION typ func tympred is_pure)) e.
Let Expr_expr := (Expr_expr_fs tbl).
Existing Instance Expr_expr.
Definition run_tac' tac goal :=
runOnGoals tac nil nil 0 0 (CTop nil nil)
(ctx_empty (typ := typ) (expr := expr typ func)) goal.

Lemma run_rtac_More tac s goal e
(Hsound : rtac_sound tac)
(Hres : run_tac' tac (GGoal e) = More_ s goal) :
goalD_Prop tbl nil nil goal -> exprD_Prop tbl nil nil e.