Separation_Algebra/Sep_Tactics.thy
changeset 0 1378b654acde
child 25 a5f5b9336007
equal deleted inserted replaced
-1:000000000000 0:1378b654acde
       
     1 (* Authors: Gerwin Klein and Rafal Kolanski, 2012
       
     2    Maintainers: Gerwin Klein <kleing at cse.unsw.edu.au>
       
     3                 Rafal Kolanski <rafal.kolanski at nicta.com.au>
       
     4 *)
       
     5 
       
     6 header "Separation Logic Tactics"
       
     7 
       
     8 theory Sep_Tactics
       
     9 imports Separation_Algebra
       
    10 begin
       
    11 
       
    12 ML_file "sep_tactics.ML"
       
    13 
       
    14 text {* A number of proof methods to assist with reasoning about separation logic. *}
       
    15 
       
    16 
       
    17 section {* Selection (move-to-front) tactics *}
       
    18 
       
    19 method_setup sep_select = {*
       
    20   Scan.lift Parse.int >> (fn n => fn ctxt => SIMPLE_METHOD' (sep_select_tac ctxt n))
       
    21 *} "Select nth separation conjunct in conclusion"
       
    22 
       
    23 method_setup sep_select_asm = {*
       
    24   Scan.lift Parse.int >> (fn n => fn ctxt => SIMPLE_METHOD' (sep_select_asm_tac ctxt n))
       
    25 *} "Select nth separation conjunct in assumptions"
       
    26 
       
    27 
       
    28 section {* Substitution *}
       
    29 
       
    30 method_setup "sep_subst" = {*
       
    31   Scan.lift (Args.mode "asm" -- Scan.optional (Args.parens (Scan.repeat Parse.nat)) [0]) --
       
    32     Attrib.thms >> (fn ((asm, occs), thms) => fn ctxt =>
       
    33       SIMPLE_METHOD' ((if asm then sep_subst_asm_tac else sep_subst_tac) ctxt occs thms))
       
    34 *}
       
    35 "single-step substitution after solving one separation logic assumption"
       
    36 
       
    37 
       
    38 section {* Forward Reasoning *}
       
    39 
       
    40 method_setup "sep_drule" = {*
       
    41   Attrib.thms >> (fn thms => fn ctxt => SIMPLE_METHOD' (sep_dtac ctxt thms))
       
    42 *} "drule after separating conjunction reordering"
       
    43 
       
    44 method_setup "sep_frule" = {*
       
    45   Attrib.thms >> (fn thms => fn ctxt => SIMPLE_METHOD' (sep_ftac ctxt thms))
       
    46 *} "frule after separating conjunction reordering"
       
    47 
       
    48 
       
    49 section {* Backward Reasoning *}
       
    50 
       
    51 method_setup "sep_rule" = {*
       
    52   Attrib.thms >> (fn thms => fn ctxt => SIMPLE_METHOD' (sep_rtac ctxt thms))
       
    53 *} "applies rule after separating conjunction reordering"
       
    54 
       
    55 
       
    56 section {* Cancellation of Common Conjuncts via Elimination Rules *}
       
    57 
       
    58 ML {*
       
    59   structure SepCancel_Rules = Named_Thms (
       
    60     val name = @{binding "sep_cancel"};
       
    61     val description = "sep_cancel rules";
       
    62   );
       
    63 *}
       
    64 setup SepCancel_Rules.setup
       
    65 
       
    66 text {*
       
    67   The basic @{text sep_cancel_tac} is minimal. It only eliminates
       
    68   erule-derivable conjuncts between an assumption and the conclusion.
       
    69 
       
    70   To have a more useful tactic, we augment it with more logic, to proceed as
       
    71   follows:
       
    72   \begin{itemize}
       
    73   \item try discharge the goal first using @{text tac}
       
    74   \item if that fails, invoke @{text sep_cancel_tac}
       
    75   \item if @{text sep_cancel_tac} succeeds
       
    76     \begin{itemize}
       
    77     \item try to finish off with tac (but ok if that fails)
       
    78     \item try to finish off with @{term sep_true} (but ok if that fails)
       
    79     \end{itemize}
       
    80   \end{itemize}
       
    81   *}
       
    82 
       
    83 ML {*
       
    84   fun sep_cancel_smart_tac ctxt tac =
       
    85     let fun TRY' tac = tac ORELSE' (K all_tac)
       
    86     in
       
    87       tac
       
    88       ORELSE' (sep_cancel_tac ctxt tac
       
    89                THEN' TRY' tac
       
    90                THEN' TRY' (rtac @{thm TrueI}))
       
    91       ORELSE' (etac @{thm sep_conj_sep_emptyE}
       
    92                THEN' sep_cancel_tac ctxt tac
       
    93                THEN' TRY' tac
       
    94                THEN' TRY' (rtac @{thm TrueI}))
       
    95     end;
       
    96 
       
    97   fun sep_cancel_smart_tac_rules ctxt etacs =
       
    98       sep_cancel_smart_tac ctxt (FIRST' ([atac] @ etacs));
       
    99 
       
   100   val sep_cancel_syntax = Method.sections [
       
   101     Args.add -- Args.colon >> K (I, SepCancel_Rules.add)] >> K ();
       
   102 *}
       
   103 
       
   104 method_setup sep_cancel = {*
       
   105   sep_cancel_syntax >> (fn _ => fn ctxt =>
       
   106     let
       
   107       val etacs = map etac (SepCancel_Rules.get ctxt);
       
   108     in
       
   109       SIMPLE_METHOD' (sep_cancel_smart_tac_rules ctxt etacs)
       
   110     end)
       
   111 *} "Separating conjunction conjunct cancellation"
       
   112 
       
   113 text {*
       
   114   As above, but use blast with a depth limit to figure out where cancellation
       
   115   can be done. *}
       
   116 
       
   117 method_setup sep_cancel_blast = {*
       
   118   sep_cancel_syntax >> (fn _ => fn ctxt =>
       
   119     let
       
   120       val rules = SepCancel_Rules.get ctxt;
       
   121       val tac = Blast.depth_tac (ctxt addIs rules) 10;
       
   122     in
       
   123       SIMPLE_METHOD' (sep_cancel_smart_tac ctxt tac)
       
   124     end)
       
   125 *} "Separating conjunction conjunct cancellation using blast"
       
   126 
       
   127 end