src/HOL/Tools/TFL/tfl.ML
changeset 41164 6854e9a40edc
parent 40314 b5ec88d9ac03
child 41491 a2ad5b824051
equal deleted inserted replaced
41163:3f21a269780e 41164:6854e9a40edc
    40 structure Prim: PRIM =
    40 structure Prim: PRIM =
    41 struct
    41 struct
    42 
    42 
    43 val trace = Unsynchronized.ref false;
    43 val trace = Unsynchronized.ref false;
    44 
    44 
    45 structure R = Rules;
    45 
    46 structure S = USyntax;
    46 fun TFL_ERR func mesg = Utils.ERR {module = "Tfl", func = func, mesg = mesg};
    47 structure U = Utils;
    47 
    48 
    48 val concl = #2 o Rules.dest_thm;
    49 
    49 val hyp = #1 o Rules.dest_thm;
    50 fun TFL_ERR func mesg = U.ERR {module = "Tfl", func = func, mesg = mesg};
    50 
    51 
    51 val list_mk_type = Utils.end_itlist (curry (op -->));
    52 val concl = #2 o R.dest_thm;
       
    53 val hyp = #1 o R.dest_thm;
       
    54 
       
    55 val list_mk_type = U.end_itlist (curry (op -->));
       
    56 
    52 
    57 fun front_last [] = raise TFL_ERR "front_last" "empty list"
    53 fun front_last [] = raise TFL_ERR "front_last" "empty list"
    58   | front_last [x] = ([],x)
    54   | front_last [x] = ([],x)
    59   | front_last (h::t) =
    55   | front_last (h::t) =
    60      let val (pref,x) = front_last t
    56      let val (pref,x) = front_last t
    97           let val (c, T) = dest_Const c
    93           let val (c, T) = dest_Const c
    98               val L = binder_types T
    94               val L = binder_types T
    99               val (in_group, not_in_group) =
    95               val (in_group, not_in_group) =
   100                fold_rev (fn (row as (p::rst, rhs)) =>
    96                fold_rev (fn (row as (p::rst, rhs)) =>
   101                          fn (in_group,not_in_group) =>
    97                          fn (in_group,not_in_group) =>
   102                   let val (pc,args) = S.strip_comb p
    98                   let val (pc,args) = USyntax.strip_comb p
   103                   in if (#1(dest_Const pc) = c)
    99                   in if (#1(dest_Const pc) = c)
   104                      then ((args@rst, rhs)::in_group, not_in_group)
   100                      then ((args@rst, rhs)::in_group, not_in_group)
   105                      else (in_group, row::not_in_group)
   101                      else (in_group, row::not_in_group)
   106                   end)      rows ([],[])
   102                   end)      rows ([],[])
   107               val col_types = U.take type_of (length L, #1(hd in_group))
   103               val col_types = Utils.take type_of (length L, #1(hd in_group))
   108           in
   104           in
   109           part{constrs = crst, rows = not_in_group,
   105           part{constrs = crst, rows = not_in_group,
   110                A = {constructor = c,
   106                A = {constructor = c,
   111                     new_formals = map gv col_types,
   107                     new_formals = map gv col_types,
   112                     group = in_group}::A}
   108                     group = in_group}::A}
   140 fun fresh_constr ty_match colty gv c =
   136 fun fresh_constr ty_match colty gv c =
   141   let val (_,Ty) = dest_Const c
   137   let val (_,Ty) = dest_Const c
   142       val L = binder_types Ty
   138       val L = binder_types Ty
   143       and ty = body_type Ty
   139       and ty = body_type Ty
   144       val ty_theta = ty_match ty colty
   140       val ty_theta = ty_match ty colty
   145       val c' = S.inst ty_theta c
   141       val c' = USyntax.inst ty_theta c
   146       val gvars = map (S.inst ty_theta o gv) L
   142       val gvars = map (USyntax.inst ty_theta o gv) L
   147   in (c', gvars)
   143   in (c', gvars)
   148   end;
   144   end;
   149 
   145 
   150 
   146 
   151 (*---------------------------------------------------------------------------
   147 (*---------------------------------------------------------------------------
   153  * pattern with constructor = name.
   149  * pattern with constructor = name.
   154  *---------------------------------------------------------------------------*)
   150  *---------------------------------------------------------------------------*)
   155 fun mk_group name rows =
   151 fun mk_group name rows =
   156   fold_rev (fn (row as ((prfx, p::rst), rhs)) =>
   152   fold_rev (fn (row as ((prfx, p::rst), rhs)) =>
   157             fn (in_group,not_in_group) =>
   153             fn (in_group,not_in_group) =>
   158                let val (pc,args) = S.strip_comb p
   154                let val (pc,args) = USyntax.strip_comb p
   159                in if ((#1 (Term.dest_Const pc) = name) handle TERM _ => false)
   155                in if ((#1 (Term.dest_Const pc) = name) handle TERM _ => false)
   160                   then (((prfx,args@rst), rhs)::in_group, not_in_group)
   156                   then (((prfx,args@rst), rhs)::in_group, not_in_group)
   161                   else (in_group, row::not_in_group) end)
   157                   else (in_group, row::not_in_group) end)
   162       rows ([],[]);
   158       rows ([],[]);
   163 
   159 
   172        | part {constrs = c::crst, rows, A} =
   168        | part {constrs = c::crst, rows, A} =
   173          let val (c',gvars) = fresh c
   169          let val (c',gvars) = fresh c
   174              val (in_group, not_in_group) = mk_group (#1 (dest_Const c')) rows
   170              val (in_group, not_in_group) = mk_group (#1 (dest_Const c')) rows
   175              val in_group' =
   171              val in_group' =
   176                  if (null in_group)  (* Constructor not given *)
   172                  if (null in_group)  (* Constructor not given *)
   177                  then [((prfx, #2(fresh c)), (S.ARB res_ty, (~1,false)))]
   173                  then [((prfx, #2(fresh c)), (USyntax.ARB res_ty, (~1,false)))]
   178                  else in_group
   174                  else in_group
   179          in
   175          in
   180          part{constrs = crst,
   176          part{constrs = crst,
   181               rows = not_in_group,
   177               rows = not_in_group,
   182               A = {constructor = c',
   178               A = {constructor = c',
   262             and constructors' = map #constructor subproblems
   258             and constructors' = map #constructor subproblems
   263             val news = map (fn (nf,rows) => {path = nf@rstp, rows=rows})
   259             val news = map (fn (nf,rows) => {path = nf@rstp, rows=rows})
   264                            (ListPair.zip (new_formals, groups))
   260                            (ListPair.zip (new_formals, groups))
   265             val rec_calls = map mk news
   261             val rec_calls = map mk news
   266             val (pat_rect,dtrees) = ListPair.unzip rec_calls
   262             val (pat_rect,dtrees) = ListPair.unzip rec_calls
   267             val case_functions = map S.list_mk_abs
   263             val case_functions = map USyntax.list_mk_abs
   268                                   (ListPair.zip (new_formals, dtrees))
   264                                   (ListPair.zip (new_formals, dtrees))
   269             val types = map type_of (case_functions@[u]) @ [range_ty]
   265             val types = map type_of (case_functions@[u]) @ [range_ty]
   270             val case_const' = Const(case_const_name, list_mk_type types)
   266             val case_const' = Const(case_const_name, list_mk_type types)
   271             val tree = list_comb(case_const', case_functions@[u])
   267             val tree = list_comb(case_const', case_functions@[u])
   272             val pat_rect1 = flat (ListPair.map mk_pat (constructors', pat_rect))
   268             val pat_rect1 = flat (ListPair.map mk_pat (constructors', pat_rect))
   277  end;
   273  end;
   278 
   274 
   279 
   275 
   280 (* Repeated variable occurrences in a pattern are not allowed. *)
   276 (* Repeated variable occurrences in a pattern are not allowed. *)
   281 fun FV_multiset tm =
   277 fun FV_multiset tm =
   282    case (S.dest_term tm)
   278    case (USyntax.dest_term tm)
   283      of S.VAR{Name = c, Ty = T} => [Free(c, T)]
   279      of USyntax.VAR{Name = c, Ty = T} => [Free(c, T)]
   284       | S.CONST _ => []
   280       | USyntax.CONST _ => []
   285       | S.COMB{Rator, Rand} => FV_multiset Rator @ FV_multiset Rand
   281       | USyntax.COMB{Rator, Rand} => FV_multiset Rator @ FV_multiset Rand
   286       | S.LAMB _ => raise TFL_ERR "FV_multiset" "lambda";
   282       | USyntax.LAMB _ => raise TFL_ERR "FV_multiset" "lambda";
   287 
   283 
   288 fun no_repeat_vars thy pat =
   284 fun no_repeat_vars thy pat =
   289  let fun check [] = true
   285  let fun check [] = true
   290        | check (v::rst) =
   286        | check (v::rst) =
   291          if member (op aconv) rst v then
   287          if member (op aconv) rst v then
   368 fun poly_tvars (Type(a,Ts)) = Type(a, map (poly_tvars) Ts)
   364 fun poly_tvars (Type(a,Ts)) = Type(a, map (poly_tvars) Ts)
   369   | poly_tvars (TFree (a,sort)) = TVar (("?" ^ a, 0), sort)
   365   | poly_tvars (TFree (a,sort)) = TVar (("?" ^ a, 0), sort)
   370   | poly_tvars (TVar ((a,i),sort)) = TVar (("?" ^ a, i+1), sort);
   366   | poly_tvars (TVar ((a,i),sort)) = TVar (("?" ^ a, i+1), sort);
   371 
   367 
   372 local val f_eq_wfrec_R_M =
   368 local val f_eq_wfrec_R_M =
   373            #ant(S.dest_imp(#2(S.strip_forall (concl Thms.WFREC_COROLLARY))))
   369            #ant(USyntax.dest_imp(#2(USyntax.strip_forall (concl Thms.WFREC_COROLLARY))))
   374       val {lhs=f, rhs} = S.dest_eq f_eq_wfrec_R_M
   370       val {lhs=f, rhs} = USyntax.dest_eq f_eq_wfrec_R_M
   375       val (fname,_) = dest_Free f
   371       val (fname,_) = dest_Free f
   376       val (wfrec,_) = S.strip_comb rhs
   372       val (wfrec,_) = USyntax.strip_comb rhs
   377 in
   373 in
   378 fun wfrec_definition0 thy fid R (functional as Abs(x, Ty, _)) =
   374 fun wfrec_definition0 thy fid R (functional as Abs(x, Ty, _)) =
   379  let val def_name = Long_Name.base_name fid ^ "_def"
   375  let val def_name = Long_Name.base_name fid ^ "_def"
   380      val wfrec_R_M =  map_types poly_tvars
   376      val wfrec_R_M =  map_types poly_tvars
   381                           (wfrec $ map_types poly_tvars R)
   377                           (wfrec $ map_types poly_tvars R)
   420 
   416 
   421 fun givens pats = map pat_of (filter given pats);
   417 fun givens pats = map pat_of (filter given pats);
   422 
   418 
   423 fun post_definition meta_tflCongs (theory, (def, pats)) =
   419 fun post_definition meta_tflCongs (theory, (def, pats)) =
   424  let val tych = Thry.typecheck theory
   420  let val tych = Thry.typecheck theory
   425      val f = #lhs(S.dest_eq(concl def))
   421      val f = #lhs(USyntax.dest_eq(concl def))
   426      val corollary = R.MATCH_MP Thms.WFREC_COROLLARY def
   422      val corollary = Rules.MATCH_MP Thms.WFREC_COROLLARY def
   427      val pats' = filter given pats
   423      val pats' = filter given pats
   428      val given_pats = map pat_of pats'
   424      val given_pats = map pat_of pats'
   429      val rows = map row_of_pat pats'
   425      val rows = map row_of_pat pats'
   430      val WFR = #ant(S.dest_imp(concl corollary))
   426      val WFR = #ant(USyntax.dest_imp(concl corollary))
   431      val R = #Rand(S.dest_comb WFR)
   427      val R = #Rand(USyntax.dest_comb WFR)
   432      val corollary' = R.UNDISCH corollary  (* put WF R on assums *)
   428      val corollary' = Rules.UNDISCH corollary  (* put WF R on assums *)
   433      val corollaries = map (fn pat => R.SPEC (tych pat) corollary')
   429      val corollaries = map (fn pat => Rules.SPEC (tych pat) corollary')
   434                            given_pats
   430                            given_pats
   435      val (case_rewrites,context_congs) = extraction_thms theory
   431      val (case_rewrites,context_congs) = extraction_thms theory
   436      (*case_ss causes minimal simplification: bodies of case expressions are
   432      (*case_ss causes minimal simplification: bodies of case expressions are
   437        not simplified. Otherwise large examples (Red-Black trees) are too
   433        not simplified. Otherwise large examples (Red-Black trees) are too
   438        slow.*)
   434        slow.*)
   439      val case_ss = Simplifier.global_context theory
   435      val case_ss = Simplifier.global_context theory
   440        (HOL_basic_ss addcongs
   436        (HOL_basic_ss addcongs
   441          (map (#weak_case_cong o snd) o Symtab.dest o Datatype.get_all) theory addsimps case_rewrites)
   437          (map (#weak_case_cong o snd) o Symtab.dest o Datatype.get_all) theory addsimps case_rewrites)
   442      val corollaries' = map (Simplifier.simplify case_ss) corollaries
   438      val corollaries' = map (Simplifier.simplify case_ss) corollaries
   443      val extract = R.CONTEXT_REWRITE_RULE
   439      val extract = Rules.CONTEXT_REWRITE_RULE
   444                      (f, [R], @{thm cut_apply}, meta_tflCongs@context_congs)
   440                      (f, [R], @{thm cut_apply}, meta_tflCongs@context_congs)
   445      val (rules, TCs) = ListPair.unzip (map extract corollaries')
   441      val (rules, TCs) = ListPair.unzip (map extract corollaries')
   446      val rules0 = map (rewrite_rule [Thms.CUT_DEF]) rules
   442      val rules0 = map (rewrite_rule [Thms.CUT_DEF]) rules
   447      val mk_cond_rule = R.FILTER_DISCH_ALL(not o curry (op aconv) WFR)
   443      val mk_cond_rule = Rules.FILTER_DISCH_ALL(not o curry (op aconv) WFR)
   448      val rules1 = R.LIST_CONJ(map mk_cond_rule rules0)
   444      val rules1 = Rules.LIST_CONJ(map mk_cond_rule rules0)
   449  in
   445  in
   450  {rules = rules1,
   446  {rules = rules1,
   451   rows = rows,
   447   rows = rows,
   452   full_pats_TCs = merge (map pat_of pats) (ListPair.zip (given_pats, TCs)),
   448   full_pats_TCs = merge (map pat_of pats) (ListPair.zip (given_pats, TCs)),
   453   TCs = TCs}
   449   TCs = TCs}
   461  * The purpose of wfrec_eqns is merely to instantiate the recursion theorem
   457  * The purpose of wfrec_eqns is merely to instantiate the recursion theorem
   462  * and extract termination conditions: no definition is made.
   458  * and extract termination conditions: no definition is made.
   463  *---------------------------------------------------------------------------*)
   459  *---------------------------------------------------------------------------*)
   464 
   460 
   465 fun wfrec_eqns thy fid tflCongs eqns =
   461 fun wfrec_eqns thy fid tflCongs eqns =
   466  let val {lhs,rhs} = S.dest_eq (hd eqns)
   462  let val {lhs,rhs} = USyntax.dest_eq (hd eqns)
   467      val (f,args) = S.strip_comb lhs
   463      val (f,args) = USyntax.strip_comb lhs
   468      val (fname,fty) = dest_atom f
   464      val (fname,fty) = dest_atom f
   469      val (SV,a) = front_last args    (* SV = schematic variables *)
   465      val (SV,a) = front_last args    (* SV = schematic variables *)
   470      val g = list_comb(f,SV)
   466      val g = list_comb(f,SV)
   471      val h = Free(fname,type_of g)
   467      val h = Free(fname,type_of g)
   472      val eqns1 = map (subst_free[(g,h)]) eqns
   468      val eqns1 = map (subst_free[(g,h)]) eqns
   480                                       quote fid ^ " but found one of " ^
   476                                       quote fid ^ " but found one of " ^
   481                                       quote x)
   477                                       quote x)
   482                  else ()
   478                  else ()
   483      val (case_rewrites,context_congs) = extraction_thms thy
   479      val (case_rewrites,context_congs) = extraction_thms thy
   484      val tych = Thry.typecheck thy
   480      val tych = Thry.typecheck thy
   485      val WFREC_THM0 = R.ISPEC (tych functional) Thms.WFREC_COROLLARY
   481      val WFREC_THM0 = Rules.ISPEC (tych functional) Thms.WFREC_COROLLARY
   486      val Const(@{const_name All},_) $ Abs(Rname,Rtype,_) = concl WFREC_THM0
   482      val Const(@{const_name All},_) $ Abs(Rname,Rtype,_) = concl WFREC_THM0
   487      val R = Free (Name.variant (List.foldr OldTerm.add_term_names [] eqns) Rname,
   483      val R = Free (Name.variant (List.foldr OldTerm.add_term_names [] eqns) Rname,
   488                    Rtype)
   484                    Rtype)
   489      val WFREC_THM = R.ISPECL [tych R, tych g] WFREC_THM0
   485      val WFREC_THM = Rules.ISPECL [tych R, tych g] WFREC_THM0
   490      val ([proto_def, WFR],_) = S.strip_imp(concl WFREC_THM)
   486      val ([proto_def, WFR],_) = USyntax.strip_imp(concl WFREC_THM)
   491      val dummy =
   487      val dummy =
   492            if !trace then
   488            if !trace then
   493                writeln ("ORIGINAL PROTO_DEF: " ^
   489                writeln ("ORIGINAL PROTO_DEF: " ^
   494                           Syntax.string_of_term_global thy proto_def)
   490                           Syntax.string_of_term_global thy proto_def)
   495            else ()
   491            else ()
   496      val R1 = S.rand WFR
   492      val R1 = USyntax.rand WFR
   497      val corollary' = R.UNDISCH(R.UNDISCH WFREC_THM)
   493      val corollary' = Rules.UNDISCH (Rules.UNDISCH WFREC_THM)
   498      val corollaries = map (fn pat => R.SPEC (tych pat) corollary') given_pats
   494      val corollaries = map (fn pat => Rules.SPEC (tych pat) corollary') given_pats
   499      val corollaries' = map (rewrite_rule case_rewrites) corollaries
   495      val corollaries' = map (rewrite_rule case_rewrites) corollaries
   500      fun extract X = R.CONTEXT_REWRITE_RULE
   496      fun extract X = Rules.CONTEXT_REWRITE_RULE
   501                        (f, R1::SV, @{thm cut_apply}, tflCongs@context_congs) X
   497                        (f, R1::SV, @{thm cut_apply}, tflCongs@context_congs) X
   502  in {proto_def = proto_def,
   498  in {proto_def = proto_def,
   503      SV=SV,
   499      SV=SV,
   504      WFR=WFR,
   500      WFR=WFR,
   505      pats=pats,
   501      pats=pats,
   515  *---------------------------------------------------------------------------*)
   511  *---------------------------------------------------------------------------*)
   516 
   512 
   517 fun lazyR_def thy fid tflCongs eqns =
   513 fun lazyR_def thy fid tflCongs eqns =
   518  let val {proto_def,WFR,pats,extracta,SV} =
   514  let val {proto_def,WFR,pats,extracta,SV} =
   519            wfrec_eqns thy fid tflCongs eqns
   515            wfrec_eqns thy fid tflCongs eqns
   520      val R1 = S.rand WFR
   516      val R1 = USyntax.rand WFR
   521      val f = #lhs(S.dest_eq proto_def)
   517      val f = #lhs(USyntax.dest_eq proto_def)
   522      val (extractants,TCl) = ListPair.unzip extracta
   518      val (extractants,TCl) = ListPair.unzip extracta
   523      val dummy = if !trace
   519      val dummy = if !trace
   524                  then writeln (cat_lines ("Extractants =" ::
   520                  then writeln (cat_lines ("Extractants =" ::
   525                   map (Display.string_of_thm_global thy) extractants))
   521                   map (Display.string_of_thm_global thy) extractants))
   526                  else ()
   522                  else ()
   527      val TCs = fold_rev (union (op aconv)) TCl []
   523      val TCs = fold_rev (union (op aconv)) TCl []
   528      val full_rqt = WFR::TCs
   524      val full_rqt = WFR::TCs
   529      val R' = S.mk_select{Bvar=R1, Body=S.list_mk_conj full_rqt}
   525      val R' = USyntax.mk_select{Bvar=R1, Body=USyntax.list_mk_conj full_rqt}
   530      val R'abs = S.rand R'
   526      val R'abs = USyntax.rand R'
   531      val proto_def' = subst_free[(R1,R')] proto_def
   527      val proto_def' = subst_free[(R1,R')] proto_def
   532      val dummy = if !trace then writeln ("proto_def' = " ^
   528      val dummy = if !trace then writeln ("proto_def' = " ^
   533                                          Syntax.string_of_term_global
   529                                          Syntax.string_of_term_global
   534                                          thy proto_def')
   530                                          thy proto_def')
   535                            else ()
   531                            else ()
   536      val {lhs,rhs} = S.dest_eq proto_def'
   532      val {lhs,rhs} = USyntax.dest_eq proto_def'
   537      val (c,args) = S.strip_comb lhs
   533      val (c,args) = USyntax.strip_comb lhs
   538      val (name,Ty) = dest_atom c
   534      val (name,Ty) = dest_atom c
   539      val defn = const_def thy (name, Ty, S.list_mk_abs (args,rhs))
   535      val defn = const_def thy (name, Ty, USyntax.list_mk_abs (args,rhs))
   540      val ([def0], theory) =
   536      val ([def0], theory) =
   541        thy
   537        thy
   542        |> Global_Theory.add_defs false
   538        |> Global_Theory.add_defs false
   543             [Thm.no_attributes (Binding.name (fid ^ "_def"), defn)]
   539             [Thm.no_attributes (Binding.name (fid ^ "_def"), defn)]
   544      val def = Thm.unvarify_global def0;
   540      val def = Thm.unvarify_global def0;
   545      val dummy =
   541      val dummy =
   546        if !trace then writeln ("DEF = " ^ Display.string_of_thm_global theory def)
   542        if !trace then writeln ("DEF = " ^ Display.string_of_thm_global theory def)
   547        else ()
   543        else ()
   548      (* val fconst = #lhs(S.dest_eq(concl def))  *)
   544      (* val fconst = #lhs(USyntax.dest_eq(concl def))  *)
   549      val tych = Thry.typecheck theory
   545      val tych = Thry.typecheck theory
   550      val full_rqt_prop = map (Dcterm.mk_prop o tych) full_rqt
   546      val full_rqt_prop = map (Dcterm.mk_prop o tych) full_rqt
   551          (*lcp: a lot of object-logic inference to remove*)
   547          (*lcp: a lot of object-logic inference to remove*)
   552      val baz = R.DISCH_ALL
   548      val baz = Rules.DISCH_ALL
   553                  (fold_rev R.DISCH full_rqt_prop
   549                  (fold_rev Rules.DISCH full_rqt_prop
   554                   (R.LIST_CONJ extractants))
   550                   (Rules.LIST_CONJ extractants))
   555      val dum = if !trace then writeln ("baz = " ^ Display.string_of_thm_global theory baz)
   551      val dum = if !trace then writeln ("baz = " ^ Display.string_of_thm_global theory baz)
   556                            else ()
   552                            else ()
   557      val f_free = Free (fid, fastype_of f)  (*'cos f is a Const*)
   553      val f_free = Free (fid, fastype_of f)  (*'cos f is a Const*)
   558      val SV' = map tych SV;
   554      val SV' = map tych SV;
   559      val SVrefls = map Thm.reflexive SV'
   555      val SVrefls = map Thm.reflexive SV'
   560      val def0 = (fold (fn x => fn th => R.rbeta(Thm.combination th x))
   556      val def0 = (fold (fn x => fn th => Rules.rbeta(Thm.combination th x))
   561                    SVrefls def)
   557                    SVrefls def)
   562                 RS meta_eq_to_obj_eq
   558                 RS meta_eq_to_obj_eq
   563      val def' = R.MP (R.SPEC (tych R') (R.GEN (tych R1) baz)) def0
   559      val def' = Rules.MP (Rules.SPEC (tych R') (Rules.GEN (tych R1) baz)) def0
   564      val body_th = R.LIST_CONJ (map R.ASSUME full_rqt_prop)
   560      val body_th = Rules.LIST_CONJ (map Rules.ASSUME full_rqt_prop)
   565      val SELECT_AX = (*in this way we hope to avoid a STATIC dependence upon
   561      val SELECT_AX = (*in this way we hope to avoid a STATIC dependence upon
   566                        theory Hilbert_Choice*)
   562                        theory Hilbert_Choice*)
   567          ML_Context.thm "Hilbert_Choice.tfl_some"
   563          ML_Context.thm "Hilbert_Choice.tfl_some"
   568          handle ERROR msg => cat_error msg
   564          handle ERROR msg => cat_error msg
   569     "defer_recdef requires theory Main or at least Hilbert_Choice as parent"
   565     "defer_recdef requires theory Main or at least Hilbert_Choice as parent"
   570      val bar = R.MP (R.ISPECL[tych R'abs, tych R1] SELECT_AX) body_th
   566      val bar = Rules.MP (Rules.ISPECL[tych R'abs, tych R1] SELECT_AX) body_th
   571  in {theory = theory, R=R1, SV=SV,
   567  in {theory = theory, R=R1, SV=SV,
   572      rules = fold (U.C R.MP) (R.CONJUNCTS bar) def',
   568      rules = fold (Utils.C Rules.MP) (Rules.CONJUNCTS bar) def',
   573      full_pats_TCs = merge (map pat_of pats) (ListPair.zip (givens pats, TCl)),
   569      full_pats_TCs = merge (map pat_of pats) (ListPair.zip (givens pats, TCl)),
   574      patterns = pats}
   570      patterns = pats}
   575  end;
   571  end;
   576 
   572 
   577 
   573 
   601  * aspect of the nchotomy theorem, we make the correspondence explicit by
   597  * aspect of the nchotomy theorem, we make the correspondence explicit by
   602  * pairing the incoming new variable with the term it gets beta-reduced into.
   598  * pairing the incoming new variable with the term it gets beta-reduced into.
   603  *---------------------------------------------------------------------------*)
   599  *---------------------------------------------------------------------------*)
   604 
   600 
   605 fun alpha_ex_unroll (xlist, tm) =
   601 fun alpha_ex_unroll (xlist, tm) =
   606   let val (qvars,body) = S.strip_exists tm
   602   let val (qvars,body) = USyntax.strip_exists tm
   607       val vlist = #2(S.strip_comb (S.rhs body))
   603       val vlist = #2 (USyntax.strip_comb (USyntax.rhs body))
   608       val plist = ListPair.zip (vlist, xlist)
   604       val plist = ListPair.zip (vlist, xlist)
   609       val args = map (the o AList.lookup (op aconv) plist) qvars
   605       val args = map (the o AList.lookup (op aconv) plist) qvars
   610                    handle Option => raise Fail "TFL.alpha_ex_unroll: no correspondence"
   606                    handle Option => raise Fail "TFL.alpha_ex_unroll: no correspondence"
   611       fun build ex      []   = []
   607       fun build ex      []   = []
   612         | build (_$rex) (v::rst) =
   608         | build (_$rex) (v::rst) =
   632  val tych = Thry.typecheck thy
   628  val tych = Thry.typecheck thy
   633  fun tych_binding(x,y) = (tych x, tych y)
   629  fun tych_binding(x,y) = (tych x, tych y)
   634  fun fail s = raise TFL_ERR "mk_case" s
   630  fun fail s = raise TFL_ERR "mk_case" s
   635  fun mk{rows=[],...} = fail"no rows"
   631  fun mk{rows=[],...} = fail"no rows"
   636    | mk{path=[], rows = [([], (thm, bindings))]} =
   632    | mk{path=[], rows = [([], (thm, bindings))]} =
   637                          R.IT_EXISTS (map tych_binding bindings) thm
   633                          Rules.IT_EXISTS (map tych_binding bindings) thm
   638    | mk{path = u::rstp, rows as (p::_, _)::_} =
   634    | mk{path = u::rstp, rows as (p::_, _)::_} =
   639      let val (pat_rectangle,rights) = ListPair.unzip rows
   635      let val (pat_rectangle,rights) = ListPair.unzip rows
   640          val col0 = map hd pat_rectangle
   636          val col0 = map hd pat_rectangle
   641          val pat_rectangle' = map tl pat_rectangle
   637          val pat_rectangle' = map tl pat_rectangle
   642      in
   638      in
   649      let val Type (ty_name,_) = type_of p
   645      let val Type (ty_name,_) = type_of p
   650      in
   646      in
   651      case (ty_info ty_name)
   647      case (ty_info ty_name)
   652      of NONE => fail("Not a known datatype: "^ty_name)
   648      of NONE => fail("Not a known datatype: "^ty_name)
   653       | SOME{constructors,nchotomy} =>
   649       | SOME{constructors,nchotomy} =>
   654         let val thm' = R.ISPEC (tych u) nchotomy
   650         let val thm' = Rules.ISPEC (tych u) nchotomy
   655             val disjuncts = S.strip_disj (concl thm')
   651             val disjuncts = USyntax.strip_disj (concl thm')
   656             val subproblems = divide(constructors, rows)
   652             val subproblems = divide(constructors, rows)
   657             val groups      = map #group subproblems
   653             val groups      = map #group subproblems
   658             and new_formals = map #new_formals subproblems
   654             and new_formals = map #new_formals subproblems
   659             val existentials = ListPair.map alpha_ex_unroll
   655             val existentials = ListPair.map alpha_ex_unroll
   660                                    (new_formals, disjuncts)
   656                                    (new_formals, disjuncts)
   661             val constraints = map #1 existentials
   657             val constraints = map #1 existentials
   662             val vexl = map #2 existentials
   658             val vexl = map #2 existentials
   663             fun expnd tm (pats,(th,b)) = (pats,(R.SUBS[R.ASSUME(tych tm)]th,b))
   659             fun expnd tm (pats,(th,b)) = (pats, (Rules.SUBS [Rules.ASSUME (tych tm)] th, b))
   664             val news = map (fn (nf,rows,c) => {path = nf@rstp,
   660             val news = map (fn (nf,rows,c) => {path = nf@rstp,
   665                                                rows = map (expnd c) rows})
   661                                                rows = map (expnd c) rows})
   666                            (U.zip3 new_formals groups constraints)
   662                            (Utils.zip3 new_formals groups constraints)
   667             val recursive_thms = map mk news
   663             val recursive_thms = map mk news
   668             val build_exists = Library.foldr
   664             val build_exists = Library.foldr
   669                                 (fn((x,t), th) =>
   665                                 (fn((x,t), th) =>
   670                                  R.CHOOSE (tych x, R.ASSUME (tych t)) th)
   666                                  Rules.CHOOSE (tych x, Rules.ASSUME (tych t)) th)
   671             val thms' = ListPair.map build_exists (vexl, recursive_thms)
   667             val thms' = ListPair.map build_exists (vexl, recursive_thms)
   672             val same_concls = R.EVEN_ORS thms'
   668             val same_concls = Rules.EVEN_ORS thms'
   673         in R.DISJ_CASESL thm' same_concls
   669         in Rules.DISJ_CASESL thm' same_concls
   674         end
   670         end
   675      end end
   671      end end
   676  in mk
   672  in mk
   677  end;
   673  end;
   678 
   674 
   686      val aname = Name.variant names "a"
   682      val aname = Name.variant names "a"
   687      val vname = Name.variant (aname::names) "v"
   683      val vname = Name.variant (aname::names) "v"
   688      val a = Free (aname, T)
   684      val a = Free (aname, T)
   689      val v = Free (vname, T)
   685      val v = Free (vname, T)
   690      val a_eq_v = HOLogic.mk_eq(a,v)
   686      val a_eq_v = HOLogic.mk_eq(a,v)
   691      val ex_th0 = R.EXISTS (tych (S.mk_exists{Bvar=v,Body=a_eq_v}), tych a)
   687      val ex_th0 = Rules.EXISTS (tych (USyntax.mk_exists{Bvar=v,Body=a_eq_v}), tych a)
   692                            (R.REFL (tych a))
   688                            (Rules.REFL (tych a))
   693      val th0 = R.ASSUME (tych a_eq_v)
   689      val th0 = Rules.ASSUME (tych a_eq_v)
   694      val rows = map (fn x => ([x], (th0,[]))) pats
   690      val rows = map (fn x => ([x], (th0,[]))) pats
   695  in
   691  in
   696  R.GEN (tych a)
   692  Rules.GEN (tych a)
   697        (R.RIGHT_ASSOC
   693        (Rules.RIGHT_ASSOC
   698           (R.CHOOSE(tych v, ex_th0)
   694           (Rules.CHOOSE(tych v, ex_th0)
   699                 (mk_case ty_info (vname::aname::names)
   695                 (mk_case ty_info (vname::aname::names)
   700                  thy {path=[v], rows=rows})))
   696                  thy {path=[v], rows=rows})))
   701  end end;
   697  end end;
   702 
   698 
   703 
   699 
   710  *
   706  *
   711  * Note. When the context is empty, there can be no local variables.
   707  * Note. When the context is empty, there can be no local variables.
   712  *---------------------------------------------------------------------------*)
   708  *---------------------------------------------------------------------------*)
   713 (*
   709 (*
   714 local infix 5 ==>
   710 local infix 5 ==>
   715       fun (tm1 ==> tm2) = S.mk_imp{ant = tm1, conseq = tm2}
   711       fun (tm1 ==> tm2) = USyntax.mk_imp{ant = tm1, conseq = tm2}
   716 in
   712 in
   717 fun build_ih f P (pat,TCs) =
   713 fun build_ih f P (pat,TCs) =
   718  let val globals = S.free_vars_lr pat
   714  let val globals = USyntax.free_vars_lr pat
   719      fun nested tm = is_some (S.find_term (curry (op aconv) f) tm)
   715      fun nested tm = is_some (USyntax.find_term (curry (op aconv) f) tm)
   720      fun dest_TC tm =
   716      fun dest_TC tm =
   721          let val (cntxt,R_y_pat) = S.strip_imp(#2(S.strip_forall tm))
   717          let val (cntxt,R_y_pat) = USyntax.strip_imp(#2(USyntax.strip_forall tm))
   722              val (R,y,_) = S.dest_relation R_y_pat
   718              val (R,y,_) = USyntax.dest_relation R_y_pat
   723              val P_y = if (nested tm) then R_y_pat ==> P$y else P$y
   719              val P_y = if (nested tm) then R_y_pat ==> P$y else P$y
   724          in case cntxt
   720          in case cntxt
   725               of [] => (P_y, (tm,[]))
   721               of [] => (P_y, (tm,[]))
   726                | _  => let
   722                | _  => let
   727                     val imp = S.list_mk_conj cntxt ==> P_y
   723                     val imp = USyntax.list_mk_conj cntxt ==> P_y
   728                     val lvs = gen_rems (op aconv) (S.free_vars_lr imp, globals)
   724                     val lvs = gen_rems (op aconv) (USyntax.free_vars_lr imp, globals)
   729                     val locals = #2(U.pluck (curry (op aconv) P) lvs) handle U.ERR _ => lvs
   725                     val locals = #2(Utils.pluck (curry (op aconv) P) lvs) handle Utils.ERR _ => lvs
   730                     in (S.list_mk_forall(locals,imp), (tm,locals)) end
   726                     in (USyntax.list_mk_forall(locals,imp), (tm,locals)) end
   731          end
   727          end
   732  in case TCs
   728  in case TCs
   733     of [] => (S.list_mk_forall(globals, P$pat), [])
   729     of [] => (USyntax.list_mk_forall(globals, P$pat), [])
   734      |  _ => let val (ihs, TCs_locals) = ListPair.unzip(map dest_TC TCs)
   730      |  _ => let val (ihs, TCs_locals) = ListPair.unzip(map dest_TC TCs)
   735                  val ind_clause = S.list_mk_conj ihs ==> P$pat
   731                  val ind_clause = USyntax.list_mk_conj ihs ==> P$pat
   736              in (S.list_mk_forall(globals,ind_clause), TCs_locals)
   732              in (USyntax.list_mk_forall(globals,ind_clause), TCs_locals)
   737              end
   733              end
   738  end
   734  end
   739 end;
   735 end;
   740 *)
   736 *)
   741 
   737 
   742 local infix 5 ==>
   738 local infix 5 ==>
   743       fun (tm1 ==> tm2) = S.mk_imp{ant = tm1, conseq = tm2}
   739       fun (tm1 ==> tm2) = USyntax.mk_imp{ant = tm1, conseq = tm2}
   744 in
   740 in
   745 fun build_ih f (P,SV) (pat,TCs) =
   741 fun build_ih f (P,SV) (pat,TCs) =
   746  let val pat_vars = S.free_vars_lr pat
   742  let val pat_vars = USyntax.free_vars_lr pat
   747      val globals = pat_vars@SV
   743      val globals = pat_vars@SV
   748      fun nested tm = is_some (S.find_term (curry (op aconv) f) tm)
   744      fun nested tm = is_some (USyntax.find_term (curry (op aconv) f) tm)
   749      fun dest_TC tm =
   745      fun dest_TC tm =
   750          let val (cntxt,R_y_pat) = S.strip_imp(#2(S.strip_forall tm))
   746          let val (cntxt,R_y_pat) = USyntax.strip_imp(#2(USyntax.strip_forall tm))
   751              val (R,y,_) = S.dest_relation R_y_pat
   747              val (R,y,_) = USyntax.dest_relation R_y_pat
   752              val P_y = if (nested tm) then R_y_pat ==> P$y else P$y
   748              val P_y = if (nested tm) then R_y_pat ==> P$y else P$y
   753          in case cntxt
   749          in case cntxt
   754               of [] => (P_y, (tm,[]))
   750               of [] => (P_y, (tm,[]))
   755                | _  => let
   751                | _  => let
   756                     val imp = S.list_mk_conj cntxt ==> P_y
   752                     val imp = USyntax.list_mk_conj cntxt ==> P_y
   757                     val lvs = subtract (op aconv) globals (S.free_vars_lr imp)
   753                     val lvs = subtract (op aconv) globals (USyntax.free_vars_lr imp)
   758                     val locals = #2(U.pluck (curry (op aconv) P) lvs) handle U.ERR _ => lvs
   754                     val locals = #2(Utils.pluck (curry (op aconv) P) lvs) handle Utils.ERR _ => lvs
   759                     in (S.list_mk_forall(locals,imp), (tm,locals)) end
   755                     in (USyntax.list_mk_forall(locals,imp), (tm,locals)) end
   760          end
   756          end
   761  in case TCs
   757  in case TCs
   762     of [] => (S.list_mk_forall(pat_vars, P$pat), [])
   758     of [] => (USyntax.list_mk_forall(pat_vars, P$pat), [])
   763      |  _ => let val (ihs, TCs_locals) = ListPair.unzip(map dest_TC TCs)
   759      |  _ => let val (ihs, TCs_locals) = ListPair.unzip(map dest_TC TCs)
   764                  val ind_clause = S.list_mk_conj ihs ==> P$pat
   760                  val ind_clause = USyntax.list_mk_conj ihs ==> P$pat
   765              in (S.list_mk_forall(pat_vars,ind_clause), TCs_locals)
   761              in (USyntax.list_mk_forall(pat_vars,ind_clause), TCs_locals)
   766              end
   762              end
   767  end
   763  end
   768 end;
   764 end;
   769 
   765 
   770 (*---------------------------------------------------------------------------
   766 (*---------------------------------------------------------------------------
   774  *           TCs = TC_1[pat] ... TC_n[pat]
   770  *           TCs = TC_1[pat] ... TC_n[pat]
   775  *           thm = ih1 /\ ... /\ ih_n |- ih[pat]
   771  *           thm = ih1 /\ ... /\ ih_n |- ih[pat]
   776  *---------------------------------------------------------------------------*)
   772  *---------------------------------------------------------------------------*)
   777 fun prove_case f thy (tm,TCs_locals,thm) =
   773 fun prove_case f thy (tm,TCs_locals,thm) =
   778  let val tych = Thry.typecheck thy
   774  let val tych = Thry.typecheck thy
   779      val antc = tych(#ant(S.dest_imp tm))
   775      val antc = tych(#ant(USyntax.dest_imp tm))
   780      val thm' = R.SPEC_ALL thm
   776      val thm' = Rules.SPEC_ALL thm
   781      fun nested tm = is_some (S.find_term (curry (op aconv) f) tm)
   777      fun nested tm = is_some (USyntax.find_term (curry (op aconv) f) tm)
   782      fun get_cntxt TC = tych(#ant(S.dest_imp(#2(S.strip_forall(concl TC)))))
   778      fun get_cntxt TC = tych(#ant(USyntax.dest_imp(#2(USyntax.strip_forall(concl TC)))))
   783      fun mk_ih ((TC,locals),th2,nested) =
   779      fun mk_ih ((TC,locals),th2,nested) =
   784          R.GENL (map tych locals)
   780          Rules.GENL (map tych locals)
   785             (if nested then R.DISCH (get_cntxt TC) th2 handle U.ERR _ => th2
   781             (if nested then Rules.DISCH (get_cntxt TC) th2 handle Utils.ERR _ => th2
   786              else if S.is_imp (concl TC) then R.IMP_TRANS TC th2
   782              else if USyntax.is_imp (concl TC) then Rules.IMP_TRANS TC th2
   787              else R.MP th2 TC)
   783              else Rules.MP th2 TC)
   788  in
   784  in
   789  R.DISCH antc
   785  Rules.DISCH antc
   790  (if S.is_imp(concl thm') (* recursive calls in this clause *)
   786  (if USyntax.is_imp(concl thm') (* recursive calls in this clause *)
   791   then let val th1 = R.ASSUME antc
   787   then let val th1 = Rules.ASSUME antc
   792            val TCs = map #1 TCs_locals
   788            val TCs = map #1 TCs_locals
   793            val ylist = map (#2 o S.dest_relation o #2 o S.strip_imp o
   789            val ylist = map (#2 o USyntax.dest_relation o #2 o USyntax.strip_imp o
   794                             #2 o S.strip_forall) TCs
   790                             #2 o USyntax.strip_forall) TCs
   795            val TClist = map (fn(TC,lvs) => (R.SPEC_ALL(R.ASSUME(tych TC)),lvs))
   791            val TClist = map (fn(TC,lvs) => (Rules.SPEC_ALL(Rules.ASSUME(tych TC)),lvs))
   796                             TCs_locals
   792                             TCs_locals
   797            val th2list = map (U.C R.SPEC th1 o tych) ylist
   793            val th2list = map (Utils.C Rules.SPEC th1 o tych) ylist
   798            val nlist = map nested TCs
   794            val nlist = map nested TCs
   799            val triples = U.zip3 TClist th2list nlist
   795            val triples = Utils.zip3 TClist th2list nlist
   800            val Pylist = map mk_ih triples
   796            val Pylist = map mk_ih triples
   801        in R.MP thm' (R.LIST_CONJ Pylist) end
   797        in Rules.MP thm' (Rules.LIST_CONJ Pylist) end
   802   else thm')
   798   else thm')
   803  end;
   799  end;
   804 
   800 
   805 
   801 
   806 (*---------------------------------------------------------------------------
   802 (*---------------------------------------------------------------------------
   810  *      ?v1 ... vn. x = (v1,...,vn) |- M[x]
   806  *      ?v1 ... vn. x = (v1,...,vn) |- M[x]
   811  *
   807  *
   812  *---------------------------------------------------------------------------*)
   808  *---------------------------------------------------------------------------*)
   813 fun LEFT_ABS_VSTRUCT tych thm =
   809 fun LEFT_ABS_VSTRUCT tych thm =
   814   let fun CHOOSER v (tm,thm) =
   810   let fun CHOOSER v (tm,thm) =
   815         let val ex_tm = S.mk_exists{Bvar=v,Body=tm}
   811         let val ex_tm = USyntax.mk_exists{Bvar=v,Body=tm}
   816         in (ex_tm, R.CHOOSE(tych v, R.ASSUME (tych ex_tm)) thm)
   812         in (ex_tm, Rules.CHOOSE(tych v, Rules.ASSUME (tych ex_tm)) thm)
   817         end
   813         end
   818       val [veq] = filter (can S.dest_eq) (#1 (R.dest_thm thm))
   814       val [veq] = filter (can USyntax.dest_eq) (#1 (Rules.dest_thm thm))
   819       val {lhs,rhs} = S.dest_eq veq
   815       val {lhs,rhs} = USyntax.dest_eq veq
   820       val L = S.free_vars_lr rhs
   816       val L = USyntax.free_vars_lr rhs
   821   in  #2 (fold_rev CHOOSER L (veq,thm))  end;
   817   in  #2 (fold_rev CHOOSER L (veq,thm))  end;
   822 
   818 
   823 
   819 
   824 (*----------------------------------------------------------------------------
   820 (*----------------------------------------------------------------------------
   825  * Input : f, R,  and  [(pat1,TCs1),..., (patn,TCsn)]
   821  * Input : f, R,  and  [(pat1,TCs1),..., (patn,TCsn)]
   828  * recursion induction (Rinduct) by proving the antecedent of Sinduct from
   824  * recursion induction (Rinduct) by proving the antecedent of Sinduct from
   829  * the antecedent of Rinduct.
   825  * the antecedent of Rinduct.
   830  *---------------------------------------------------------------------------*)
   826  *---------------------------------------------------------------------------*)
   831 fun mk_induction thy {fconst, R, SV, pat_TCs_list} =
   827 fun mk_induction thy {fconst, R, SV, pat_TCs_list} =
   832 let val tych = Thry.typecheck thy
   828 let val tych = Thry.typecheck thy
   833     val Sinduction = R.UNDISCH (R.ISPEC (tych R) Thms.WF_INDUCTION_THM)
   829     val Sinduction = Rules.UNDISCH (Rules.ISPEC (tych R) Thms.WF_INDUCTION_THM)
   834     val (pats,TCsl) = ListPair.unzip pat_TCs_list
   830     val (pats,TCsl) = ListPair.unzip pat_TCs_list
   835     val case_thm = complete_cases thy pats
   831     val case_thm = complete_cases thy pats
   836     val domain = (type_of o hd) pats
   832     val domain = (type_of o hd) pats
   837     val Pname = Name.variant (List.foldr (Library.foldr OldTerm.add_term_names)
   833     val Pname = Name.variant (List.foldr (Library.foldr OldTerm.add_term_names)
   838                               [] (pats::TCsl)) "P"
   834                               [] (pats::TCsl)) "P"
   839     val P = Free(Pname, domain --> HOLogic.boolT)
   835     val P = Free(Pname, domain --> HOLogic.boolT)
   840     val Sinduct = R.SPEC (tych P) Sinduction
   836     val Sinduct = Rules.SPEC (tych P) Sinduction
   841     val Sinduct_assumf = S.rand ((#ant o S.dest_imp o concl) Sinduct)
   837     val Sinduct_assumf = USyntax.rand ((#ant o USyntax.dest_imp o concl) Sinduct)
   842     val Rassums_TCl' = map (build_ih fconst (P,SV)) pat_TCs_list
   838     val Rassums_TCl' = map (build_ih fconst (P,SV)) pat_TCs_list
   843     val (Rassums,TCl') = ListPair.unzip Rassums_TCl'
   839     val (Rassums,TCl') = ListPair.unzip Rassums_TCl'
   844     val Rinduct_assum = R.ASSUME (tych (S.list_mk_conj Rassums))
   840     val Rinduct_assum = Rules.ASSUME (tych (USyntax.list_mk_conj Rassums))
   845     val cases = map (fn pat => Term.betapply (Sinduct_assumf, pat)) pats
   841     val cases = map (fn pat => Term.betapply (Sinduct_assumf, pat)) pats
   846     val tasks = U.zip3 cases TCl' (R.CONJUNCTS Rinduct_assum)
   842     val tasks = Utils.zip3 cases TCl' (Rules.CONJUNCTS Rinduct_assum)
   847     val proved_cases = map (prove_case fconst thy) tasks
   843     val proved_cases = map (prove_case fconst thy) tasks
   848     val v = Free (Name.variant (List.foldr OldTerm.add_term_names [] (map concl proved_cases))
   844     val v = Free (Name.variant (List.foldr OldTerm.add_term_names [] (map concl proved_cases))
   849                     "v",
   845                     "v",
   850                   domain)
   846                   domain)
   851     val vtyped = tych v
   847     val vtyped = tych v
   852     val substs = map (R.SYM o R.ASSUME o tych o (curry HOLogic.mk_eq v)) pats
   848     val substs = map (Rules.SYM o Rules.ASSUME o tych o (curry HOLogic.mk_eq v)) pats
   853     val proved_cases1 = ListPair.map (fn (th,th') => R.SUBS[th]th')
   849     val proved_cases1 = ListPair.map (fn (th,th') => Rules.SUBS[th]th')
   854                           (substs, proved_cases)
   850                           (substs, proved_cases)
   855     val abs_cases = map (LEFT_ABS_VSTRUCT tych) proved_cases1
   851     val abs_cases = map (LEFT_ABS_VSTRUCT tych) proved_cases1
   856     val dant = R.GEN vtyped (R.DISJ_CASESL (R.ISPEC vtyped case_thm) abs_cases)
   852     val dant = Rules.GEN vtyped (Rules.DISJ_CASESL (Rules.ISPEC vtyped case_thm) abs_cases)
   857     val dc = R.MP Sinduct dant
   853     val dc = Rules.MP Sinduct dant
   858     val Parg_ty = type_of(#Bvar(S.dest_forall(concl dc)))
   854     val Parg_ty = type_of(#Bvar(USyntax.dest_forall(concl dc)))
   859     val vars = map (gvvariant[Pname]) (S.strip_prod_type Parg_ty)
   855     val vars = map (gvvariant[Pname]) (USyntax.strip_prod_type Parg_ty)
   860     val dc' = fold_rev (R.GEN o tych) vars
   856     val dc' = fold_rev (Rules.GEN o tych) vars
   861                        (R.SPEC (tych(S.mk_vstruct Parg_ty vars)) dc)
   857                        (Rules.SPEC (tych(USyntax.mk_vstruct Parg_ty vars)) dc)
   862 in
   858 in
   863    R.GEN (tych P) (R.DISCH (tych(concl Rinduct_assum)) dc')
   859    Rules.GEN (tych P) (Rules.DISCH (tych(concl Rinduct_assum)) dc')
   864 end
   860 end
   865 handle U.ERR _ => raise TFL_ERR "mk_induction" "failed derivation";
   861 handle Utils.ERR _ => raise TFL_ERR "mk_induction" "failed derivation";
   866 
   862 
   867 
   863 
   868 
   864 
   869 
   865 
   870 (*---------------------------------------------------------------------------
   866 (*---------------------------------------------------------------------------
   874  *---------------------------------------------------------------------------*)
   870  *---------------------------------------------------------------------------*)
   875 
   871 
   876 
   872 
   877 fun simplify_induction thy hth ind =
   873 fun simplify_induction thy hth ind =
   878   let val tych = Thry.typecheck thy
   874   let val tych = Thry.typecheck thy
   879       val (asl,_) = R.dest_thm ind
   875       val (asl,_) = Rules.dest_thm ind
   880       val (_,tc_eq_tc') = R.dest_thm hth
   876       val (_,tc_eq_tc') = Rules.dest_thm hth
   881       val tc = S.lhs tc_eq_tc'
   877       val tc = USyntax.lhs tc_eq_tc'
   882       fun loop [] = ind
   878       fun loop [] = ind
   883         | loop (asm::rst) =
   879         | loop (asm::rst) =
   884           if (can (Thry.match_term thy asm) tc)
   880           if (can (Thry.match_term thy asm) tc)
   885           then R.UNDISCH
   881           then Rules.UNDISCH
   886                  (R.MATCH_MP
   882                  (Rules.MATCH_MP
   887                      (R.MATCH_MP Thms.simp_thm (R.DISCH (tych asm) ind))
   883                      (Rules.MATCH_MP Thms.simp_thm (Rules.DISCH (tych asm) ind))
   888                      hth)
   884                      hth)
   889          else loop rst
   885          else loop rst
   890   in loop asl
   886   in loop asl
   891 end;
   887 end;
   892 
   888 
   894 (*---------------------------------------------------------------------------
   890 (*---------------------------------------------------------------------------
   895  * The termination condition is an antecedent to the rule, and an
   891  * The termination condition is an antecedent to the rule, and an
   896  * assumption to the theorem.
   892  * assumption to the theorem.
   897  *---------------------------------------------------------------------------*)
   893  *---------------------------------------------------------------------------*)
   898 fun elim_tc tcthm (rule,induction) =
   894 fun elim_tc tcthm (rule,induction) =
   899    (R.MP rule tcthm, R.PROVE_HYP tcthm induction)
   895    (Rules.MP rule tcthm, Rules.PROVE_HYP tcthm induction)
   900 
   896 
   901 
   897 
   902 fun trace_thms s L =
   898 fun trace_thms s L =
   903   if !trace then writeln (cat_lines (s :: map Display.string_of_thm_without_context L))
   899   if !trace then writeln (cat_lines (s :: map Display.string_of_thm_without_context L))
   904   else ();
   900   else ();
   909   else ();
   905   else ();
   910 
   906 
   911 
   907 
   912 fun postprocess strict {wf_tac, terminator, simplifier} theory {rules,induction,TCs} =
   908 fun postprocess strict {wf_tac, terminator, simplifier} theory {rules,induction,TCs} =
   913 let val tych = Thry.typecheck theory
   909 let val tych = Thry.typecheck theory
   914     val prove = R.prove strict;
   910     val prove = Rules.prove strict;
   915 
   911 
   916    (*---------------------------------------------------------------------
   912    (*---------------------------------------------------------------------
   917     * Attempt to eliminate WF condition. It's the only assumption of rules
   913     * Attempt to eliminate WF condition. It's the only assumption of rules
   918     *---------------------------------------------------------------------*)
   914     *---------------------------------------------------------------------*)
   919    val (rules1,induction1)  =
   915    val (rules1,induction1)  =
   920        let val thm = prove(tych(HOLogic.mk_Trueprop
   916        let val thm = prove(tych(HOLogic.mk_Trueprop
   921                                   (hd(#1(R.dest_thm rules)))),
   917                                   (hd(#1(Rules.dest_thm rules)))),
   922                              wf_tac)
   918                              wf_tac)
   923        in (R.PROVE_HYP thm rules,  R.PROVE_HYP thm induction)
   919        in (Rules.PROVE_HYP thm rules, Rules.PROVE_HYP thm induction)
   924        end handle U.ERR _ => (rules,induction);
   920        end handle Utils.ERR _ => (rules,induction);
   925 
   921 
   926    (*----------------------------------------------------------------------
   922    (*----------------------------------------------------------------------
   927     * The termination condition (tc) is simplified to |- tc = tc' (there
   923     * The termination condition (tc) is simplified to |- tc = tc' (there
   928     * might not be a change!) and then 3 attempts are made:
   924     * might not be a change!) and then 3 attempts are made:
   929     *
   925     *
   936        let val tc1 = tych tc
   932        let val tc1 = tych tc
   937            val _ = trace_cterm "TC before simplification: " tc1
   933            val _ = trace_cterm "TC before simplification: " tc1
   938            val tc_eq = simplifier tc1
   934            val tc_eq = simplifier tc1
   939            val _ = trace_thms "result: " [tc_eq]
   935            val _ = trace_thms "result: " [tc_eq]
   940        in
   936        in
   941        elim_tc (R.MATCH_MP Thms.eqT tc_eq) (r,ind)
   937        elim_tc (Rules.MATCH_MP Thms.eqT tc_eq) (r,ind)
   942        handle U.ERR _ =>
   938        handle Utils.ERR _ =>
   943         (elim_tc (R.MATCH_MP(R.MATCH_MP Thms.rev_eq_mp tc_eq)
   939         (elim_tc (Rules.MATCH_MP(Rules.MATCH_MP Thms.rev_eq_mp tc_eq)
   944                   (prove(tych(HOLogic.mk_Trueprop(S.rhs(concl tc_eq))),
   940                   (prove(tych(HOLogic.mk_Trueprop(USyntax.rhs(concl tc_eq))),
   945                            terminator)))
   941                            terminator)))
   946                  (r,ind)
   942                  (r,ind)
   947          handle U.ERR _ =>
   943          handle Utils.ERR _ =>
   948           (R.UNDISCH(R.MATCH_MP (R.MATCH_MP Thms.simp_thm r) tc_eq),
   944           (Rules.UNDISCH(Rules.MATCH_MP (Rules.MATCH_MP Thms.simp_thm r) tc_eq),
   949            simplify_induction theory tc_eq ind))
   945            simplify_induction theory tc_eq ind))
   950        end
   946        end
   951 
   947 
   952    (*----------------------------------------------------------------------
   948    (*----------------------------------------------------------------------
   953     * Nested termination conditions are harder to get at, since they are
   949     * Nested termination conditions are harder to get at, since they are
   961     *   1. if |- tc = T, then return |- tc; otherwise,
   957     *   1. if |- tc = T, then return |- tc; otherwise,
   962     *   2. apply the terminator to tc'. If |- tc' = T then return |- tc; else
   958     *   2. apply the terminator to tc'. If |- tc' = T then return |- tc; else
   963     *   3. return |- tc = tc'
   959     *   3. return |- tc = tc'
   964     *---------------------------------------------------------------------*)
   960     *---------------------------------------------------------------------*)
   965    fun simplify_nested_tc tc =
   961    fun simplify_nested_tc tc =
   966       let val tc_eq = simplifier (tych (#2 (S.strip_forall tc)))
   962       let val tc_eq = simplifier (tych (#2 (USyntax.strip_forall tc)))
   967       in
   963       in
   968       R.GEN_ALL
   964       Rules.GEN_ALL
   969        (R.MATCH_MP Thms.eqT tc_eq
   965        (Rules.MATCH_MP Thms.eqT tc_eq
   970         handle U.ERR _ =>
   966         handle Utils.ERR _ =>
   971           (R.MATCH_MP(R.MATCH_MP Thms.rev_eq_mp tc_eq)
   967           (Rules.MATCH_MP(Rules.MATCH_MP Thms.rev_eq_mp tc_eq)
   972                       (prove(tych(HOLogic.mk_Trueprop (S.rhs(concl tc_eq))),
   968                       (prove(tych(HOLogic.mk_Trueprop (USyntax.rhs(concl tc_eq))),
   973                                terminator))
   969                                terminator))
   974             handle U.ERR _ => tc_eq))
   970             handle Utils.ERR _ => tc_eq))
   975       end
   971       end
   976 
   972 
   977    (*-------------------------------------------------------------------
   973    (*-------------------------------------------------------------------
   978     * Attempt to simplify the termination conditions in each rule and
   974     * Attempt to simplify the termination conditions in each rule and
   979     * in the induction theorem.
   975     * in the induction theorem.
   980     *-------------------------------------------------------------------*)
   976     *-------------------------------------------------------------------*)
   981    fun strip_imp tm = if S.is_neg tm then ([],tm) else S.strip_imp tm
   977    fun strip_imp tm = if USyntax.is_neg tm then ([],tm) else USyntax.strip_imp tm
   982    fun loop ([],extras,R,ind) = (rev R, ind, extras)
   978    fun loop ([],extras,R,ind) = (rev R, ind, extras)
   983      | loop ((r,ftcs)::rst, nthms, R, ind) =
   979      | loop ((r,ftcs)::rst, nthms, R, ind) =
   984         let val tcs = #1(strip_imp (concl r))
   980         let val tcs = #1(strip_imp (concl r))
   985             val extra_tcs = subtract (op aconv) tcs ftcs
   981             val extra_tcs = subtract (op aconv) tcs ftcs
   986             val extra_tc_thms = map simplify_nested_tc extra_tcs
   982             val extra_tc_thms = map simplify_nested_tc extra_tcs
   987             val (r1,ind1) = fold simplify_tc tcs (r,ind)
   983             val (r1,ind1) = fold simplify_tc tcs (r,ind)
   988             val r2 = R.FILTER_DISCH_ALL(not o S.is_WFR) r1
   984             val r2 = Rules.FILTER_DISCH_ALL(not o USyntax.is_WFR) r1
   989         in loop(rst, nthms@extra_tc_thms, r2::R, ind1)
   985         in loop(rst, nthms@extra_tc_thms, r2::R, ind1)
   990         end
   986         end
   991    val rules_tcs = ListPair.zip (R.CONJUNCTS rules1, TCs)
   987    val rules_tcs = ListPair.zip (Rules.CONJUNCTS rules1, TCs)
   992    val (rules2,ind2,extras) = loop(rules_tcs,[],[],induction1)
   988    val (rules2,ind2,extras) = loop(rules_tcs,[],[],induction1)
   993 in
   989 in
   994   {induction = ind2, rules = R.LIST_CONJ rules2, nested_tcs = extras}
   990   {induction = ind2, rules = Rules.LIST_CONJ rules2, nested_tcs = extras}
   995 end;
   991 end;
   996 
   992 
   997 
   993 
   998 end;
   994 end;