Separation_Algebra/sep_tactics.ML
author Christian Urban <christian dot urban at kcl dot ac dot uk>
Thu, 06 Mar 2014 13:28:38 +0000
changeset 0 1378b654acde
child 25 a5f5b9336007
permissions -rw-r--r--
initial commit for Isabelle 2013-1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     1
(* Title: Tactics for abstract separation algebras
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     2
   Authors: Gerwin Klein and Rafal Kolanski, 2012
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     3
   Maintainers: Gerwin Klein <kleing at cse.unsw.edu.au>
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     4
                Rafal Kolanski <rafal.kolanski at nicta.com.au>
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     5
*)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     6
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     7
(* Separating Conjunction (and Top, AKA sep_true) {{{
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     8
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     9
  This defines all the constants and theorems necessary for the conjunct
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    10
  selection and cancelling tactic, as well as utility functions.
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    11
*)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    12
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    13
structure SepConj =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    14
struct
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    15
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    16
val sep_conj_term = @{term sep_conj};
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    17
val sep_conj_str = "**";
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    18
val sep_conj_ac = @{thms sep_conj_ac};
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    19
val sep_conj_impl = @{thm sep_conj_impl}
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    20
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    21
fun is_sep_conj_const (Const (@{const_name sep_conj}, _)) = true
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    22
  | is_sep_conj_const _ = false;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    23
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    24
fun is_sep_conj_term
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    25
      (Const t $ _ $ _ $ _) = is_sep_conj_const (Const t)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    26
  | is_sep_conj_term _ = false;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    27
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    28
fun is_sep_conj_prop
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    29
      (Const Trueprop $ t) = is_sep_conj_term t
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    30
  | is_sep_conj_prop _ = false;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    31
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    32
fun break_sep_conj (Const (@{const_name sep_conj},_) $ t1 $ t2 $ _) =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    33
  [t1] @ (break_sep_conj t2)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    34
  | break_sep_conj (Const (@{const_name sep_conj},_) $ t1 $ t2) =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    35
  [t1] @ (break_sep_conj t2)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    36
  (* dig through eta exanded terms: *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    37
  | break_sep_conj (Abs (_, _, t $ Bound 0)) = break_sep_conj t
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    38
  | break_sep_conj t = [t];
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    39
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    40
fun is_sep_true_term (Abs (_, _, Const (@{const_name True}, _))) = true
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    41
  | is_sep_true_term _ = false;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    42
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    43
end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    44
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    45
(* }}} *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    46
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    47
(* Convenience functions for lists {{{ *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    48
structure ListExtra =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    49
struct
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    50
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    51
fun init l = List.take (l, List.length l - 1);
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    52
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    53
fun range _ 0 = []
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    54
  | range from howmany = from :: (range (from+1) (howmany-1));
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    55
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    56
(* move nth element in list to the front *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    57
fun nth_to_front i xs =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    58
      (nth xs i) :: (List.take (xs, i)) @ (List.drop (xs,i+1));
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    59
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    60
(* assign all members of list an index in the list *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    61
fun index_list xs = ListPair.zip (range 0 (length xs), xs);
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    62
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    63
end; (* }}} *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    64
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    65
(* Function application terms {{{ *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    66
(* Dealing with function applications of the type
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    67
     Const/Free(name,type) $ arg1 $ arg2 $ ... $ last_arg *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    68
structure FunApp =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    69
struct
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    70
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    71
(* apply a transformation to the args in a function application term *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    72
fun app_args_op f t = strip_comb t |> apsnd f |> list_comb;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    73
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    74
(* remove last argument *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    75
fun app_del_last_arg t = app_args_op ListExtra.init t;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    76
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    77
(* apply a function term to a Free with given name *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    78
fun fun_app_free t free_name = t $ Free (free_name, type_of t |> domain_type);
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    79
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    80
(* fold two-argument function over a list of arg names using fun_app_free *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    81
fun fun_app_foldr f [a,b] = fun_app_free (fun_app_free f a) b
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    82
  | fun_app_foldr f (x::xs) = (fun_app_free f x) $ (fun_app_foldr f xs)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    83
  | fun_app_foldr _ _ = raise Fail "fun_app_foldr";
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    84
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    85
end; (* }}} *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    86
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    87
(* Selecting Conjuncts in Premise or Conclusion {{{ *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    88
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    89
(* Constructs a rearrangement lemma of the kind:
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    90
   (A ** B ** C) s ==> (C ** A ** B) s
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    91
   When cjt_select = 2 (0-based index of C) and
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    92
   cjt_select = 3 (number of conjuncts to use), conclusion = true
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    93
   "conclusion" specifies whether the rearrangement occurs in conclusion
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    94
   (for dtac) or the premise (for rtac) of the rule.
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    95
*)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    96
fun mk_sep_select_rule ctxt conclusion (cjt_count, cjt_select) =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    97
let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    98
  fun variants nctxt names = fold_map Name.variant names nctxt;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    99
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   100
  val (state, nctxt0) = Name.variant "s" (Variable.names_of ctxt);
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   101
  fun sep_conj_prop cjts =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   102
        FunApp.fun_app_free
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   103
          (FunApp.fun_app_foldr SepConj.sep_conj_term cjts) state
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   104
        |> HOLogic.mk_Trueprop;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   105
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   106
  (* concatenate string and string of an int *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   107
  fun conc_str_int str int = str ^ Int.toString int;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   108
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   109
  (* make the conjunct names *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   110
  val (cjts, _) = ListExtra.range 1 cjt_count
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   111
                  |> map (conc_str_int "a") |> variants nctxt0;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   112
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   113
  (* make normal-order separation conjunction terms *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   114
  val orig = sep_conj_prop cjts;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   115
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   116
  (* make reordered separation conjunction terms *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   117
  val reordered = sep_conj_prop (ListExtra.nth_to_front cjt_select cjts);
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   118
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   119
  val goal = Logic.mk_implies
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   120
               (if conclusion then (orig, reordered) else (reordered, orig));
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   121
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   122
  (* simp add: sep_conj_ac *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   123
  val sep_conj_ac_tac = Simplifier.asm_full_simp_tac
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   124
                          (put_simpset HOL_basic_ss ctxt addsimps SepConj.sep_conj_ac);
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   125
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   126
in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   127
  (* XXX: normally you'd want to keep track of what variables we want to make
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   128
     schematic and which ones are bound, but we don't use fixed names for
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   129
     the rules we make, so we use Drule.export_without_context to schematise
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   130
     all. *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   131
  Goal.prove ctxt [] [] goal (fn _ => sep_conj_ac_tac 1)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   132
  |> Drule.export_without_context
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   133
end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   134
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   135
(* }}} *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   136
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   137
local
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   138
  (* Common tactic functionality {{{ *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   139
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   140
  (* given two terms of some 'a to bool, can you prove
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   141
     \<And>s. t1 s \<Longrightarrow> t2 s
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   142
     using the supplied proof method?
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   143
     NOTE: t1 and t2 MUST have a function type with one argument,
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   144
     or TYPE dest_Type is raised
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   145
     NOTE: if asm or concl is sep_true, returns false
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   146
  *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   147
  fun can_prove ctxt tac asm concl =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   148
    let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   149
      fun variant name = Name.variant name (Variable.names_of ctxt) |> fst;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   150
      val arg_name = variant "s";
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   151
      val left = FunApp.fun_app_free asm arg_name |> HOLogic.mk_Trueprop;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   152
      val right = FunApp.fun_app_free concl arg_name |> HOLogic.mk_Trueprop;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   153
      val goal = Logic.mk_implies (left, right);
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   154
    in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   155
      if (SepConj.is_sep_true_term asm) orelse (SepConj.is_sep_true_term concl)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   156
      then false
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   157
      else (Goal.prove ctxt [] [] goal (fn _ => tac 1); true)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   158
            handle ERROR _ => false
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   159
    end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   160
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   161
  (* apply function in list until it returns SOME *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   162
  fun find_some (x::xs) f =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   163
    (case f x of SOME v => SOME v
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   164
               | NONE => find_some xs f)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   165
    | find_some [] _ = NONE;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   166
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   167
  (* Given indices into the separating conjunctions in the assumption and
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   168
     conclusion, rewrite them so that the targeted conjuncts are at the
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   169
     front, then remove them. *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   170
  fun eliminate_target_tac ctxt tac
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   171
                           ((prem_total,prem_idx), (concl_total,concl_idx)) =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   172
    let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   173
      val asm_select = mk_sep_select_rule ctxt true (prem_total,prem_idx);
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   174
      val concl_select = mk_sep_select_rule ctxt false
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   175
                           (concl_total,concl_idx);
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   176
    in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   177
      dtac asm_select THEN' rtac concl_select
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   178
      THEN' etac SepConj.sep_conj_impl THEN' tac
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   179
    end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   180
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   181
  fun find_target ctxt tac cprem cconcl =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   182
    let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   183
      val prem_cjts = cprem |> term_of |> SepConj.break_sep_conj;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   184
      val concl_cjts = cconcl |> term_of |> SepConj.break_sep_conj;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   185
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   186
      val iprems = ListExtra.index_list prem_cjts;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   187
      val iconcls = ListExtra.index_list concl_cjts;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   188
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   189
      fun can_prove' (pi,p) (ci,c) =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   190
            if can_prove ctxt tac p c then SOME (pi, ci) else NONE;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   191
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   192
      val target = find_some iconcls
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   193
                     (fn c => find_some iprems (fn p => can_prove' p c));
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   194
    in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   195
      case target
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   196
        of SOME (pi,ci) => SOME ((List.length prem_cjts, pi),
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   197
                                 (List.length concl_cjts, ci))
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   198
         | NONE => NONE
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   199
    end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   200
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   201
  fun strip_cprop ct =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   202
    let val thy = theory_of_cterm ct
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   203
    in ct |> term_of |> HOLogic.dest_Trueprop |> cterm_of thy
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   204
    end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   205
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   206
  (* }}} *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   207
in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   208
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   209
  (* Tactic: Select nth conjunct in assumption {{{ *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   210
  local
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   211
    fun sep_select_asm_tac' ctxt n (ct, i) =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   212
      let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   213
        (* digging out prems *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   214
        val ((_, ct'), _) = Variable.focus_cterm ct ctxt;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   215
        val prems = Drule.strip_imp_prems ct';
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   216
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   217
        fun prem_ok ct = SepConj.is_sep_conj_prop (term_of ct)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   218
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   219
        fun mk_tac prem =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   220
            let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   221
              val prem = HOLogic.dest_Trueprop (term_of prem)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   222
              val p = length (SepConj.break_sep_conj prem)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   223
              val th = mk_sep_select_rule ctxt true (p,n)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   224
                  handle Subscript => error "Conjunct index out of range"
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   225
             in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   226
               dtac th i
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   227
             end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   228
      in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   229
        if length prems = 0
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   230
        then error ("No assumption of form: (_ " ^ SepConj.sep_conj_str ^
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   231
                    " _) _")
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   232
        else
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   233
          (* backtrack until first premise that does something *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   234
          map mk_tac (filter prem_ok prems) |> FIRST
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   235
      end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   236
    in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   237
      fun sep_select_asm_tac ctxt n = CSUBGOAL (sep_select_asm_tac' ctxt (n-1))
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   238
    end; (* }}} *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   239
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   240
  (* Tactic: Select nth conjunct in conclusion {{{ *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   241
  local
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   242
    fun sep_select_tac' ctxt n (ct, i) =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   243
      let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   244
        (* digging out conclusions *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   245
        val ((_, ct'), _) = Variable.focus_cterm ct ctxt;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   246
        val concl = ct' |> Drule.strip_imp_concl |> term_of;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   247
        val p = concl |> HOLogic.dest_Trueprop |> SepConj.break_sep_conj
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   248
                |> length;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   249
        val th = mk_sep_select_rule ctxt false (p,n)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   250
                 handle Subscript => error "Conjunct index out of range"
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   251
      in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   252
        if not (SepConj.is_sep_conj_prop concl)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   253
        then error ("Goal not of form: (_ " ^ SepConj.sep_conj_str ^ " _) _")
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   254
        else rtac th i
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   255
      end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   256
  in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   257
    fun sep_select_tac ctxt n = CSUBGOAL (sep_select_tac' ctxt (n-1))
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   258
  end; (* }}} *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   259
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   260
  (* Tactic: for all reorderings of the premises try apply tac {{{ *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   261
    local
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   262
      fun sep_assm_tac' ctxt tac (ct,i) =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   263
        let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   264
          (* digging out prems *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   265
          val ((_, ct'), _) = Variable.focus_cterm ct ctxt;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   266
          val prems = Drule.strip_imp_prems ct';
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   267
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   268
          fun prem_ok ct = SepConj.is_sep_conj_prop (term_of ct)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   269
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   270
          fun mk_tac prem =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   271
            let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   272
              val prem = HOLogic.dest_Trueprop (term_of prem)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   273
              val p = length (SepConj.break_sep_conj prem)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   274
              fun ord n = mk_sep_select_rule ctxt true (p,n)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   275
              val ord_thms = map ord (0 upto p-1)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   276
            in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   277
                (dresolve_tac ord_thms THEN' tac) i
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   278
            end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   279
        in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   280
          (* backtrack until first premise that does something *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   281
          map mk_tac (filter prem_ok prems) |> FIRST
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   282
        end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   283
    in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   284
      fun sep_assm_tac ctxt tac = CSUBGOAL (sep_assm_tac' ctxt tac)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   285
    end; (* }}} *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   286
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   287
  (* Tactic: for all reorderings of the conclusion, try apply tac {{{ *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   288
  local
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   289
    fun sep_concl_tac' ctxt tac (ct, i) =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   290
      let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   291
        (* digging out conclusion *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   292
        val ((_, ct'), _) = Variable.focus_cterm ct ctxt;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   293
        val concl = ct' |> Drule.strip_imp_concl |> term_of;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   294
        val p = concl |> HOLogic.dest_Trueprop |> SepConj.break_sep_conj
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   295
                |> length;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   296
        fun ord n = mk_sep_select_rule ctxt false (p,n);
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   297
        val ord_thms = map ord (0 upto p-1);
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   298
      in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   299
        if not (SepConj.is_sep_conj_prop concl)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   300
        then (tracing ("Goal not of form: (_ " ^ SepConj.sep_conj_str ^
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   301
                      " _) _");
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   302
              no_tac)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   303
        else (resolve_tac ord_thms THEN' tac) i
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   304
      end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   305
  in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   306
    fun sep_concl_tac ctxt tac = CSUBGOAL (sep_concl_tac' ctxt tac)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   307
  end; (* }}} *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   308
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   309
  (* Tactic: Cancel conjuncts of assumption and conclusion via tac {{{ *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   310
  local
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   311
    fun sep_cancel_tac' ctxt tac (ct, i) =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   312
      let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   313
        (* digging out prems and conclusions *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   314
        val ((vars, ct'), ctxt') = Variable.focus_cterm ct ctxt;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   315
        val concl = Drule.strip_imp_concl ct';
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   316
        val prems = Drule.strip_imp_prems ct';
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   317
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   318
        fun prem_ok ct =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   319
          let
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   320
            (* name of state in sep conj (should be Free after focus) *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   321
            fun state_get (_ $ _ $ _ $ s) = s
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   322
              | state_get t = raise Fail "prem_ok: state_get";
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   323
            val state_get_ct = state_get o HOLogic.dest_Trueprop o term_of;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   324
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   325
            val concl_state = concl |> state_get_ct;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   326
            (* states considered equal if they alpha-convert *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   327
            fun state_ok ct = (state_get_ct ct) aconv concl_state;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   328
          in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   329
            SepConj.is_sep_conj_prop (term_of ct) andalso state_ok ct
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   330
          end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   331
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   332
        fun mk_tac prem =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   333
              case find_target ctxt tac (prem |> strip_cprop)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   334
                                        (strip_cprop concl)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   335
                of SOME target => eliminate_target_tac ctxt tac target i
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   336
                 | NONE => no_tac;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   337
      in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   338
        if (not (concl |> term_of |> SepConj.is_sep_conj_prop))
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   339
        then (tracing ("Goal not of form: (_ " ^ SepConj.sep_conj_str ^
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   340
                       " _) _");
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   341
              no_tac)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   342
        else if (length prems = 0)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   343
        then (tracing ("No assumption of form: (_ " ^ SepConj.sep_conj_str ^
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   344
                       " _) _");
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   345
              no_tac)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   346
        else
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   347
          (* backtrack until first premise that does something *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   348
          map mk_tac (filter prem_ok prems) |> FIRST
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   349
      end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   350
  in
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   351
    fun sep_cancel_tac ctxt tac = CSUBGOAL (sep_cancel_tac' ctxt tac)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   352
  end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   353
  (* }}} *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   354
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   355
  (* Derived Tactics *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   356
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   357
  fun sep_atac ctxt = sep_assm_tac ctxt atac;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   358
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   359
  (* Substitution *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   360
  fun sep_subst_tac ctxt occs thms =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   361
        EqSubst.eqsubst_tac ctxt occs thms THEN' sep_atac ctxt;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   362
  fun sep_subst_asm_tac ctxt occs thms =
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   363
        EqSubst.eqsubst_asm_tac ctxt occs thms THEN' sep_atac ctxt;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   364
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   365
  (* Forward reasoning *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   366
  fun sep_dtac ctxt thms = sep_assm_tac ctxt (dresolve_tac thms)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   367
  fun sep_ftac ctxt thms = sep_assm_tac ctxt (forward_tac thms)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   368
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   369
  (* Backward reasoning *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   370
  fun sep_rtac ctxt thms = sep_concl_tac ctxt (resolve_tac thms)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   371
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   372
end;
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   373
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   374
(* vim: set foldmethod=marker sw=2 sts=2 et: *)
1378b654acde initial commit for Isabelle 2013-1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   375