src/Tools/atomize_elim.ML
author krauss
Tue, 08 Apr 2008 20:09:54 +0200
changeset 26582 6f9c62d17baa
child 27571 69f3981c8ed4
permissions -rw-r--r--
added missing file
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
26582
6f9c62d17baa added missing file
krauss
parents:
diff changeset
     1
(*  Title:      Tools/atomize_elim.ML
6f9c62d17baa added missing file
krauss
parents:
diff changeset
     2
    ID:         $Id$
6f9c62d17baa added missing file
krauss
parents:
diff changeset
     3
    Author:     Alexander Krauss, TU Muenchen
6f9c62d17baa added missing file
krauss
parents:
diff changeset
     4
6f9c62d17baa added missing file
krauss
parents:
diff changeset
     5
Turn elimination rules into atomic expressions in the object logic.
6f9c62d17baa added missing file
krauss
parents:
diff changeset
     6
*)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
     7
6f9c62d17baa added missing file
krauss
parents:
diff changeset
     8
signature ATOMIZE_ELIM =
6f9c62d17baa added missing file
krauss
parents:
diff changeset
     9
sig
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    10
  val declare_atomize_elim : attribute  
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    11
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    12
  val atomize_elim : Proof.context -> conv
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    13
  val full_atomize_elim : Proof.context -> conv
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    14
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    15
  val atomize_elim_tac : Proof.context -> int -> tactic
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    16
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    17
  val setup : theory -> theory
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    18
end
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    19
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    20
structure AtomizeElim : ATOMIZE_ELIM =
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    21
struct
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    22
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    23
(* theory data *)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    24
structure AtomizeElimData = TheoryDataFun
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    25
(
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    26
  type T = thm list;
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    27
  val empty = [];
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    28
  val copy = I;
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    29
  val extend = I;
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    30
  fun merge _ = Thm.merge_thms
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    31
);
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    32
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    33
val add_elim = AtomizeElimData.map o Thm.add_thm
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    34
val declare_atomize_elim = Thm.declaration_attribute (fn th => Context.mapping (add_elim th) I);
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    35
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    36
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    37
(* More conversions: *)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    38
local open Conv in
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    39
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    40
(* Compute inverse permutation *)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    41
fun invert_perm pi =
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    42
      (pi @ ((0 upto (fold (curry Int.max) pi 0)) \\ pi))
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    43
           |> map_index I
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    44
           |> sort (int_ord o pairself snd)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    45
           |> map fst
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    46
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    47
(* rearrange_prems as a conversion *)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    48
fun rearrange_prems_conv pi ct =
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    49
    let
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    50
      val pi' = 0 :: map (curry op + 1) pi
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    51
      val fwd  = trivial ct
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    52
                  |> Drule.rearrange_prems pi'
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    53
      val back = trivial (snd (Thm.dest_implies (cprop_of fwd)))
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    54
                  |> Drule.rearrange_prems (invert_perm pi')
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    55
    in equal_intr fwd back end
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    56
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    57
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    58
(* convert !!thesis. (!!x y z. ... => thesis) ==> ... 
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    59
                     ==> (!!a b c. ... => thesis)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    60
                     ==> thesis
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    61
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    62
   to
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    63
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    64
   (EX x y z. ...) | ... | (EX a b c. ...)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    65
*)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    66
fun atomize_elim ctxt ct =
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    67
    (forall_conv (K (prems_conv ~1 ObjectLogic.atomize_prems)) ctxt
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    68
    then_conv MetaSimplifier.rewrite true (AtomizeElimData.get (ProofContext.theory_of ctxt))
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    69
    then_conv (fn ct' => if can ObjectLogic.dest_judgment ct'
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    70
                         then all_conv ct'
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    71
                         else raise CTERM ("atomize_elim", [ct', ct])))
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    72
    ct
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    73
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    74
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    75
(* Move the thesis-quantifier inside over other quantifiers and unrelated prems *)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    76
fun thesis_miniscope_conv inner_cv ctxt =
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    77
    let
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    78
      (* check if the outermost quantifier binds the conclusion *)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    79
      fun is_forall_thesis (Const ("all", _) $ Abs (_, T, b)) =
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    80
          exists_subterm (fn Free (n, _) => n = "" | _ => false) 
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    81
                         (Logic.strip_assums_concl (subst_bound (Free ("", dummyT), b)))
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    82
        | is_forall_thesis _ = false
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    83
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    84
      (* move unrelated assumptions out of the quantification *)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    85
      fun movea_conv ctxt ct =
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    86
          let
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    87
            val _ $ Abs (_, _, b) = term_of ct
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    88
            val idxs = fold_index (fn (i, t) => not (loose_bvar1 (t, 0)) ? cons i)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    89
                       (Logic.strip_imp_prems b) []
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    90
                       |> rev
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    91
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    92
            fun skip_over_assm cv = rewr_conv (Thm.symmetric Drule.norm_hhf_eq)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    93
                                    then_conv (implies_concl_conv cv)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    94
          in
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    95
            (forall_conv (K (rearrange_prems_conv idxs)) ctxt
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    96
             then_conv (funpow (length idxs) skip_over_assm (inner_cv ctxt)))
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    97
            ct
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    98
          end
6f9c62d17baa added missing file
krauss
parents:
diff changeset
    99
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   100
      (* move current quantifier to the right *)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   101
      fun moveq_conv ctxt = 
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   102
          (rewr_conv @{thm swap_params} then_conv (forall_conv (uncurry (K moveq_conv)) ctxt))
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   103
          else_conv (movea_conv ctxt)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   104
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   105
      fun ms_conv ctxt ct = 
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   106
          if is_forall_thesis (term_of ct)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   107
          then moveq_conv ctxt ct
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   108
          else (implies_concl_conv (ms_conv ctxt)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   109
            else_conv
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   110
            (forall_conv (uncurry (K ms_conv)) ctxt))
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   111
            ct
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   112
    in
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   113
      ms_conv ctxt 
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   114
    end
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   115
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   116
val full_atomize_elim = thesis_miniscope_conv atomize_elim
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   117
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   118
end
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   119
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   120
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   121
fun atomize_elim_tac ctxt = CSUBGOAL (fn (csubg, i) =>
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   122
    let
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   123
      val _ $ thesis = Logic.strip_assums_concl (term_of csubg)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   124
                       
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   125
      (* Introduce a quantifier first if the thesis is not bound *)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   126
      val quantify_thesis = 
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   127
          if is_Bound thesis then all_tac
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   128
          else let
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   129
              val cthesis = cterm_of (theory_of_cterm csubg) thesis
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   130
              val rule = instantiate' [SOME (ctyp_of_term cthesis)] [NONE, SOME cthesis] 
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   131
                         @{thm meta_spec}
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   132
            in
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   133
              Thm.compose_no_flatten false (rule, 1) i
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   134
            end
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   135
    in
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   136
      quantify_thesis
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   137
      THEN (CONVERSION (full_atomize_elim ctxt) i)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   138
    end)
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   139
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   140
val setup = Method.add_methods
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   141
  [("atomize_elim", Method.ctxt_args (Method.SIMPLE_METHOD' o atomize_elim_tac),
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   142
    "convert obtains statement to atomic object logic goal")]
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   143
  #> Attrib.add_attributes 
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   144
      [("atomize_elim", Attrib.no_args declare_atomize_elim, "declaration of atomize_elim rewrite rule")]
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   145
6f9c62d17baa added missing file
krauss
parents:
diff changeset
   146
end