src/HOL/Tools/Function/pattern_split.ML
author blanchet
Wed, 08 Jun 2011 16:20:18 +0200
changeset 43293 a80cdc4b27a3
parent 42483 39eefaef816a
child 54406 a2d18fea844a
permissions -rw-r--r--
made "query" type systes a bit more sound -- local facts, e.g. the negated conjecture, may make invalid the infinity check, e.g. if we are proving that there exists two values of an infinite type, we can use the negated conjecture that there is only one value to derive unsound proofs unless the type is properly encoded
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
31775
2b04504fcb69 uniformly capitialized names for subdirectories
haftmann
parents: 31723
diff changeset
     1
(*  Title:      HOL/Tools/Function/pattern_split.ML
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
     2
    Author:     Alexander Krauss, TU Muenchen
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
     3
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
     4
Fairly ad-hoc pattern splitting.
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
     5
*)
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
     6
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents: 33049
diff changeset
     7
signature FUNCTION_SPLIT =
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
     8
sig
20289
ba7a7c56bed5 normalized Proof.context/method type aliases;
wenzelm
parents: 20270
diff changeset
     9
  val split_some_equations :
21237
b803f9870e97 untabified
krauss
parents: 21051
diff changeset
    10
      Proof.context -> (bool * term) list -> term list list
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    11
20523
36a59e5d0039 Major update to function package, including new syntax and the (only theoretical)
krauss
parents: 20344
diff changeset
    12
  val split_all_equations :
21237
b803f9870e97 untabified
krauss
parents: 21051
diff changeset
    13
      Proof.context -> term list -> term list list
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    14
end
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    15
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents: 33049
diff changeset
    16
structure Function_Split : FUNCTION_SPLIT =
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    17
struct
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    18
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents: 33049
diff changeset
    19
open Function_Lib
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    20
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    21
fun new_var ctxt vs T =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    22
  let
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    23
    val [v] = Variable.variant_frees ctxt vs [("v", T)]
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    24
  in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    25
    (Free v :: vs, Free v)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    26
  end
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    27
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    28
fun saturate ctxt vs t =
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    29
  fold (fn T => fn (vs, t) => new_var ctxt vs T |> apsnd (curry op $ t))
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    30
    (binder_types (fastype_of t)) (vs, t)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    31
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    32
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    33
(* This is copied from "pat_completeness.ML" *)
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    34
fun inst_constrs_of thy (T as Type (name, _)) =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    35
  map (fn (Cn,CT) =>
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    36
    Envir.subst_term_types (Sign.typ_match thy (body_type CT, T) Vartab.empty) (Const (Cn, CT)))
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    37
    (the (Datatype.get_constrs thy name))
25402
0a1005435e11 avoid ML print in production code;
wenzelm
parents: 24584
diff changeset
    38
  | inst_constrs_of thy T = raise TYPE ("inst_constrs_of", [T], [])
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    39
20636
ddddf0b7d322 Fixed error in pattern splitting algorithm
krauss
parents: 20523
diff changeset
    40
ddddf0b7d322 Fixed error in pattern splitting algorithm
krauss
parents: 20523
diff changeset
    41
fun join ((vs1,sub1), (vs2,sub2)) = (merge (op aconv) (vs1,vs2), sub1 @ sub2)
25538
58e8ba3b792b map_product and fold_product
haftmann
parents: 25402
diff changeset
    42
fun join_product (xs, ys) = map_product (curry join) xs ys
20636
ddddf0b7d322 Fixed error in pattern splitting algorithm
krauss
parents: 20523
diff changeset
    43
ddddf0b7d322 Fixed error in pattern splitting algorithm
krauss
parents: 20523
diff changeset
    44
exception DISJ
ddddf0b7d322 Fixed error in pattern splitting algorithm
krauss
parents: 20523
diff changeset
    45
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    46
fun pattern_subtract_subst ctxt vs t t' =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    47
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    48
    exception DISJ
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    49
    fun pattern_subtract_subst_aux vs _ (Free v2) = []
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    50
      | pattern_subtract_subst_aux vs (v as (Free (_, T))) t' =
20344
d02b43ea722e avoid low-level tsig;
wenzelm
parents: 20338
diff changeset
    51
          let
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    52
            fun foo constr =
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    53
              let
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    54
                val (vs', t) = saturate ctxt vs constr
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    55
                val substs = pattern_subtract_subst ctxt vs' t t'
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    56
              in
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    57
                map (fn (vs, subst) => (vs, (v,t)::subst)) substs
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    58
              end
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    59
          in
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    60
            maps foo (inst_constrs_of (Proof_Context.theory_of ctxt) T)
20636
ddddf0b7d322 Fixed error in pattern splitting algorithm
krauss
parents: 20523
diff changeset
    61
          end
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    62
     | pattern_subtract_subst_aux vs t t' =
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    63
         let
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    64
           val (C, ps) = strip_comb t
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    65
           val (C', qs) = strip_comb t'
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    66
         in
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    67
           if C = C'
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    68
           then flat (map2 (pattern_subtract_subst_aux vs) ps qs)
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    69
           else raise DISJ
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    70
         end
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    71
  in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    72
    pattern_subtract_subst_aux vs t t'
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    73
    handle DISJ => [(vs, [])]
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    74
  end
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    75
20523
36a59e5d0039 Major update to function package, including new syntax and the (only theoretical)
krauss
parents: 20344
diff changeset
    76
(* p - q *)
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    77
fun pattern_subtract ctxt eq2 eq1 =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    78
  let
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    79
    val thy = Proof_Context.theory_of ctxt
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    80
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    81
    val (vs, feq1 as (_ $ (_ $ lhs1 $ _))) = dest_all_all eq1
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    82
    val (_,  _ $ (_ $ lhs2 $ _)) = dest_all_all eq2
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    83
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
    84
    val substs = pattern_subtract_subst ctxt vs lhs1 lhs2
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    85
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    86
    fun instantiate (vs', sigma) =
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    87
      let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    88
        val t = Pattern.rewrite_term thy sigma [] feq1
42483
39eefaef816a eliminated obsolete Function_Lib.frees_in_term;
wenzelm
parents: 42362
diff changeset
    89
        val xs = fold_aterms
39eefaef816a eliminated obsolete Function_Lib.frees_in_term;
wenzelm
parents: 42362
diff changeset
    90
          (fn x as Free (a, _) =>
39eefaef816a eliminated obsolete Function_Lib.frees_in_term;
wenzelm
parents: 42362
diff changeset
    91
              if not (Variable.is_fixed ctxt a) andalso member (op =) vs' x
39eefaef816a eliminated obsolete Function_Lib.frees_in_term;
wenzelm
parents: 42362
diff changeset
    92
              then insert (op =) x else I
39eefaef816a eliminated obsolete Function_Lib.frees_in_term;
wenzelm
parents: 42362
diff changeset
    93
            | _ => I) t [];
39eefaef816a eliminated obsolete Function_Lib.frees_in_term;
wenzelm
parents: 42362
diff changeset
    94
      in fold Logic.all xs t end
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    95
  in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    96
    map instantiate substs
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    97
  end
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    98
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
    99
(* ps - p' *)
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
   100
fun pattern_subtract_from_many ctxt p'=
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
   101
  maps (pattern_subtract ctxt p')
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
   102
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
   103
(* in reverse order *)
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
   104
fun pattern_subtract_many ctxt ps' =
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
   105
  fold_rev (pattern_subtract_from_many ctxt) ps'
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
   106
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
   107
fun split_some_equations ctxt eqns =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   108
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   109
    fun split_aux prev [] = []
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   110
      | split_aux prev ((true, eq) :: es) =
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
   111
          pattern_subtract_many ctxt prev [eq] :: split_aux (eq :: prev) es
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   112
      | split_aux prev ((false, eq) :: es) =
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
   113
          [eq] :: split_aux (eq :: prev) es
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   114
  in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   115
    split_aux [] eqns
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   116
  end
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   117
42362
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
   118
fun split_all_equations ctxt =
5528970ac6f7 observe firm naming convention ctxt: Proof.context;
wenzelm
parents: 42361
diff changeset
   119
  split_some_equations ctxt o map (pair true)
20523
36a59e5d0039 Major update to function package, including new syntax and the (only theoretical)
krauss
parents: 20344
diff changeset
   120
36a59e5d0039 Major update to function package, including new syntax and the (only theoretical)
krauss
parents: 20344
diff changeset
   121
20270
3abe7dae681e Function package can now do automatic splits of overlapping datatype patterns
krauss
parents:
diff changeset
   122
end