Definition skip_lemma : my_lemma.Definition seq_lemma (s1 s2: statement)  : my_lemma.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 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 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) _)).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.Definition run_tac' tac goal :=
  runOnGoals tac nil nil 0 0 (CTop nil nil)
    (ctx_empty (typ := typ) (expr := expr typ func)) goal.

(* Specifications: *)
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.
Lemma run_rtac_Solved tac s e (Hsound : rtac_sound tac) (Hres : run_tac' tac (GGoal e) = Solved s) : exprD_Prop tbl nil nil e.