TFL/tfl.sml
changeset 3391 5e45dd3b64e9
parent 3388 dbf61e36f8e9
child 3405 2cccd0e3e9ea
equal deleted inserted replaced
3390:0c7625196d95 3391:5e45dd3b64e9
     1 (*  Title:      TFL/tfl
     1 (*  Title:      TFL/tfl
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Konrad Slind, Cambridge University Computer Laboratory
     3     Author:     Konrad Slind, Cambridge University Computer Laboratory
     4     Copyright   1997  University of Cambridge
     4     Copyright   1997  University of Cambridge
     5 
     5 
     6 Main TFL functor
     6 Main module
     7 *)
     7 *)
     8 
     8 
     9 functor TFL(structure Rules : Rules_sig
     9 structure Prim : TFL_sig =
    10             structure Thry  : Thry_sig
       
    11             structure Thms  : Thms_sig) : TFL_sig  =
       
    12 struct
    10 struct
    13 
       
    14 (* Declarations *)
       
    15 structure Thms = Thms;
       
    16 structure Rules = Rules;
       
    17 structure Thry = Thry;
       
    18 structure USyntax = Thry.USyntax;
       
    19 
       
    20 
    11 
    21 (* Abbreviations *)
    12 (* Abbreviations *)
    22 structure R = Rules;
    13 structure R = Rules;
    23 structure S = USyntax;
    14 structure S = USyntax;
    24 structure U = S.Utils;
    15 structure U = S.Utils;
    25 
       
    26 nonfix mem -->;
       
    27 val --> = S.-->;
       
    28 
       
    29 infixr 3 -->;
       
    30 
    16 
    31 val concl = #2 o R.dest_thm;
    17 val concl = #2 o R.dest_thm;
    32 val hyp = #1 o R.dest_thm;
    18 val hyp = #1 o R.dest_thm;
    33 
    19 
    34 val list_mk_type = U.end_itlist (curry(op -->));
    20 val list_mk_type = U.end_itlist (curry(op -->));
    81   let fun pfail s = raise TFL_ERR{func = "partition.part", mesg = s}
    67   let fun pfail s = raise TFL_ERR{func = "partition.part", mesg = s}
    82       fun part {constrs = [],   rows = [],   A} = rev A
    68       fun part {constrs = [],   rows = [],   A} = rev A
    83         | part {constrs = [],   rows = _::_, A} = pfail"extra cases in defn"
    69         | part {constrs = [],   rows = _::_, A} = pfail"extra cases in defn"
    84         | part {constrs = _::_, rows = [],   A} = pfail"cases missing in defn"
    70         | part {constrs = _::_, rows = [],   A} = pfail"cases missing in defn"
    85         | part {constrs = c::crst, rows,     A} =
    71         | part {constrs = c::crst, rows,     A} =
    86           let val {Name,Ty} = S.dest_const c
    72           let val (Name,Ty) = dest_Const c
    87               val (L,_) = S.strip_type Ty
    73               val L = binder_types Ty
    88               val (in_group, not_in_group) =
    74               val (in_group, not_in_group) =
    89                U.itlist (fn (row as (p::rst, rhs)) =>
    75                U.itlist (fn (row as (p::rst, rhs)) =>
    90                          fn (in_group,not_in_group) =>
    76                          fn (in_group,not_in_group) =>
    91                   let val (pc,args) = S.strip_comb p
    77                   let val (pc,args) = S.strip_comb p
    92                   in if (#Name(S.dest_const pc) = Name)
    78                   in if (#1(dest_Const pc) = Name)
    93                      then ((args@rst, rhs)::in_group, not_in_group)
    79                      then ((args@rst, rhs)::in_group, not_in_group)
    94                      else (in_group, row::not_in_group)
    80                      else (in_group, row::not_in_group)
    95                   end)      rows ([],[])
    81                   end)      rows ([],[])
    96               val col_types = U.take type_of (length L, #1(hd in_group))
    82               val col_types = U.take type_of (length L, #1(hd in_group))
    97           in 
    83           in 
   110  * clause in a function definition.
    96  * clause in a function definition.
   111  *---------------------------------------------------------------------------*)
    97  *---------------------------------------------------------------------------*)
   112 datatype pattern = GIVEN   of term * int
    98 datatype pattern = GIVEN   of term * int
   113                  | OMITTED of term * int
    99                  | OMITTED of term * int
   114 
   100 
   115 fun psubst theta (GIVEN (tm,i)) = GIVEN(subst_free theta tm, i)
   101 fun pattern_map f (GIVEN (tm,i)) = GIVEN(f tm, i)
   116   | psubst theta (OMITTED (tm,i)) = OMITTED(subst_free theta tm, i);
   102   | pattern_map f (OMITTED (tm,i)) = OMITTED(f tm, i);
       
   103 
       
   104 fun pattern_subst theta = pattern_map (subst_free theta);
   117 
   105 
   118 fun dest_pattern (GIVEN (tm,i)) = ((GIVEN,i),tm)
   106 fun dest_pattern (GIVEN (tm,i)) = ((GIVEN,i),tm)
   119   | dest_pattern (OMITTED (tm,i)) = ((OMITTED,i),tm);
   107   | dest_pattern (OMITTED (tm,i)) = ((OMITTED,i),tm);
   120 
   108 
   121 val pat_of = #2 o dest_pattern;
   109 val pat_of = #2 o dest_pattern;
   123 
   111 
   124 (*---------------------------------------------------------------------------
   112 (*---------------------------------------------------------------------------
   125  * Produce an instance of a constructor, plus genvars for its arguments.
   113  * Produce an instance of a constructor, plus genvars for its arguments.
   126  *---------------------------------------------------------------------------*)
   114  *---------------------------------------------------------------------------*)
   127 fun fresh_constr ty_match colty gv c =
   115 fun fresh_constr ty_match colty gv c =
   128   let val {Ty,...} = S.dest_const c
   116   let val (_,Ty) = dest_Const c
   129       val (L,ty) = S.strip_type Ty
   117       val L = binder_types Ty
       
   118       and ty = body_type Ty
   130       val ty_theta = ty_match ty colty
   119       val ty_theta = ty_match ty colty
   131       val c' = S.inst ty_theta c
   120       val c' = S.inst ty_theta c
   132       val gvars = map (S.inst ty_theta o gv) L
   121       val gvars = map (S.inst ty_theta o gv) L
   133   in (c', gvars)
   122   in (c', gvars)
   134   end;
   123   end;
   140  *---------------------------------------------------------------------------*)
   129  *---------------------------------------------------------------------------*)
   141 fun mk_group Name rows =
   130 fun mk_group Name rows =
   142   U.itlist (fn (row as ((prefix, p::rst), rhs)) =>
   131   U.itlist (fn (row as ((prefix, p::rst), rhs)) =>
   143             fn (in_group,not_in_group) =>
   132             fn (in_group,not_in_group) =>
   144                let val (pc,args) = S.strip_comb p
   133                let val (pc,args) = S.strip_comb p
   145                in if ((#Name(S.dest_const pc) = Name) handle _ => false)
   134                in if ((#1(dest_Const pc) = Name) handle _ => false)
   146                   then (((prefix,args@rst), rhs)::in_group, not_in_group)
   135                   then (((prefix,args@rst), rhs)::in_group, not_in_group)
   147                   else (in_group, row::not_in_group) end)
   136                   else (in_group, row::not_in_group) end)
   148       rows ([],[]);
   137       rows ([],[]);
   149 
   138 
   150 (*---------------------------------------------------------------------------
   139 (*---------------------------------------------------------------------------
   155               (constructors, colty, res_ty, rows as (((prefix,_),_)::_)) =
   144               (constructors, colty, res_ty, rows as (((prefix,_),_)::_)) =
   156 let val fresh = fresh_constr ty_match colty gv
   145 let val fresh = fresh_constr ty_match colty gv
   157      fun part {constrs = [],      rows, A} = rev A
   146      fun part {constrs = [],      rows, A} = rev A
   158        | part {constrs = c::crst, rows, A} =
   147        | part {constrs = c::crst, rows, A} =
   159          let val (c',gvars) = fresh c
   148          let val (c',gvars) = fresh c
   160              val {Name,Ty} = S.dest_const c'
   149              val (Name,Ty) = dest_Const c'
   161              val (in_group, not_in_group) = mk_group Name rows
   150              val (in_group, not_in_group) = mk_group Name rows
   162              val in_group' =
   151              val in_group' =
   163                  if (null in_group)  (* Constructor not given *)
   152                  if (null in_group)  (* Constructor not given *)
   164                  then [((prefix, #2(fresh c)), OMITTED (S.ARB res_ty, ~1))]
   153                  then [((prefix, #2(fresh c)), OMITTED (S.ARB res_ty, ~1))]
   165                  else in_group
   154                  else in_group
   176 (*---------------------------------------------------------------------------
   165 (*---------------------------------------------------------------------------
   177  * Misc. routines used in mk_case
   166  * Misc. routines used in mk_case
   178  *---------------------------------------------------------------------------*)
   167  *---------------------------------------------------------------------------*)
   179 
   168 
   180 fun mk_pat (c,l) =
   169 fun mk_pat (c,l) =
   181   let val L = length(#1(S.strip_type(type_of c)))
   170   let val L = length (binder_types (type_of c))
   182       fun build (prefix,tag,plist) =
   171       fun build (prefix,tag,plist) =
   183           let val args   = take (L,plist)
   172           let val args   = take (L,plist)
   184               and plist' = drop(L,plist)
   173               and plist' = drop(L,plist)
   185           in (prefix,tag,list_comb(c,args)::plist') end
   174           in (prefix,tag,list_comb(c,args)::plist') end
   186   in map build l end;
   175   in map build l end;
   209    | expand constructors ty (row as ((prefix, p::rst), rhs)) = 
   198    | expand constructors ty (row as ((prefix, p::rst), rhs)) = 
   210        if (is_Free p) 
   199        if (is_Free p) 
   211        then let val fresh = fresh_constr ty_match ty fresh_var
   200        then let val fresh = fresh_constr ty_match ty fresh_var
   212                 fun expnd (c,gvs) = 
   201                 fun expnd (c,gvs) = 
   213                   let val capp = list_comb(c,gvs)
   202                   let val capp = list_comb(c,gvs)
   214                   in ((prefix, capp::rst), psubst[(p,capp)] rhs)
   203                   in ((prefix, capp::rst), pattern_subst[(p,capp)] rhs)
   215                   end
   204                   end
   216             in map expnd (map fresh constructors)  end
   205             in map expnd (map fresh constructors)  end
   217        else [row]
   206        else [row]
   218  fun mk{rows=[],...} = mk_case_fail"no rows"
   207  fun mk{rows=[],...} = mk_case_fail"no rows"
   219    | mk{path=[], rows = ((prefix, []), rhs)::_} =  (* Done *)
   208    | mk{path=[], rows = ((prefix, []), rhs)::_} =  (* Done *)
   227    | mk{path = u::rstp, rows as ((_, p::_), _)::_} =
   216    | mk{path = u::rstp, rows as ((_, p::_), _)::_} =
   228      let val (pat_rectangle,rights) = ListPair.unzip rows
   217      let val (pat_rectangle,rights) = ListPair.unzip rows
   229          val col0 = map(hd o #2) pat_rectangle
   218          val col0 = map(hd o #2) pat_rectangle
   230      in 
   219      in 
   231      if (forall is_Free col0) 
   220      if (forall is_Free col0) 
   232      then let val rights' = map (fn(v,e) => psubst[(v,u)] e)
   221      then let val rights' = map (fn(v,e) => pattern_subst[(v,u)] e)
   233                                 (ListPair.zip (col0, rights))
   222                                 (ListPair.zip (col0, rights))
   234               val pat_rectangle' = map v_to_prefix pat_rectangle
   223               val pat_rectangle' = map v_to_prefix pat_rectangle
   235               val (pref_patl,tm) = mk{path = rstp,
   224               val (pref_patl,tm) = mk{path = rstp,
   236                                       rows = ListPair.zip (pat_rectangle',
   225                                       rows = ListPair.zip (pat_rectangle',
   237                                                            rights')}
   226                                                            rights')}
   241      let val pty as Type (ty_name,_) = type_of p
   230      let val pty as Type (ty_name,_) = type_of p
   242      in
   231      in
   243      case (ty_info ty_name)
   232      case (ty_info ty_name)
   244      of None => mk_case_fail("Not a known datatype: "^ty_name)
   233      of None => mk_case_fail("Not a known datatype: "^ty_name)
   245       | Some{case_const,constructors} =>
   234       | Some{case_const,constructors} =>
   246         let val case_const_name = #Name(S.dest_const case_const)
   235         let val case_const_name = #1(dest_Const case_const)
   247             val nrows = List_.concat (map (expand constructors pty) rows)
   236             val nrows = List_.concat (map (expand constructors pty) rows)
   248             val subproblems = divide(constructors, pty, range_ty, nrows)
   237             val subproblems = divide(constructors, pty, range_ty, nrows)
   249             val groups      = map #group subproblems
   238             val groups      = map #group subproblems
   250             and new_formals = map #new_formals subproblems
   239             and new_formals = map #new_formals subproblems
   251             and constructors' = map #constructor subproblems
   240             and constructors' = map #constructor subproblems
   254             val rec_calls = map mk news
   243             val rec_calls = map mk news
   255             val (pat_rect,dtrees) = ListPair.unzip rec_calls
   244             val (pat_rect,dtrees) = ListPair.unzip rec_calls
   256             val case_functions = map S.list_mk_abs
   245             val case_functions = map S.list_mk_abs
   257                                   (ListPair.zip (new_formals, dtrees))
   246                                   (ListPair.zip (new_formals, dtrees))
   258             val types = map type_of (case_functions@[u]) @ [range_ty]
   247             val types = map type_of (case_functions@[u]) @ [range_ty]
   259             val case_const' = S.mk_const{Name = case_const_name,
   248             val case_const' = Const(case_const_name, list_mk_type types)
   260                                          Ty   = list_mk_type types}
       
   261             val tree = list_comb(case_const', case_functions@[u])
   249             val tree = list_comb(case_const', case_functions@[u])
   262             val pat_rect1 = List_.concat
   250             val pat_rect1 = List_.concat
   263                               (ListPair.map mk_pat (constructors', pat_rect))
   251                               (ListPair.map mk_pat (constructors', pat_rect))
   264         in (pat_rect1,tree)
   252         in (pat_rect1,tree)
   265         end 
   253         end 
   269 
   257 
   270 
   258 
   271 (* Repeated variable occurrences in a pattern are not allowed. *)
   259 (* Repeated variable occurrences in a pattern are not allowed. *)
   272 fun FV_multiset tm = 
   260 fun FV_multiset tm = 
   273    case (S.dest_term tm)
   261    case (S.dest_term tm)
   274      of S.VAR v => [S.mk_var v]
   262      of S.VAR{Name,Ty} => [Free(Name,Ty)]
   275       | S.CONST _ => []
   263       | S.CONST _ => []
   276       | S.COMB{Rator, Rand} => FV_multiset Rator @ FV_multiset Rand
   264       | S.COMB{Rator, Rand} => FV_multiset Rator @ FV_multiset Rand
   277       | S.LAMB _ => raise TFL_ERR{func = "FV_multiset", mesg = "lambda"};
   265       | S.LAMB _ => raise TFL_ERR{func = "FV_multiset", mesg = "lambda"};
   278 
   266 
   279 fun no_repeat_vars thy pat =
   267 fun no_repeat_vars thy pat =
   286 			  quote (string_of_cterm (Thry.typecheck thy pat))}
   274 			  quote (string_of_cterm (Thry.typecheck thy pat))}
   287          else check rst
   275          else check rst
   288  in check (FV_multiset pat)
   276  in check (FV_multiset pat)
   289  end;
   277  end;
   290 
   278 
   291 local fun paired1{lhs,rhs} = (lhs,rhs) 
   279 local fun mk_functional_err s = raise TFL_ERR{func = "mk_functional", mesg=s}
   292       and paired2{Rator,Rand} = (Rator,Rand)
       
   293       fun mk_functional_err s = raise TFL_ERR{func = "mk_functional", mesg=s}
       
   294       fun single [f] = f
   280       fun single [f] = f
   295         | single fs  = mk_functional_err (Int.toString (length fs) ^ 
   281         | single fs  = mk_functional_err (Int.toString (length fs) ^ 
   296                                           " distinct function names!")
   282                                           " distinct function names!")
   297 in
   283 in
   298 fun mk_functional thy eqs =
   284 fun mk_functional thy clauses =
   299  let val clauses = S.strip_conj eqs
   285  let val (L,R) = ListPair.unzip 
   300      val (L,R) = ListPair.unzip 
   286                     (map (fn (Const("op =",_) $ t $ u) => (t,u)) clauses)
   301                     (map (paired1 o S.dest_eq o #2 o S.strip_forall)
   287      val (funcs,pats) = ListPair.unzip (map (fn (t$u) =>(t,u)) L)
   302                          clauses)
   288      val f = single (gen_distinct (op aconv) funcs)
   303      val (funcs,pats) = ListPair.unzip(map (paired2 o S.dest_comb) L)
   289      (**??why change the Const to a Free??????????????**)
   304      val f = single (U.mk_set (S.aconv) funcs)
   290      val fvar = if (is_Free f) then f else Free(dest_Const f)
   305      val fvar = if (is_Free f) then f else S.mk_var(S.dest_const f)
       
   306      val dummy = map (no_repeat_vars thy) pats
   291      val dummy = map (no_repeat_vars thy) pats
   307      val rows = ListPair.zip (map (fn x => ([],[x])) pats,
   292      val rows = ListPair.zip (map (fn x => ([],[x])) pats,
   308                               map GIVEN (enumerate R))
   293                               map GIVEN (enumerate R))
   309      val fvs = S.free_varsl R
   294      val fvs = S.free_varsl R
   310      val a = S.variant fvs (S.mk_var{Name="a", Ty = type_of(hd pats)})
   295      val a = S.variant fvs (Free("a",type_of(hd pats)))
   311      val FV = a::fvs
   296      val FV = a::fvs
   312      val ty_info = Thry.match_info thy
   297      val ty_info = Thry.match_info thy
   313      val ty_match = Thry.match_type thy
   298      val ty_match = Thry.match_type thy
   314      val range_ty = type_of (hd R)
   299      val range_ty = type_of (hd R)
   315      val (patts, case_tm) = mk_case ty_info ty_match FV range_ty 
   300      val (patts, case_tm) = mk_case ty_info ty_match FV range_ty 
   316                                     {path=[a], rows=rows}
   301                                     {path=[a], rows=rows}
   317      val patts1 = map (fn (_,(tag,i),[pat]) => tag (pat,i)) patts handle _ 
   302      val patts1 = map (fn (_,(tag,i),[pat]) => tag (pat,i)) patts 
   318                   => mk_functional_err "error in pattern-match translation"
   303 	  handle _ => mk_functional_err "error in pattern-match translation"
   319      val patts2 = U.sort(fn p1=>fn p2=> row_of_pat p1 < row_of_pat p2) patts1
   304      val patts2 = U.sort(fn p1=>fn p2=> row_of_pat p1 < row_of_pat p2) patts1
   320      val finals = map row_of_pat patts2
   305      val finals = map row_of_pat patts2
   321      val originals = map (row_of_pat o #2) rows
   306      val originals = map (row_of_pat o #2) rows
   322      fun int_eq i1 (i2:int) =  (i1=i2)
   307      val dummy = case (originals\\finals)
   323      val dummy = case (U.set_diff int_eq originals finals)
       
   324              of [] => ()
   308              of [] => ()
   325           | L => mk_functional_err("The following rows (counting from zero)\
   309           | L => mk_functional_err("The following rows (counting from zero)\
   326                                    \ are inaccessible: "^stringize L)
   310                                    \ are inaccessible: "^stringize L)
   327      val case_tm' = subst_free [(f,fvar)] case_tm
   311      val case_tm' = subst_free [(f,fvar)] case_tm
   328  in {functional = S.list_mk_abs ([fvar,a], case_tm'),
   312  in {functional = S.list_mk_abs ([fvar,a], case_tm'),
   350            #ant(S.dest_imp(#2(S.strip_forall (concl Thms.WFREC_COROLLARY))))
   334            #ant(S.dest_imp(#2(S.strip_forall (concl Thms.WFREC_COROLLARY))))
   351       val {lhs=f, rhs} = S.dest_eq f_eq_wfrec_R_M
   335       val {lhs=f, rhs} = S.dest_eq f_eq_wfrec_R_M
   352       val (fname,_) = dest_Free f
   336       val (fname,_) = dest_Free f
   353       val (wfrec,_) = S.strip_comb rhs
   337       val (wfrec,_) = S.strip_comb rhs
   354 in
   338 in
   355 fun wfrec_definition0 thy fid R functional =
   339 fun wfrec_definition0 thy fid R (functional as Abs(Name, Ty, _)) =
   356  let val {Bvar,...} = S.dest_abs functional
   340  let val def_name = if Name<>fid then 
   357      val (Name, Ty) = dest_Free Bvar  
       
   358      val def_name = if Name<>fid then 
       
   359 			raise TFL_ERR{func = "wfrec_definition0",
   341 			raise TFL_ERR{func = "wfrec_definition0",
   360 				      mesg = "Expected a definition of " ^ 
   342 				      mesg = "Expected a definition of " ^ 
   361 					     quote fid ^ " but found one of " ^
   343 					     quote fid ^ " but found one of " ^
   362 				      quote Name}
   344 				      quote Name}
   363 		    else Name ^ "_def"
   345 		    else Name ^ "_def"
   364      val wfrec_R_M = map_term_types poly_tvars
   346      val wfrec_R_M =  map_term_types poly_tvars 
   365 	               (wfrec $ R $ (map_term_types poly_tvars functional))
   347 	                  (wfrec $ map_term_types poly_tvars R) 
       
   348 	              $ functional
   366      val (_, def_term, _) = 
   349      val (_, def_term, _) = 
   367 	 Sign.infer_types (sign_of thy) (K None) (K None) [] false
   350 	 Sign.infer_types (sign_of thy) (K None) (K None) [] false
   368 	       ([HOLogic.mk_eq(Bvar, wfrec_R_M)], 
   351 	       ([HOLogic.mk_eq(Const(Name,Ty), wfrec_R_M)], 
   369 		HOLogic.boolT)
   352 		HOLogic.boolT)
   370 		    
   353 		    
   371   in 
   354   in 
   372   Thry.make_definition thy def_name def_term
   355   Thry.make_definition thy def_name def_term
   373   end
   356   end
   399  * cases. This routine is used to prepare input for mk_induction.
   382  * cases. This routine is used to prepare input for mk_induction.
   400  *---------------------------------------------------------------------------*)
   383  *---------------------------------------------------------------------------*)
   401 fun merge full_pats TCs =
   384 fun merge full_pats TCs =
   402 let fun insert (p,TCs) =
   385 let fun insert (p,TCs) =
   403       let fun insrt ((x as (h,[]))::rst) = 
   386       let fun insrt ((x as (h,[]))::rst) = 
   404                  if (S.aconv p h) then (p,TCs)::rst else x::insrt rst
   387                  if (p aconv h) then (p,TCs)::rst else x::insrt rst
   405             | insrt (x::rst) = x::insrt rst
   388             | insrt (x::rst) = x::insrt rst
   406             | insrt[] = raise TFL_ERR{func="merge.insert",mesg="pat not found"}
   389             | insrt[] = raise TFL_ERR{func="merge.insert",
       
   390 				      mesg="pattern not found"}
   407       in insrt end
   391       in insrt end
   408     fun pass ([],ptcl_final) = ptcl_final
   392     fun pass ([],ptcl_final) = ptcl_final
   409       | pass (ptcs::tcl, ptcl) = pass(tcl, insert ptcs ptcl)
   393       | pass (ptcs::tcl, ptcl) = pass(tcl, insert ptcs ptcl)
   410 in 
   394 in 
   411   pass (TCs, map (fn p => (p,[])) full_pats)
   395   pass (TCs, map (fn p => (p,[])) full_pats)
   412 end;
   396 end;
   413 
   397 
   414 fun not_omitted (GIVEN(tm,_)) = tm
   398 
   415   | not_omitted (OMITTED _) = raise TFL_ERR{func="not_omitted",mesg=""}
   399 (*Replace all TFrees by TVars [CURRENTLY UNUSED]*)
   416 val givens = U.mapfilter not_omitted;
   400 val tvars_of_tfrees = 
   417 
   401     map_term_types (map_type_tfree (fn (a,sort) => TVar ((a, 0), sort)));
       
   402 
       
   403 fun givens [] = []
       
   404   | givens (GIVEN(tm,_)::pats) = tm :: givens pats
       
   405   | givens (OMITTED _::pats)   = givens pats;
   418 
   406 
   419 fun post_definition (theory, (def, pats)) =
   407 fun post_definition (theory, (def, pats)) =
   420  let val tych = Thry.typecheck theory 
   408  let val tych = Thry.typecheck theory 
   421      val f = #lhs(S.dest_eq(concl def))
   409      val f = #lhs(S.dest_eq(concl def))
   422      val corollary = R.MATCH_MP Thms.WFREC_COROLLARY def
   410      val corollary = R.MATCH_MP Thms.WFREC_COROLLARY def
   423      val given_pats = givens pats
   411      val given_pats = givens pats
   424      val WFR = #ant(S.dest_imp(concl corollary))
   412      val WFR = #ant(S.dest_imp(concl corollary))
   425      val R = #Rand(S.dest_comb WFR)
   413      val R = #Rand(S.dest_comb WFR)
   426      val corollary' = R.UNDISCH corollary  (* put WF R on assums *)
   414      val corollary' = R.UNDISCH corollary  (* put WF R on assums *)
   427      val corollaries = map (U.C R.SPEC corollary' o tych) given_pats
   415      val corollaries = map (fn pat => R.SPEC (tych pat) corollary') 
       
   416 	                   given_pats
   428      val (case_rewrites,context_congs) = extraction_thms theory
   417      val (case_rewrites,context_congs) = extraction_thms theory
   429      val corollaries' = map(R.simplify case_rewrites) corollaries
   418      val corollaries' = map(R.simplify case_rewrites) corollaries
   430      fun xtract th = R.CONTEXT_REWRITE_RULE(f,R)
   419      fun xtract th = R.CONTEXT_REWRITE_RULE(f,R)
   431                          {cut_lemma = R.ISPECL (map tych [f,R]) Thms.CUT_LEMMA,
   420                          {cut_lemma = R.ISPECL (map tych [f,R]) Thms.CUT_LEMMA,
   432 			  congs = context_congs,
   421 			  congs = context_congs,
   436      val mk_cond_rule = R.FILTER_DISCH_ALL(not o S.aconv WFR)
   425      val mk_cond_rule = R.FILTER_DISCH_ALL(not o S.aconv WFR)
   437      val rules1 = R.LIST_CONJ(map mk_cond_rule rules0)
   426      val rules1 = R.LIST_CONJ(map mk_cond_rule rules0)
   438  in
   427  in
   439  {theory = theory,   (* holds def, if it's needed *)
   428  {theory = theory,   (* holds def, if it's needed *)
   440   rules = rules1,
   429   rules = rules1,
   441   full_pats_TCs = merge (map pat_of pats) (ListPair.zip (given_pats, TCs)), 
   430   full_pats_TCs = merge (map pat_of pats) 
       
   431                         (ListPair.zip (given_pats, TCs)), 
   442   TCs = TCs, 
   432   TCs = TCs, 
   443   patterns = pats}
   433   patterns = pats}
   444  end;
   434  end;
   445 
   435 
   446 (*---------------------------------------------------------------------------
   436 (*---------------------------------------------------------------------------
   455      val {Bvar = x, ...} = S.dest_abs Body
   445      val {Bvar = x, ...} = S.dest_abs Body
   456      val (Name, Type("fun", [f_dty, f_rty])) = dest_Free f
   446      val (Name, Type("fun", [f_dty, f_rty])) = dest_Free f
   457      val (case_rewrites,context_congs) = extraction_thms thy
   447      val (case_rewrites,context_congs) = extraction_thms thy
   458      val tych = Thry.typecheck thy
   448      val tych = Thry.typecheck thy
   459      val WFREC_THM0 = R.ISPEC (tych functional) Thms.WFREC_COROLLARY
   449      val WFREC_THM0 = R.ISPEC (tych functional) Thms.WFREC_COROLLARY
   460      val R = S.variant(S.free_vars eqns) 
   450      val R = S.variant(foldr add_term_frees (eqns,[])) 
   461                       (#Bvar(S.dest_forall(concl WFREC_THM0)))
   451                       (#Bvar(S.dest_forall(concl WFREC_THM0)))
   462      val WFREC_THM = R.ISPECL [tych R, tych f] WFREC_THM0
   452      val WFREC_THM = R.ISPECL [tych R, tych f] WFREC_THM0
   463      val ([proto_def, WFR],_) = S.strip_imp(concl WFREC_THM)
   453      val ([proto_def, WFR],_) = S.strip_imp(concl WFREC_THM)
   464      val R1 = S.rand WFR
   454      val R1 = S.rand WFR
   465      val corollary' = R.UNDISCH(R.UNDISCH WFREC_THM)
   455      val corollary' = R.UNDISCH(R.UNDISCH WFREC_THM)
   614  end;
   604  end;
   615 
   605 
   616 
   606 
   617 fun complete_cases thy =
   607 fun complete_cases thy =
   618  let val tych = Thry.typecheck thy
   608  let val tych = Thry.typecheck thy
   619      fun pmk_var n ty = S.mk_var{Name = n,Ty = ty}
       
   620      val ty_info = Thry.induct_info thy
   609      val ty_info = Thry.induct_info thy
   621  in fn pats =>
   610  in fn pats =>
   622  let val FV0 = S.free_varsl pats
   611  let val FV0 = S.free_varsl pats
   623      val a = S.variant FV0 (pmk_var "a" (type_of(hd pats)))
   612      val T = type_of (hd pats)
   624      val v = S.variant (a::FV0) (pmk_var "v" (type_of a))
   613      val a = S.variant FV0 (Free ("a", T))
       
   614      val v = S.variant (a::FV0) (Free ("v", T))
   625      val FV = a::v::FV0
   615      val FV = a::v::FV0
   626      val a_eq_v = HOLogic.mk_eq(a,v)
   616      val a_eq_v = HOLogic.mk_eq(a,v)
   627      val ex_th0 = R.EXISTS (tych (S.mk_exists{Bvar=v,Body=a_eq_v}), tych a)
   617      val ex_th0 = R.EXISTS (tych (S.mk_exists{Bvar=v,Body=a_eq_v}), tych a)
   628                            (R.REFL (tych a))
   618                            (R.REFL (tych a))
   629      val th0 = R.ASSUME (tych a_eq_v)
   619      val th0 = R.ASSUME (tych a_eq_v)
   659              val P_y = if (nested tm) then R_y_pat ==> P^y else P^y
   649              val P_y = if (nested tm) then R_y_pat ==> P^y else P^y
   660          in case cntxt 
   650          in case cntxt 
   661               of [] => (P_y, (tm,[]))
   651               of [] => (P_y, (tm,[]))
   662                | _  => let 
   652                | _  => let 
   663                     val imp = S.list_mk_conj cntxt ==> P_y
   653                     val imp = S.list_mk_conj cntxt ==> P_y
   664                     val lvs = U.set_diff S.aconv (S.free_vars_lr imp) globals
   654                     val lvs = gen_rems (op aconv) (S.free_vars_lr imp, globals)
   665                     val locals = #2(U.pluck (S.aconv P) lvs) handle _ => lvs
   655                     val locals = #2(U.pluck (S.aconv P) lvs) handle _ => lvs
   666                     in (S.list_mk_forall(locals,imp), (tm,locals)) end
   656                     in (S.list_mk_forall(locals,imp), (tm,locals)) end
   667          end
   657          end
   668  in case TCs
   658  in case TCs
   669     of [] => (S.list_mk_forall(globals, P^pat), [])
   659     of [] => (S.list_mk_forall(globals, P^pat), [])
   748     val Sinduction = R.UNDISCH (R.ISPEC (tych R) Thms.WF_INDUCTION_THM)
   738     val Sinduction = R.UNDISCH (R.ISPEC (tych R) Thms.WF_INDUCTION_THM)
   749     val (pats,TCsl) = ListPair.unzip pat_TCs_list
   739     val (pats,TCsl) = ListPair.unzip pat_TCs_list
   750     val case_thm = complete_cases thy pats
   740     val case_thm = complete_cases thy pats
   751     val domain = (type_of o hd) pats
   741     val domain = (type_of o hd) pats
   752     val P = S.variant (S.all_varsl (pats @ List_.concat TCsl))
   742     val P = S.variant (S.all_varsl (pats @ List_.concat TCsl))
   753                       (S.mk_var{Name="P", Ty=domain --> HOLogic.boolT})
   743                       (Free("P",domain --> HOLogic.boolT))
   754     val Sinduct = R.SPEC (tych P) Sinduction
   744     val Sinduct = R.SPEC (tych P) Sinduction
   755     val Sinduct_assumf = S.rand ((#ant o S.dest_imp o concl) Sinduct)
   745     val Sinduct_assumf = S.rand ((#ant o S.dest_imp o concl) Sinduct)
   756     val Rassums_TCl' = map (build_ih f P) pat_TCs_list
   746     val Rassums_TCl' = map (build_ih f P) pat_TCs_list
   757     val (Rassums,TCl') = ListPair.unzip Rassums_TCl'
   747     val (Rassums,TCl') = ListPair.unzip Rassums_TCl'
   758     val Rinduct_assum = R.ASSUME (tych (S.list_mk_conj Rassums))
   748     val Rinduct_assum = R.ASSUME (tych (S.list_mk_conj Rassums))
   759     val cases = map (S.beta_conv o combize Sinduct_assumf) pats
   749     val cases = map (S.beta_conv o combize Sinduct_assumf) pats
   760     val tasks = U.zip3 cases TCl' (R.CONJUNCTS Rinduct_assum)
   750     val tasks = U.zip3 cases TCl' (R.CONJUNCTS Rinduct_assum)
   761     val proved_cases = map (prove_case f thy) tasks
   751     val proved_cases = map (prove_case f thy) tasks
   762     val v = S.variant (S.free_varsl (map concl proved_cases))
   752     val v = S.variant (S.free_varsl (map concl proved_cases))
   763                       (S.mk_var{Name="v", Ty=domain})
   753                       (Free("v",domain))
   764     val vtyped = tych v
   754     val vtyped = tych v
   765     val substs = map (R.SYM o R.ASSUME o tych o (curry HOLogic.mk_eq v)) pats
   755     val substs = map (R.SYM o R.ASSUME o tych o (curry HOLogic.mk_eq v)) pats
   766     val proved_cases1 = ListPair.map (fn (th,th') => R.SUBS[th]th') 
   756     val proved_cases1 = ListPair.map (fn (th,th') => R.SUBS[th]th') 
   767                           (substs, proved_cases)
   757                           (substs, proved_cases)
   768     val abs_cases = map (LEFT_ABS_VSTRUCT tych) proved_cases1
   758     val abs_cases = map (LEFT_ABS_VSTRUCT tych) proved_cases1
   772     val vars = map (gvvariant[P]) (S.strip_prod_type Parg_ty)
   762     val vars = map (gvvariant[P]) (S.strip_prod_type Parg_ty)
   773     val dc' = U.itlist (R.GEN o tych) vars
   763     val dc' = U.itlist (R.GEN o tych) vars
   774                        (R.SPEC (tych(S.mk_vstruct Parg_ty vars)) dc)
   764                        (R.SPEC (tych(S.mk_vstruct Parg_ty vars)) dc)
   775 in 
   765 in 
   776    R.GEN (tych P) (R.DISCH (tych(concl Rinduct_assum)) dc')
   766    R.GEN (tych P) (R.DISCH (tych(concl Rinduct_assum)) dc')
   777 end 
   767 end
   778 handle _ => raise TFL_ERR{func = "mk_induction", mesg = "failed derivation"};
   768 handle _ => raise TFL_ERR{func = "mk_induction", mesg = "failed derivation"};
       
   769 
   779 
   770 
   780 
   771 
   781 
   772 
   782 (*---------------------------------------------------------------------------
   773 (*---------------------------------------------------------------------------
   783  * 
   774  * 
   873     *-------------------------------------------------------------------*)
   864     *-------------------------------------------------------------------*)
   874    fun strip_imp tm = if S.is_neg tm then ([],tm) else S.strip_imp tm
   865    fun strip_imp tm = if S.is_neg tm then ([],tm) else S.strip_imp tm
   875    fun loop ([],extras,R,ind) = (rev R, ind, extras)
   866    fun loop ([],extras,R,ind) = (rev R, ind, extras)
   876      | loop ((r,ftcs)::rst, nthms, R, ind) =
   867      | loop ((r,ftcs)::rst, nthms, R, ind) =
   877         let val tcs = #1(strip_imp (concl r))
   868         let val tcs = #1(strip_imp (concl r))
   878             val extra_tcs = U.set_diff S.aconv ftcs tcs
   869             val extra_tcs = gen_rems (op aconv) (ftcs, tcs)
   879             val extra_tc_thms = map simplify_nested_tc extra_tcs
   870             val extra_tc_thms = map simplify_nested_tc extra_tcs
   880             val (r1,ind1) = U.rev_itlist simplify_tc tcs (r,ind)
   871             val (r1,ind1) = U.rev_itlist simplify_tc tcs (r,ind)
   881             val r2 = R.FILTER_DISCH_ALL(not o S.is_WFR) r1
   872             val r2 = R.FILTER_DISCH_ALL(not o S.is_WFR) r1
   882         in loop(rst, nthms@extra_tc_thms, r2::R, ind1)
   873         in loop(rst, nthms@extra_tc_thms, r2::R, ind1)
   883         end
   874         end