TFL/tfl.ML
author mengj
Fri, 28 Oct 2005 02:28:20 +0200
changeset 18002 35ec4681d38f
parent 17465 93fc1211603f
child 18176 ae9bd644d106
permissions -rw-r--r--
Added several new functions that are used to prove HOL goals. Added new methods "vampireH" and "eproverH" that can prove both FOL and HOL goals. The old "vampire" and "eprover" methods are renamed to "vampireF" and "eproverF"; they can only prove FOL goals.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     1
(*  Title:      TFL/tfl.ML
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     2
    ID:         $Id$
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     3
    Author:     Konrad Slind, Cambridge University Computer Laboratory
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     4
    Copyright   1997  University of Cambridge
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     5
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     6
First part of main module.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     7
*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     8
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     9
signature PRIM =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    10
sig
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    11
  val trace: bool ref
14240
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
    12
  val trace_thms: string -> thm list -> unit
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
    13
  val trace_cterms: string -> cterm list -> unit
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    14
  type pattern
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    15
  val mk_functional: theory -> term list -> {functional: term, pats: pattern list}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    16
  val wfrec_definition0: theory -> string -> term -> term -> theory * thm
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    17
  val post_definition: thm list -> theory * (thm * pattern list) ->
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    18
   {theory: theory,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    19
    rules: thm,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    20
    rows: int list,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    21
    TCs: term list list,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    22
    full_pats_TCs: (term * term list) list}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    23
  val wfrec_eqns: theory -> xstring -> thm list -> term list ->
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    24
   {WFR: term,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    25
    SV: term list,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    26
    proto_def: term,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    27
    extracta: (thm * term list) list,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    28
    pats: pattern list}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    29
  val lazyR_def: theory -> xstring -> thm list -> term list ->
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    30
   {theory: theory,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    31
    rules: thm,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    32
    R: term,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    33
    SV: term list,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    34
    full_pats_TCs: (term * term list) list,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    35
    patterns : pattern list}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    36
  val mk_induction: theory ->
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    37
    {fconst: term, R: term, SV: term list, pat_TCs_list: (term * term list) list} -> thm
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11455
diff changeset
    38
  val postprocess: bool -> {wf_tac: tactic, terminator: tactic, simplifier: cterm -> thm}
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11455
diff changeset
    39
    -> theory -> {rules: thm, induction: thm, TCs: term list list}
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11455
diff changeset
    40
    -> {rules: thm, induction: thm, nested_tcs: thm list}
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    41
end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    42
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    43
structure Prim: PRIM =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    44
struct
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    45
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    46
val trace = ref false;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    47
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    48
structure R = Rules;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    49
structure S = USyntax;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    50
structure U = Utils;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    51
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    52
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    53
fun TFL_ERR func mesg = U.ERR {module = "Tfl", func = func, mesg = mesg};
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    54
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    55
val concl = #2 o R.dest_thm;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    56
val hyp = #1 o R.dest_thm;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    57
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    58
val list_mk_type = U.end_itlist (curry (op -->));
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    59
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    60
fun enumerate xs = ListPair.zip(xs, 0 upto (length xs - 1));
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    61
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    62
fun front_last [] = raise TFL_ERR "front_last" "empty list"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    63
  | front_last [x] = ([],x)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    64
  | front_last (h::t) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    65
     let val (pref,x) = front_last t
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    66
     in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    67
        (h::pref,x)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    68
     end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    69
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    70
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    71
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    72
 * The next function is common to pattern-match translation and
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    73
 * proof of completeness of cases for the induction theorem.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    74
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    75
 * The curried function "gvvariant" returns a function to generate distinct
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    76
 * variables that are guaranteed not to be in names.  The names of
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    77
 * the variables go u, v, ..., z, aa, ..., az, ...  The returned
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    78
 * function contains embedded refs!
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    79
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    80
fun gvvariant names =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    81
  let val slist = ref names
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    82
      val vname = ref "u"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    83
      fun new() =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    84
         if !vname mem_string (!slist)
12902
a23dc0b7566f Symbol.bump_string;
wenzelm
parents: 11632
diff changeset
    85
         then (vname := Symbol.bump_string (!vname);  new())
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    86
         else (slist := !vname :: !slist;  !vname)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    87
  in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    88
  fn ty => Free(new(), ty)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    89
  end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    90
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    91
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    92
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    93
 * Used in induction theorem production. This is the simple case of
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    94
 * partitioning up pattern rows by the leading constructor.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    95
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    96
fun ipartition gv (constructors,rows) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    97
  let fun pfail s = raise TFL_ERR "partition.part" s
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    98
      fun part {constrs = [],   rows = [],   A} = rev A
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    99
        | part {constrs = [],   rows = _::_, A} = pfail"extra cases in defn"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   100
        | part {constrs = _::_, rows = [],   A} = pfail"cases missing in defn"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   101
        | part {constrs = c::crst, rows,     A} =
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   102
          let val (c, T) = dest_Const c
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   103
              val L = binder_types T
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   104
              val (in_group, not_in_group) =
16853
33b886cbdc8f replaced itlist by fold_rev;
wenzelm
parents: 16505
diff changeset
   105
               fold_rev (fn (row as (p::rst, rhs)) =>
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   106
                         fn (in_group,not_in_group) =>
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   107
                  let val (pc,args) = S.strip_comb p
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   108
                  in if (#1(dest_Const pc) = c)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   109
                     then ((args@rst, rhs)::in_group, not_in_group)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   110
                     else (in_group, row::not_in_group)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   111
                  end)      rows ([],[])
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   112
              val col_types = U.take type_of (length L, #1(hd in_group))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   113
          in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   114
          part{constrs = crst, rows = not_in_group,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   115
               A = {constructor = c,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   116
                    new_formals = map gv col_types,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   117
                    group = in_group}::A}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   118
          end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   119
  in part{constrs = constructors, rows = rows, A = []}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   120
  end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   121
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   122
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   123
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   124
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   125
 * Each pattern carries with it a tag (i,b) where
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   126
 * i is the clause it came from and
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   127
 * b=true indicates that clause was given by the user
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   128
 * (or is an instantiation of a user supplied pattern)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   129
 * b=false --> i = ~1
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   130
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   131
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   132
type pattern = term * (int * bool)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   133
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   134
fun pattern_map f (tm,x) = (f tm, x);
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   135
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   136
fun pattern_subst theta = pattern_map (subst_free theta);
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   137
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   138
val pat_of = fst;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   139
fun row_of_pat x = fst (snd x);
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   140
fun given x = snd (snd x);
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   141
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   142
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   143
 * Produce an instance of a constructor, plus genvars for its arguments.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   144
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   145
fun fresh_constr ty_match colty gv c =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   146
  let val (_,Ty) = dest_Const c
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   147
      val L = binder_types Ty
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   148
      and ty = body_type Ty
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   149
      val ty_theta = ty_match ty colty
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   150
      val c' = S.inst ty_theta c
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   151
      val gvars = map (S.inst ty_theta o gv) L
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   152
  in (c', gvars)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   153
  end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   154
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   155
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   156
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   157
 * Goes through a list of rows and picks out the ones beginning with a
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   158
 * pattern with constructor = name.
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   159
 *---------------------------------------------------------------------------*)
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   160
fun mk_group name rows =
16853
33b886cbdc8f replaced itlist by fold_rev;
wenzelm
parents: 16505
diff changeset
   161
  fold_rev (fn (row as ((prfx, p::rst), rhs)) =>
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   162
            fn (in_group,not_in_group) =>
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   163
               let val (pc,args) = S.strip_comb p
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   164
               in if ((#1 (Term.dest_Const pc) = name) handle TERM _ => false)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   165
                  then (((prfx,args@rst), rhs)::in_group, not_in_group)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   166
                  else (in_group, row::not_in_group) end)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   167
      rows ([],[]);
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   168
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   169
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   170
 * Partition the rows. Not efficient: we should use hashing.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   171
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   172
fun partition _ _ (_,_,_,[]) = raise TFL_ERR "partition" "no rows"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   173
  | partition gv ty_match
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   174
              (constructors, colty, res_ty, rows as (((prfx,_),_)::_)) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   175
let val fresh = fresh_constr ty_match colty gv
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   176
     fun part {constrs = [],      rows, A} = rev A
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   177
       | part {constrs = c::crst, rows, A} =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   178
         let val (c',gvars) = fresh c
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   179
             val (in_group, not_in_group) = mk_group (#1 (dest_Const c')) rows
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   180
             val in_group' =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   181
                 if (null in_group)  (* Constructor not given *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   182
                 then [((prfx, #2(fresh c)), (S.ARB res_ty, (~1,false)))]
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   183
                 else in_group
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   184
         in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   185
         part{constrs = crst,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   186
              rows = not_in_group,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   187
              A = {constructor = c',
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   188
                   new_formals = gvars,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   189
                   group = in_group'}::A}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   190
         end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   191
in part{constrs=constructors, rows=rows, A=[]}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   192
end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   193
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   194
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   195
 * Misc. routines used in mk_case
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   196
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   197
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   198
fun mk_pat (c,l) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   199
  let val L = length (binder_types (type_of c))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   200
      fun build (prfx,tag,plist) =
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   201
          let val args   = Library.take (L,plist)
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   202
              and plist' = Library.drop(L,plist)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   203
          in (prfx,tag,list_comb(c,args)::plist') end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   204
  in map build l end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   205
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   206
fun v_to_prfx (prfx, v::pats) = (v::prfx,pats)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   207
  | v_to_prfx _ = raise TFL_ERR "mk_case" "v_to_prfx";
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   208
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   209
fun v_to_pats (v::prfx,tag, pats) = (prfx, tag, v::pats)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   210
  | v_to_pats _ = raise TFL_ERR "mk_case" "v_to_pats";
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   211
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   212
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   213
(*----------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   214
 * Translation of pattern terms into nested case expressions.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   215
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   216
 * This performs the translation and also builds the full set of patterns.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   217
 * Thus it supports the construction of induction theorems even when an
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   218
 * incomplete set of patterns is given.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   219
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   220
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   221
fun mk_case ty_info ty_match usednames range_ty =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   222
 let
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   223
 fun mk_case_fail s = raise TFL_ERR "mk_case" s
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   224
 val fresh_var = gvvariant usednames
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   225
 val divide = partition fresh_var ty_match
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   226
 fun expand constructors ty ((_,[]), _) = mk_case_fail"expand_var_row"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   227
   | expand constructors ty (row as ((prfx, p::rst), rhs)) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   228
       if (is_Free p)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   229
       then let val fresh = fresh_constr ty_match ty fresh_var
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   230
                fun expnd (c,gvs) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   231
                  let val capp = list_comb(c,gvs)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   232
                  in ((prfx, capp::rst), pattern_subst[(p,capp)] rhs)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   233
                  end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   234
            in map expnd (map fresh constructors)  end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   235
       else [row]
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   236
 fun mk{rows=[],...} = mk_case_fail"no rows"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   237
   | mk{path=[], rows = ((prfx, []), (tm,tag))::_} =  (* Done *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   238
        ([(prfx,tag,[])], tm)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   239
   | mk{path=[], rows = _::_} = mk_case_fail"blunder"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   240
   | mk{path as u::rstp, rows as ((prfx, []), rhs)::rst} =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   241
        mk{path = path,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   242
           rows = ((prfx, [fresh_var(type_of u)]), rhs)::rst}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   243
   | mk{path = u::rstp, rows as ((_, p::_), _)::_} =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   244
     let val (pat_rectangle,rights) = ListPair.unzip rows
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   245
         val col0 = map(hd o #2) pat_rectangle
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   246
     in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   247
     if (forall is_Free col0)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   248
     then let val rights' = map (fn(v,e) => pattern_subst[(v,u)] e)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   249
                                (ListPair.zip (col0, rights))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   250
              val pat_rectangle' = map v_to_prfx pat_rectangle
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   251
              val (pref_patl,tm) = mk{path = rstp,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   252
                                      rows = ListPair.zip (pat_rectangle',
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   253
                                                           rights')}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   254
          in (map v_to_pats pref_patl, tm)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   255
          end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   256
     else
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   257
     let val pty as Type (ty_name,_) = type_of p
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   258
     in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   259
     case (ty_info ty_name)
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14820
diff changeset
   260
     of NONE => mk_case_fail("Not a known datatype: "^ty_name)
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14820
diff changeset
   261
      | SOME{case_const,constructors} =>
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   262
        let
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   263
            val case_const_name = #1(dest_Const case_const)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   264
            val nrows = List.concat (map (expand constructors pty) rows)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   265
            val subproblems = divide(constructors, pty, range_ty, nrows)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   266
            val groups      = map #group subproblems
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   267
            and new_formals = map #new_formals subproblems
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   268
            and constructors' = map #constructor subproblems
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   269
            val news = map (fn (nf,rows) => {path = nf@rstp, rows=rows})
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   270
                           (ListPair.zip (new_formals, groups))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   271
            val rec_calls = map mk news
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   272
            val (pat_rect,dtrees) = ListPair.unzip rec_calls
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   273
            val case_functions = map S.list_mk_abs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   274
                                  (ListPair.zip (new_formals, dtrees))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   275
            val types = map type_of (case_functions@[u]) @ [range_ty]
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   276
            val case_const' = Const(case_const_name, list_mk_type types)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   277
            val tree = list_comb(case_const', case_functions@[u])
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   278
            val pat_rect1 = List.concat
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   279
                              (ListPair.map mk_pat (constructors', pat_rect))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   280
        in (pat_rect1,tree)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   281
        end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   282
     end end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   283
 in mk
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   284
 end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   285
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   286
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   287
(* Repeated variable occurrences in a pattern are not allowed. *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   288
fun FV_multiset tm =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   289
   case (S.dest_term tm)
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   290
     of S.VAR{Name = c, Ty = T} => [Free(c, T)]
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   291
      | S.CONST _ => []
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   292
      | S.COMB{Rator, Rand} => FV_multiset Rator @ FV_multiset Rand
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   293
      | S.LAMB _ => raise TFL_ERR "FV_multiset" "lambda";
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   294
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   295
fun no_repeat_vars thy pat =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   296
 let fun check [] = true
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   297
       | check (v::rst) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   298
         if mem_term (v,rst) then
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   299
            raise TFL_ERR "no_repeat_vars"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   300
                          (quote (#1 (dest_Free v)) ^
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   301
                          " occurs repeatedly in the pattern " ^
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   302
                          quote (string_of_cterm (Thry.typecheck thy pat)))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   303
         else check rst
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   304
 in check (FV_multiset pat)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   305
 end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   306
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   307
fun dest_atom (Free p) = p
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   308
  | dest_atom (Const p) = p
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   309
  | dest_atom  _ = raise TFL_ERR "dest_atom" "function name not an identifier";
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   310
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   311
fun same_name (p,q) = #1(dest_atom p) = #1(dest_atom q);
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   312
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   313
local fun mk_functional_err s = raise TFL_ERR "mk_functional" s
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   314
      fun single [_$_] =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   315
              mk_functional_err "recdef does not allow currying"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   316
        | single [f] = f
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   317
        | single fs  =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   318
              (*multiple function names?*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   319
              if length (gen_distinct same_name fs) < length fs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   320
              then mk_functional_err
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   321
                   "The function being declared appears with multiple types"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   322
              else mk_functional_err
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   323
                   (Int.toString (length fs) ^
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   324
                    " distinct function names being declared")
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   325
in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   326
fun mk_functional thy clauses =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   327
 let val (L,R) = ListPair.unzip (map HOLogic.dest_eq clauses
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   328
                   handle TERM _ => raise TFL_ERR "mk_functional"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   329
                        "recursion equations must use the = relation")
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   330
     val (funcs,pats) = ListPair.unzip (map (fn (t$u) =>(t,u)) L)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   331
     val atom = single (gen_distinct (op aconv) funcs)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   332
     val (fname,ftype) = dest_atom atom
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   333
     val dummy = map (no_repeat_vars thy) pats
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   334
     val rows = ListPair.zip (map (fn x => ([]:term list,[x])) pats,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   335
                              map (fn (t,i) => (t,(i,true))) (enumerate R))
15574
b1d1b5bfc464 Removed practically all references to Library.foldr.
skalberg
parents: 15570
diff changeset
   336
     val names = foldr add_term_names [] R
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   337
     val atype = type_of(hd pats)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   338
     and aname = variant names "a"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   339
     val a = Free(aname,atype)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   340
     val ty_info = Thry.match_info thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   341
     val ty_match = Thry.match_type thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   342
     val range_ty = type_of (hd R)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   343
     val (patts, case_tm) = mk_case ty_info ty_match (aname::names) range_ty
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   344
                                    {path=[a], rows=rows}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   345
     val patts1 = map (fn (_,tag,[pat]) => (pat,tag)) patts
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   346
          handle Match => mk_functional_err "error in pattern-match translation"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   347
     val patts2 = Library.sort (Library.int_ord o Library.pairself row_of_pat) patts1
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   348
     val finals = map row_of_pat patts2
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   349
     val originals = map (row_of_pat o #2) rows
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   350
     val dummy = case (originals\\finals)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   351
             of [] => ()
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   352
          | L => mk_functional_err
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   353
 ("The following clauses are redundant (covered by preceding clauses): " ^
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   354
                   commas (map (fn i => Int.toString (i + 1)) L))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   355
 in {functional = Abs(Sign.base_name fname, ftype,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   356
                      abstract_over (atom,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   357
                                     absfree(aname,atype, case_tm))),
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   358
     pats = patts2}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   359
end end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   360
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   361
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   362
(*----------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   363
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   364
 *                    PRINCIPLES OF DEFINITION
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   365
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   366
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   367
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   368
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   369
(*For Isabelle, the lhs of a definition must be a constant.*)
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   370
fun mk_const_def sign (c, Ty, rhs) =
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14820
diff changeset
   371
    Sign.infer_types (Sign.pp sign) sign (K NONE) (K NONE) [] false
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   372
               ([Const("==",dummyT) $ Const(c,Ty) $ rhs], propT)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   373
    |> #1;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   374
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   375
(*Make all TVars available for instantiation by adding a ? to the front*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   376
fun poly_tvars (Type(a,Ts)) = Type(a, map (poly_tvars) Ts)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   377
  | poly_tvars (TFree (a,sort)) = TVar (("?" ^ a, 0), sort)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   378
  | poly_tvars (TVar ((a,i),sort)) = TVar (("?" ^ a, i+1), sort);
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   379
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   380
local val f_eq_wfrec_R_M =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   381
           #ant(S.dest_imp(#2(S.strip_forall (concl Thms.WFREC_COROLLARY))))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   382
      val {lhs=f, rhs} = S.dest_eq f_eq_wfrec_R_M
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   383
      val (fname,_) = dest_Free f
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   384
      val (wfrec,_) = S.strip_comb rhs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   385
in
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   386
fun wfrec_definition0 thy fid R (functional as Abs(x, Ty, _)) =
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   387
 let val def_name = if x<>fid then
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   388
                        raise TFL_ERR "wfrec_definition0"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   389
                                      ("Expected a definition of " ^
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   390
                                             quote fid ^ " but found one of " ^
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   391
                                      quote x)
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   392
                    else x ^ "_def"
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   393
     val wfrec_R_M =  map_term_types poly_tvars
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   394
                          (wfrec $ map_term_types poly_tvars R)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   395
                      $ functional
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   396
     val def_term = mk_const_def (Theory.sign_of thy) (x, Ty, wfrec_R_M)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   397
     val (thy', [def]) = PureThy.add_defs_i false [Thm.no_attributes (def_name, def_term)] thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   398
 in (thy', def) end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   399
end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   400
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   401
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   402
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   403
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   404
 * This structure keeps track of congruence rules that aren't derived
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   405
 * from a datatype definition.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   406
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   407
fun extraction_thms thy =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   408
 let val {case_rewrites,case_congs} = Thry.extract_info thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   409
 in (case_rewrites, case_congs)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   410
 end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   411
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   412
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   413
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   414
 * Pair patterns with termination conditions. The full list of patterns for
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   415
 * a definition is merged with the TCs arising from the user-given clauses.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   416
 * There can be fewer clauses than the full list, if the user omitted some
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   417
 * cases. This routine is used to prepare input for mk_induction.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   418
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   419
fun merge full_pats TCs =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   420
let fun insert (p,TCs) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   421
      let fun insrt ((x as (h,[]))::rst) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   422
                 if (p aconv h) then (p,TCs)::rst else x::insrt rst
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   423
            | insrt (x::rst) = x::insrt rst
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   424
            | insrt[] = raise TFL_ERR "merge.insert" "pattern not found"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   425
      in insrt end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   426
    fun pass ([],ptcl_final) = ptcl_final
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   427
      | pass (ptcs::tcl, ptcl) = pass(tcl, insert ptcs ptcl)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   428
in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   429
  pass (TCs, map (fn p => (p,[])) full_pats)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   430
end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   431
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   432
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   433
fun givens pats = map pat_of (List.filter given pats);
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   434
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   435
fun post_definition meta_tflCongs (theory, (def, pats)) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   436
 let val tych = Thry.typecheck theory
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   437
     val f = #lhs(S.dest_eq(concl def))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   438
     val corollary = R.MATCH_MP Thms.WFREC_COROLLARY def
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   439
     val pats' = List.filter given pats
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   440
     val given_pats = map pat_of pats'
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   441
     val rows = map row_of_pat pats'
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   442
     val WFR = #ant(S.dest_imp(concl corollary))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   443
     val R = #Rand(S.dest_comb WFR)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   444
     val corollary' = R.UNDISCH corollary  (* put WF R on assums *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   445
     val corollaries = map (fn pat => R.SPEC (tych pat) corollary')
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   446
                           given_pats
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   447
     val (case_rewrites,context_congs) = extraction_thms theory
14219
9fdea25f9ebb added a comment
paulson
parents: 14217
diff changeset
   448
     (*case_ss causes minimal simplification: bodies of case expressions are
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   449
       not simplified. Otherwise large examples (Red-Black trees) are too
14219
9fdea25f9ebb added a comment
paulson
parents: 14217
diff changeset
   450
       slow.*)
14217
9f5679e97eac Fixed inefficiency in post_definition by adding weak case congruence
berghofe
parents: 12902
diff changeset
   451
     val case_ss = HOL_basic_ss addcongs
9f5679e97eac Fixed inefficiency in post_definition by adding weak case congruence
berghofe
parents: 12902
diff changeset
   452
       DatatypePackage.weak_case_congs_of theory addsimps case_rewrites
9f5679e97eac Fixed inefficiency in post_definition by adding weak case congruence
berghofe
parents: 12902
diff changeset
   453
     val corollaries' = map (Simplifier.simplify case_ss) corollaries
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   454
     val extract = R.CONTEXT_REWRITE_RULE
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   455
                     (f, [R], cut_apply, meta_tflCongs@context_congs)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   456
     val (rules, TCs) = ListPair.unzip (map extract corollaries')
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   457
     val rules0 = map (rewrite_rule [Thms.CUT_DEF]) rules
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   458
     val mk_cond_rule = R.FILTER_DISCH_ALL(not o curry (op aconv) WFR)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   459
     val rules1 = R.LIST_CONJ(map mk_cond_rule rules0)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   460
 in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   461
 {theory = theory,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   462
  rules = rules1,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   463
  rows = rows,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   464
  full_pats_TCs = merge (map pat_of pats) (ListPair.zip (given_pats, TCs)),
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   465
  TCs = TCs}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   466
 end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   467
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   468
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   469
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   470
 * Perform the extraction without making the definition. Definition and
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   471
 * extraction commute for the non-nested case.  (Deferred recdefs)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   472
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   473
 * The purpose of wfrec_eqns is merely to instantiate the recursion theorem
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   474
 * and extract termination conditions: no definition is made.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   475
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   476
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   477
fun wfrec_eqns thy fid tflCongs eqns =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   478
 let val {lhs,rhs} = S.dest_eq (hd eqns)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   479
     val (f,args) = S.strip_comb lhs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   480
     val (fname,fty) = dest_atom f
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   481
     val (SV,a) = front_last args    (* SV = schematic variables *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   482
     val g = list_comb(f,SV)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   483
     val h = Free(fname,type_of g)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   484
     val eqns1 = map (subst_free[(g,h)]) eqns
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   485
     val {functional as Abs(x, Ty, _),  pats} = mk_functional thy eqns1
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   486
     val given_pats = givens pats
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   487
     (* val f = Free(x,Ty) *)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   488
     val Type("fun", [f_dty, f_rty]) = Ty
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   489
     val dummy = if x<>fid then
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   490
                        raise TFL_ERR "wfrec_eqns"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   491
                                      ("Expected a definition of " ^
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   492
                                      quote fid ^ " but found one of " ^
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   493
                                      quote x)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   494
                 else ()
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   495
     val (case_rewrites,context_congs) = extraction_thms thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   496
     val tych = Thry.typecheck thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   497
     val WFREC_THM0 = R.ISPEC (tych functional) Thms.WFREC_COROLLARY
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   498
     val Const("All",_) $ Abs(Rname,Rtype,_) = concl WFREC_THM0
15574
b1d1b5bfc464 Removed practically all references to Library.foldr.
skalberg
parents: 15570
diff changeset
   499
     val R = Free (variant (foldr add_term_names [] eqns) Rname,
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   500
                   Rtype)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   501
     val WFREC_THM = R.ISPECL [tych R, tych g] WFREC_THM0
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   502
     val ([proto_def, WFR],_) = S.strip_imp(concl WFREC_THM)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   503
     val dummy =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   504
           if !trace then
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   505
               writeln ("ORIGINAL PROTO_DEF: " ^
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   506
                          Sign.string_of_term (Theory.sign_of thy) proto_def)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   507
           else ()
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   508
     val R1 = S.rand WFR
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   509
     val corollary' = R.UNDISCH(R.UNDISCH WFREC_THM)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   510
     val corollaries = map (fn pat => R.SPEC (tych pat) corollary') given_pats
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   511
     val corollaries' = map (rewrite_rule case_rewrites) corollaries
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   512
     fun extract X = R.CONTEXT_REWRITE_RULE
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   513
                       (f, R1::SV, cut_apply, tflCongs@context_congs) X
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   514
 in {proto_def = proto_def,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   515
     SV=SV,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   516
     WFR=WFR,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   517
     pats=pats,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   518
     extracta = map extract corollaries'}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   519
 end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   520
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   521
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   522
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   523
 * Define the constant after extracting the termination conditions. The
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   524
 * wellfounded relation used in the definition is computed by using the
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   525
 * choice operator on the extracted conditions (plus the condition that
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   526
 * such a relation must be wellfounded).
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   527
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   528
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   529
fun lazyR_def thy fid tflCongs eqns =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   530
 let val {proto_def,WFR,pats,extracta,SV} =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   531
           wfrec_eqns thy fid tflCongs eqns
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   532
     val R1 = S.rand WFR
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   533
     val f = #lhs(S.dest_eq proto_def)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   534
     val (extractants,TCl) = ListPair.unzip extracta
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   535
     val dummy = if !trace
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   536
                 then (writeln "Extractants = ";
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   537
                       prths extractants;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   538
                       ())
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   539
                 else ()
15574
b1d1b5bfc464 Removed practically all references to Library.foldr.
skalberg
parents: 15570
diff changeset
   540
     val TCs = foldr (gen_union (op aconv)) [] TCl
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   541
     val full_rqt = WFR::TCs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   542
     val R' = S.mk_select{Bvar=R1, Body=S.list_mk_conj full_rqt}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   543
     val R'abs = S.rand R'
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   544
     val proto_def' = subst_free[(R1,R')] proto_def
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   545
     val dummy = if !trace then writeln ("proto_def' = " ^
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   546
                                         Sign.string_of_term
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   547
                                         (Theory.sign_of thy) proto_def')
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   548
                           else ()
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   549
     val {lhs,rhs} = S.dest_eq proto_def'
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   550
     val (c,args) = S.strip_comb lhs
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   551
     val (name,Ty) = dest_atom c
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   552
     val defn = mk_const_def (Theory.sign_of thy)
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   553
                 (name, Ty, S.list_mk_abs (args,rhs))
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   554
     val (theory, [def0]) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   555
       thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   556
       |> PureThy.add_defs_i false
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   557
            [Thm.no_attributes (fid ^ "_def", defn)]
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   558
     val def = freezeT def0;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   559
     val dummy = if !trace then writeln ("DEF = " ^ string_of_thm def)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   560
                           else ()
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   561
     (* val fconst = #lhs(S.dest_eq(concl def))  *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   562
     val tych = Thry.typecheck theory
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   563
     val full_rqt_prop = map (Dcterm.mk_prop o tych) full_rqt
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   564
         (*lcp: a lot of object-logic inference to remove*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   565
     val baz = R.DISCH_ALL
16853
33b886cbdc8f replaced itlist by fold_rev;
wenzelm
parents: 16505
diff changeset
   566
                 (fold_rev R.DISCH full_rqt_prop
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   567
                  (R.LIST_CONJ extractants))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   568
     val dum = if !trace then writeln ("baz = " ^ string_of_thm baz)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   569
                           else ()
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   570
     val f_free = Free (fid, fastype_of f)  (*'cos f is a Const*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   571
     val SV' = map tych SV;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   572
     val SVrefls = map reflexive SV'
16853
33b886cbdc8f replaced itlist by fold_rev;
wenzelm
parents: 16505
diff changeset
   573
     val def0 = (fold (fn x => fn th => R.rbeta(combination th x))
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   574
                   SVrefls def)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   575
                RS meta_eq_to_obj_eq
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   576
     val def' = R.MP (R.SPEC (tych R') (R.GEN (tych R1) baz)) def0
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   577
     val body_th = R.LIST_CONJ (map R.ASSUME full_rqt_prop)
11455
e07927b980ec defer_recdef (lazyR_def) now looks for theorem Hilbert_Choice.tfl_some
paulson
parents: 10769
diff changeset
   578
     val SELECT_AX = (*in this way we hope to avoid a STATIC dependence upon
e07927b980ec defer_recdef (lazyR_def) now looks for theorem Hilbert_Choice.tfl_some
paulson
parents: 10769
diff changeset
   579
                       theory Hilbert_Choice*)
16505
c4b2e3cd84ab avoid identifier 'Name';
wenzelm
parents: 15574
diff changeset
   580
         thm "Hilbert_Choice.tfl_some"
11455
e07927b980ec defer_recdef (lazyR_def) now looks for theorem Hilbert_Choice.tfl_some
paulson
parents: 10769
diff changeset
   581
         handle ERROR => error
e07927b980ec defer_recdef (lazyR_def) now looks for theorem Hilbert_Choice.tfl_some
paulson
parents: 10769
diff changeset
   582
    "defer_recdef requires theory Main or at least Hilbert_Choice as parent"
e07927b980ec defer_recdef (lazyR_def) now looks for theorem Hilbert_Choice.tfl_some
paulson
parents: 10769
diff changeset
   583
     val bar = R.MP (R.ISPECL[tych R'abs, tych R1] SELECT_AX) body_th
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   584
 in {theory = theory, R=R1, SV=SV,
16853
33b886cbdc8f replaced itlist by fold_rev;
wenzelm
parents: 16505
diff changeset
   585
     rules = fold (U.C R.MP) (R.CONJUNCTS bar) def',
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   586
     full_pats_TCs = merge (map pat_of pats) (ListPair.zip (givens pats, TCl)),
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   587
     patterns = pats}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   588
 end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   589
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   590
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   591
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   592
(*----------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   593
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   594
 *                           INDUCTION THEOREM
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   595
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   596
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   597
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   598
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   599
(*------------------------  Miscellaneous function  --------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   600
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   601
 *           [x_1,...,x_n]     ?v_1...v_n. M[v_1,...,v_n]
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   602
 *     -----------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   603
 *     ( M[x_1,...,x_n], [(x_i,?v_1...v_n. M[v_1,...,v_n]),
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   604
 *                        ...
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   605
 *                        (x_j,?v_n. M[x_1,...,x_(n-1),v_n])] )
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   606
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   607
 * This function is totally ad hoc. Used in the production of the induction
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   608
 * theorem. The nchotomy theorem can have clauses that look like
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   609
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   610
 *     ?v1..vn. z = C vn..v1
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   611
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   612
 * in which the order of quantification is not the order of occurrence of the
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   613
 * quantified variables as arguments to C. Since we have no control over this
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   614
 * aspect of the nchotomy theorem, we make the correspondence explicit by
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   615
 * pairing the incoming new variable with the term it gets beta-reduced into.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   616
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   617
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   618
fun alpha_ex_unroll (xlist, tm) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   619
  let val (qvars,body) = S.strip_exists tm
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   620
      val vlist = #2(S.strip_comb (S.rhs body))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   621
      val plist = ListPair.zip (vlist, xlist)
17314
04e21a27c0ad introduces some modern-style AList operations
haftmann
parents: 16853
diff changeset
   622
      val args = map (the o AList.lookup (op aconv) plist) qvars
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14820
diff changeset
   623
                   handle Option => sys_error
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   624
                       "TFL fault [alpha_ex_unroll]: no correspondence"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   625
      fun build ex      []   = []
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   626
        | build (_$rex) (v::rst) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   627
           let val ex1 = betapply(rex, v)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   628
           in  ex1 :: build ex1 rst
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   629
           end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   630
     val (nex::exl) = rev (tm::build tm args)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   631
  in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   632
  (nex, ListPair.zip (args, rev exl))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   633
  end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   634
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   635
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   636
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   637
(*----------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   638
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   639
 *             PROVING COMPLETENESS OF PATTERNS
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   640
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   641
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   642
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   643
fun mk_case ty_info usednames thy =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   644
 let
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   645
 val divide = ipartition (gvvariant usednames)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   646
 val tych = Thry.typecheck thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   647
 fun tych_binding(x,y) = (tych x, tych y)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   648
 fun fail s = raise TFL_ERR "mk_case" s
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   649
 fun mk{rows=[],...} = fail"no rows"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   650
   | mk{path=[], rows = [([], (thm, bindings))]} =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   651
                         R.IT_EXISTS (map tych_binding bindings) thm
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   652
   | mk{path = u::rstp, rows as (p::_, _)::_} =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   653
     let val (pat_rectangle,rights) = ListPair.unzip rows
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   654
         val col0 = map hd pat_rectangle
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   655
         val pat_rectangle' = map tl pat_rectangle
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   656
     in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   657
     if (forall is_Free col0) (* column 0 is all variables *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   658
     then let val rights' = map (fn ((thm,theta),v) => (thm,theta@[(u,v)]))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   659
                                (ListPair.zip (rights, col0))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   660
          in mk{path = rstp, rows = ListPair.zip (pat_rectangle', rights')}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   661
          end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   662
     else                     (* column 0 is all constructors *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   663
     let val Type (ty_name,_) = type_of p
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   664
     in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   665
     case (ty_info ty_name)
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14820
diff changeset
   666
     of NONE => fail("Not a known datatype: "^ty_name)
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14820
diff changeset
   667
      | SOME{constructors,nchotomy} =>
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   668
        let val thm' = R.ISPEC (tych u) nchotomy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   669
            val disjuncts = S.strip_disj (concl thm')
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   670
            val subproblems = divide(constructors, rows)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   671
            val groups      = map #group subproblems
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   672
            and new_formals = map #new_formals subproblems
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   673
            val existentials = ListPair.map alpha_ex_unroll
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   674
                                   (new_formals, disjuncts)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   675
            val constraints = map #1 existentials
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   676
            val vexl = map #2 existentials
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   677
            fun expnd tm (pats,(th,b)) = (pats,(R.SUBS[R.ASSUME(tych tm)]th,b))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   678
            val news = map (fn (nf,rows,c) => {path = nf@rstp,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   679
                                               rows = map (expnd c) rows})
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   680
                           (U.zip3 new_formals groups constraints)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   681
            val recursive_thms = map mk news
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   682
            val build_exists = Library.foldr
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   683
                                (fn((x,t), th) =>
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   684
                                 R.CHOOSE (tych x, R.ASSUME (tych t)) th)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   685
            val thms' = ListPair.map build_exists (vexl, recursive_thms)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   686
            val same_concls = R.EVEN_ORS thms'
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   687
        in R.DISJ_CASESL thm' same_concls
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   688
        end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   689
     end end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   690
 in mk
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   691
 end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   692
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   693
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   694
fun complete_cases thy =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   695
 let val tych = Thry.typecheck thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   696
     val ty_info = Thry.induct_info thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   697
 in fn pats =>
15574
b1d1b5bfc464 Removed practically all references to Library.foldr.
skalberg
parents: 15570
diff changeset
   698
 let val names = foldr add_term_names [] pats
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   699
     val T = type_of (hd pats)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   700
     val aname = Term.variant names "a"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   701
     val vname = Term.variant (aname::names) "v"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   702
     val a = Free (aname, T)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   703
     val v = Free (vname, T)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   704
     val a_eq_v = HOLogic.mk_eq(a,v)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   705
     val ex_th0 = R.EXISTS (tych (S.mk_exists{Bvar=v,Body=a_eq_v}), tych a)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   706
                           (R.REFL (tych a))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   707
     val th0 = R.ASSUME (tych a_eq_v)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   708
     val rows = map (fn x => ([x], (th0,[]))) pats
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   709
 in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   710
 R.GEN (tych a)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   711
       (R.RIGHT_ASSOC
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   712
          (R.CHOOSE(tych v, ex_th0)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   713
                (mk_case ty_info (vname::aname::names)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   714
                 thy {path=[v], rows=rows})))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   715
 end end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   716
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   717
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   718
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   719
 * Constructing induction hypotheses: one for each recursive call.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   720
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   721
 * Note. R will never occur as a variable in the ind_clause, because
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   722
 * to do so, it would have to be from a nested definition, and we don't
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   723
 * allow nested defns to have R variable.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   724
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   725
 * Note. When the context is empty, there can be no local variables.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   726
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   727
(*
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   728
local infix 5 ==>
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   729
      fun (tm1 ==> tm2) = S.mk_imp{ant = tm1, conseq = tm2}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   730
in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   731
fun build_ih f P (pat,TCs) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   732
 let val globals = S.free_vars_lr pat
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   733
     fun nested tm = isSome (S.find_term (curry (op aconv) f) tm)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   734
     fun dest_TC tm =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   735
         let val (cntxt,R_y_pat) = S.strip_imp(#2(S.strip_forall tm))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   736
             val (R,y,_) = S.dest_relation R_y_pat
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   737
             val P_y = if (nested tm) then R_y_pat ==> P$y else P$y
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   738
         in case cntxt
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   739
              of [] => (P_y, (tm,[]))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   740
               | _  => let
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   741
                    val imp = S.list_mk_conj cntxt ==> P_y
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   742
                    val lvs = gen_rems (op aconv) (S.free_vars_lr imp, globals)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   743
                    val locals = #2(U.pluck (curry (op aconv) P) lvs) handle U.ERR _ => lvs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   744
                    in (S.list_mk_forall(locals,imp), (tm,locals)) end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   745
         end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   746
 in case TCs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   747
    of [] => (S.list_mk_forall(globals, P$pat), [])
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   748
     |  _ => let val (ihs, TCs_locals) = ListPair.unzip(map dest_TC TCs)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   749
                 val ind_clause = S.list_mk_conj ihs ==> P$pat
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   750
             in (S.list_mk_forall(globals,ind_clause), TCs_locals)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   751
             end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   752
 end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   753
end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   754
*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   755
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   756
local infix 5 ==>
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   757
      fun (tm1 ==> tm2) = S.mk_imp{ant = tm1, conseq = tm2}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   758
in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   759
fun build_ih f (P,SV) (pat,TCs) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   760
 let val pat_vars = S.free_vars_lr pat
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   761
     val globals = pat_vars@SV
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   762
     fun nested tm = isSome (S.find_term (curry (op aconv) f) tm)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   763
     fun dest_TC tm =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   764
         let val (cntxt,R_y_pat) = S.strip_imp(#2(S.strip_forall tm))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   765
             val (R,y,_) = S.dest_relation R_y_pat
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   766
             val P_y = if (nested tm) then R_y_pat ==> P$y else P$y
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   767
         in case cntxt
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   768
              of [] => (P_y, (tm,[]))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   769
               | _  => let
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   770
                    val imp = S.list_mk_conj cntxt ==> P_y
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   771
                    val lvs = gen_rems (op aconv) (S.free_vars_lr imp, globals)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   772
                    val locals = #2(U.pluck (curry (op aconv) P) lvs) handle U.ERR _ => lvs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   773
                    in (S.list_mk_forall(locals,imp), (tm,locals)) end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   774
         end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   775
 in case TCs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   776
    of [] => (S.list_mk_forall(pat_vars, P$pat), [])
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   777
     |  _ => let val (ihs, TCs_locals) = ListPair.unzip(map dest_TC TCs)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   778
                 val ind_clause = S.list_mk_conj ihs ==> P$pat
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   779
             in (S.list_mk_forall(pat_vars,ind_clause), TCs_locals)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   780
             end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   781
 end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   782
end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   783
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   784
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   785
 * This function makes good on the promise made in "build_ih".
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   786
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   787
 * Input  is tm = "(!y. R y pat ==> P y) ==> P pat",
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   788
 *           TCs = TC_1[pat] ... TC_n[pat]
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   789
 *           thm = ih1 /\ ... /\ ih_n |- ih[pat]
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   790
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   791
fun prove_case f thy (tm,TCs_locals,thm) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   792
 let val tych = Thry.typecheck thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   793
     val antc = tych(#ant(S.dest_imp tm))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   794
     val thm' = R.SPEC_ALL thm
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   795
     fun nested tm = isSome (S.find_term (curry (op aconv) f) tm)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   796
     fun get_cntxt TC = tych(#ant(S.dest_imp(#2(S.strip_forall(concl TC)))))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   797
     fun mk_ih ((TC,locals),th2,nested) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   798
         R.GENL (map tych locals)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   799
            (if nested then R.DISCH (get_cntxt TC) th2 handle U.ERR _ => th2
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   800
             else if S.is_imp (concl TC) then R.IMP_TRANS TC th2
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   801
             else R.MP th2 TC)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   802
 in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   803
 R.DISCH antc
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   804
 (if S.is_imp(concl thm') (* recursive calls in this clause *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   805
  then let val th1 = R.ASSUME antc
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   806
           val TCs = map #1 TCs_locals
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   807
           val ylist = map (#2 o S.dest_relation o #2 o S.strip_imp o
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   808
                            #2 o S.strip_forall) TCs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   809
           val TClist = map (fn(TC,lvs) => (R.SPEC_ALL(R.ASSUME(tych TC)),lvs))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   810
                            TCs_locals
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   811
           val th2list = map (U.C R.SPEC th1 o tych) ylist
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   812
           val nlist = map nested TCs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   813
           val triples = U.zip3 TClist th2list nlist
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   814
           val Pylist = map mk_ih triples
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   815
       in R.MP thm' (R.LIST_CONJ Pylist) end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   816
  else thm')
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   817
 end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   818
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   819
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   820
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   821
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   822
 *         x = (v1,...,vn)  |- M[x]
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   823
 *    ---------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   824
 *      ?v1 ... vn. x = (v1,...,vn) |- M[x]
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   825
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   826
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   827
fun LEFT_ABS_VSTRUCT tych thm =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   828
  let fun CHOOSER v (tm,thm) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   829
        let val ex_tm = S.mk_exists{Bvar=v,Body=tm}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   830
        in (ex_tm, R.CHOOSE(tych v, R.ASSUME (tych ex_tm)) thm)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   831
        end
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   832
      val [veq] = List.filter (can S.dest_eq) (#1 (R.dest_thm thm))
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   833
      val {lhs,rhs} = S.dest_eq veq
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   834
      val L = S.free_vars_lr rhs
16853
33b886cbdc8f replaced itlist by fold_rev;
wenzelm
parents: 16505
diff changeset
   835
  in  #2 (fold_rev CHOOSER L (veq,thm))  end;
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   836
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   837
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   838
(*----------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   839
 * Input : f, R,  and  [(pat1,TCs1),..., (patn,TCsn)]
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   840
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   841
 * Instantiates WF_INDUCTION_THM, getting Sinduct and then tries to prove
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   842
 * recursion induction (Rinduct) by proving the antecedent of Sinduct from
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   843
 * the antecedent of Rinduct.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   844
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   845
fun mk_induction thy {fconst, R, SV, pat_TCs_list} =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   846
let val tych = Thry.typecheck thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   847
    val Sinduction = R.UNDISCH (R.ISPEC (tych R) Thms.WF_INDUCTION_THM)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   848
    val (pats,TCsl) = ListPair.unzip pat_TCs_list
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   849
    val case_thm = complete_cases thy pats
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   850
    val domain = (type_of o hd) pats
15574
b1d1b5bfc464 Removed practically all references to Library.foldr.
skalberg
parents: 15570
diff changeset
   851
    val Pname = Term.variant (foldr (Library.foldr add_term_names)
b1d1b5bfc464 Removed practically all references to Library.foldr.
skalberg
parents: 15570
diff changeset
   852
                              [] (pats::TCsl)) "P"
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   853
    val P = Free(Pname, domain --> HOLogic.boolT)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   854
    val Sinduct = R.SPEC (tych P) Sinduction
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   855
    val Sinduct_assumf = S.rand ((#ant o S.dest_imp o concl) Sinduct)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   856
    val Rassums_TCl' = map (build_ih fconst (P,SV)) pat_TCs_list
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   857
    val (Rassums,TCl') = ListPair.unzip Rassums_TCl'
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   858
    val Rinduct_assum = R.ASSUME (tych (S.list_mk_conj Rassums))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   859
    val cases = map (fn pat => betapply (Sinduct_assumf, pat)) pats
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   860
    val tasks = U.zip3 cases TCl' (R.CONJUNCTS Rinduct_assum)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   861
    val proved_cases = map (prove_case fconst thy) tasks
15574
b1d1b5bfc464 Removed practically all references to Library.foldr.
skalberg
parents: 15570
diff changeset
   862
    val v = Free (variant (foldr add_term_names [] (map concl proved_cases))
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   863
                    "v",
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   864
                  domain)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   865
    val vtyped = tych v
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   866
    val substs = map (R.SYM o R.ASSUME o tych o (curry HOLogic.mk_eq v)) pats
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   867
    val proved_cases1 = ListPair.map (fn (th,th') => R.SUBS[th]th')
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   868
                          (substs, proved_cases)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   869
    val abs_cases = map (LEFT_ABS_VSTRUCT tych) proved_cases1
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   870
    val dant = R.GEN vtyped (R.DISJ_CASESL (R.ISPEC vtyped case_thm) abs_cases)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   871
    val dc = R.MP Sinduct dant
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   872
    val Parg_ty = type_of(#Bvar(S.dest_forall(concl dc)))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   873
    val vars = map (gvvariant[Pname]) (S.strip_prod_type Parg_ty)
16853
33b886cbdc8f replaced itlist by fold_rev;
wenzelm
parents: 16505
diff changeset
   874
    val dc' = fold_rev (R.GEN o tych) vars
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   875
                       (R.SPEC (tych(S.mk_vstruct Parg_ty vars)) dc)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   876
in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   877
   R.GEN (tych P) (R.DISCH (tych(concl Rinduct_assum)) dc')
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   878
end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   879
handle U.ERR _ => raise TFL_ERR "mk_induction" "failed derivation";
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   880
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   881
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   882
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   883
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   884
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   885
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   886
 *                        POST PROCESSING
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   887
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   888
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   889
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   890
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   891
fun simplify_induction thy hth ind =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   892
  let val tych = Thry.typecheck thy
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   893
      val (asl,_) = R.dest_thm ind
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   894
      val (_,tc_eq_tc') = R.dest_thm hth
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   895
      val tc = S.lhs tc_eq_tc'
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   896
      fun loop [] = ind
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   897
        | loop (asm::rst) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   898
          if (can (Thry.match_term thy asm) tc)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   899
          then R.UNDISCH
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   900
                 (R.MATCH_MP
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   901
                     (R.MATCH_MP Thms.simp_thm (R.DISCH (tych asm) ind))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   902
                     hth)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   903
         else loop rst
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   904
  in loop asl
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   905
end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   906
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   907
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   908
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   909
 * The termination condition is an antecedent to the rule, and an
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   910
 * assumption to the theorem.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   911
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   912
fun elim_tc tcthm (rule,induction) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   913
   (R.MP rule tcthm, R.PROVE_HYP tcthm induction)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   914
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   915
14240
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
   916
fun trace_thms s L =
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
   917
  if !trace then writeln (cat_lines (s :: map string_of_thm L))
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
   918
  else ();
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
   919
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
   920
fun trace_cterms s L =
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
   921
  if !trace then writeln (cat_lines (s :: map string_of_cterm L))
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
   922
  else ();;
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
   923
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
   924
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11455
diff changeset
   925
fun postprocess strict {wf_tac, terminator, simplifier} theory {rules,induction,TCs} =
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   926
let val tych = Thry.typecheck theory
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11455
diff changeset
   927
    val prove = R.prove strict;
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   928
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   929
   (*---------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   930
    * Attempt to eliminate WF condition. It's the only assumption of rules
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   931
    *---------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   932
   val (rules1,induction1)  =
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11455
diff changeset
   933
       let val thm = prove(tych(HOLogic.mk_Trueprop
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   934
                                  (hd(#1(R.dest_thm rules)))),
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   935
                             wf_tac)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   936
       in (R.PROVE_HYP thm rules,  R.PROVE_HYP thm induction)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   937
       end handle U.ERR _ => (rules,induction);
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   938
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   939
   (*----------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   940
    * The termination condition (tc) is simplified to |- tc = tc' (there
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   941
    * might not be a change!) and then 3 attempts are made:
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   942
    *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   943
    *   1. if |- tc = T, then eliminate it with eqT; otherwise,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   944
    *   2. apply the terminator to tc'. If |- tc' = T then eliminate; else
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   945
    *   3. replace tc by tc' in both the rules and the induction theorem.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   946
    *---------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   947
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   948
   fun simplify_tc tc (r,ind) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   949
       let val tc1 = tych tc
14240
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
   950
           val _ = trace_cterms "TC before simplification: " [tc1]
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   951
           val tc_eq = simplifier tc1
14240
d3843feb9de7 improved tracing
paulson
parents: 14219
diff changeset
   952
           val _ = trace_thms "result: " [tc_eq]
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   953
       in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   954
       elim_tc (R.MATCH_MP Thms.eqT tc_eq) (r,ind)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   955
       handle U.ERR _ =>
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   956
        (elim_tc (R.MATCH_MP(R.MATCH_MP Thms.rev_eq_mp tc_eq)
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11455
diff changeset
   957
                  (prove(tych(HOLogic.mk_Trueprop(S.rhs(concl tc_eq))),
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   958
                           terminator)))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   959
                 (r,ind)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   960
         handle U.ERR _ =>
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   961
          (R.UNDISCH(R.MATCH_MP (R.MATCH_MP Thms.simp_thm r) tc_eq),
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   962
           simplify_induction theory tc_eq ind))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   963
       end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   964
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   965
   (*----------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   966
    * Nested termination conditions are harder to get at, since they are
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   967
    * left embedded in the body of the function (and in induction
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   968
    * theorem hypotheses). Our "solution" is to simplify them, and try to
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   969
    * prove termination, but leave the application of the resulting theorem
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   970
    * to a higher level. So things go much as in "simplify_tc": the
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   971
    * termination condition (tc) is simplified to |- tc = tc' (there might
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   972
    * not be a change) and then 2 attempts are made:
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   973
    *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   974
    *   1. if |- tc = T, then return |- tc; otherwise,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   975
    *   2. apply the terminator to tc'. If |- tc' = T then return |- tc; else
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   976
    *   3. return |- tc = tc'
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   977
    *---------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   978
   fun simplify_nested_tc tc =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   979
      let val tc_eq = simplifier (tych (#2 (S.strip_forall tc)))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   980
      in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   981
      R.GEN_ALL
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   982
       (R.MATCH_MP Thms.eqT tc_eq
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   983
        handle U.ERR _ =>
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   984
          (R.MATCH_MP(R.MATCH_MP Thms.rev_eq_mp tc_eq)
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11455
diff changeset
   985
                      (prove(tych(HOLogic.mk_Trueprop (S.rhs(concl tc_eq))),
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   986
                               terminator))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   987
            handle U.ERR _ => tc_eq))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   988
      end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   989
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   990
   (*-------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   991
    * Attempt to simplify the termination conditions in each rule and
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   992
    * in the induction theorem.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   993
    *-------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   994
   fun strip_imp tm = if S.is_neg tm then ([],tm) else S.strip_imp tm
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   995
   fun loop ([],extras,R,ind) = (rev R, ind, extras)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   996
     | loop ((r,ftcs)::rst, nthms, R, ind) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   997
        let val tcs = #1(strip_imp (concl r))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   998
            val extra_tcs = gen_rems (op aconv) (ftcs, tcs)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   999
            val extra_tc_thms = map simplify_nested_tc extra_tcs
16853
33b886cbdc8f replaced itlist by fold_rev;
wenzelm
parents: 16505
diff changeset
  1000
            val (r1,ind1) = fold simplify_tc tcs (r,ind)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
  1001
            val r2 = R.FILTER_DISCH_ALL(not o S.is_WFR) r1
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
  1002
        in loop(rst, nthms@extra_tc_thms, r2::R, ind1)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
  1003
        end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
  1004
   val rules_tcs = ListPair.zip (R.CONJUNCTS rules1, TCs)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
  1005
   val (rules2,ind2,extras) = loop(rules_tcs,[],[],induction1)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
  1006
in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
  1007
  {induction = ind2, rules = R.LIST_CONJ rules2, nested_tcs = extras}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
  1008
end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
  1009
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
  1010
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
  1011
end;