src/HOL/Tools/TFL/tfl.ML
changeset 60363 5568b16aa477
parent 60335 edac62cd7bde
child 60364 fd5052b1881f
equal deleted inserted replaced
60362:befdc10ebb42 60363:5568b16aa477
   533                            else ()
   533                            else ()
   534      val {lhs,rhs} = USyntax.dest_eq proto_def'
   534      val {lhs,rhs} = USyntax.dest_eq proto_def'
   535      val (c,args) = USyntax.strip_comb lhs
   535      val (c,args) = USyntax.strip_comb lhs
   536      val (name,Ty) = dest_atom c
   536      val (name,Ty) = dest_atom c
   537      val defn = const_def thy (name, Ty, USyntax.list_mk_abs (args,rhs))
   537      val defn = const_def thy (name, Ty, USyntax.list_mk_abs (args,rhs))
   538      val ([def0], theory) =
   538      val ([def0], thy') =
   539        thy
   539        thy
   540        |> Global_Theory.add_defs false
   540        |> Global_Theory.add_defs false
   541             [Thm.no_attributes (Binding.name (Thm.def_name fid), defn)]
   541             [Thm.no_attributes (Binding.name (Thm.def_name fid), defn)]
   542      val def = Thm.unvarify_global def0;
   542      val def = Thm.unvarify_global def0;
       
   543      val ctxt' = Syntax.init_pretty_global thy';
   543      val dummy =
   544      val dummy =
   544        if !trace then writeln ("DEF = " ^ Display.string_of_thm_global theory def)
   545        if !trace then writeln ("DEF = " ^ Display.string_of_thm ctxt' def)
   545        else ()
   546        else ()
   546      (* val fconst = #lhs(USyntax.dest_eq(concl def))  *)
   547      (* val fconst = #lhs(USyntax.dest_eq(concl def))  *)
   547      val tych = Thry.typecheck theory
   548      val tych = Thry.typecheck thy'
   548      val full_rqt_prop = map (Dcterm.mk_prop o tych) full_rqt
   549      val full_rqt_prop = map (Dcterm.mk_prop o tych) full_rqt
   549          (*lcp: a lot of object-logic inference to remove*)
   550          (*lcp: a lot of object-logic inference to remove*)
   550      val baz = Rules.DISCH_ALL
   551      val baz = Rules.DISCH_ALL
   551                  (fold_rev Rules.DISCH full_rqt_prop
   552                  (fold_rev Rules.DISCH full_rqt_prop
   552                   (Rules.LIST_CONJ extractants))
   553                   (Rules.LIST_CONJ extractants))
   553      val dum = if !trace then writeln ("baz = " ^ Display.string_of_thm_global theory baz)
   554      val dum = if !trace then writeln ("baz = " ^ Display.string_of_thm ctxt' baz) else ()
   554                            else ()
       
   555      val f_free = Free (fid, fastype_of f)  (*'cos f is a Const*)
   555      val f_free = Free (fid, fastype_of f)  (*'cos f is a Const*)
   556      val SV' = map tych SV;
   556      val SV' = map tych SV;
   557      val SVrefls = map Thm.reflexive SV'
   557      val SVrefls = map Thm.reflexive SV'
   558      val def0 = (fold (fn x => fn th => Rules.rbeta(Thm.combination th x))
   558      val def0 = (fold (fn x => fn th => Rules.rbeta(Thm.combination th x))
   559                    SVrefls def)
   559                    SVrefls def)
   560                 RS meta_eq_to_obj_eq
   560                 RS meta_eq_to_obj_eq
   561      val def' = Rules.MP (Rules.SPEC (tych R') (Rules.GEN (tych R1) baz)) def0
   561      val def' = Rules.MP (Rules.SPEC (tych R') (Rules.GEN ctxt' (tych R1) baz)) def0
   562      val body_th = Rules.LIST_CONJ (map Rules.ASSUME full_rqt_prop)
   562      val body_th = Rules.LIST_CONJ (map Rules.ASSUME full_rqt_prop)
   563      val SELECT_AX = (*in this way we hope to avoid a STATIC dependence upon
   563      val SELECT_AX = (*in this way we hope to avoid a STATIC dependence upon
   564                        theory Hilbert_Choice*)
   564                        theory Hilbert_Choice*)
   565          ML_Context.thm "Hilbert_Choice.tfl_some"
   565          ML_Context.thm "Hilbert_Choice.tfl_some"
   566          handle ERROR msg => cat_error msg
   566          handle ERROR msg => cat_error msg
   567     "defer_recdef requires theory Main or at least Hilbert_Choice as parent"
   567     "defer_recdef requires theory Main or at least Hilbert_Choice as parent"
   568      val bar = Rules.MP (Rules.ISPECL[tych R'abs, tych R1] SELECT_AX) body_th
   568      val bar = Rules.MP (Rules.ISPECL[tych R'abs, tych R1] SELECT_AX) body_th
   569  in {theory = theory, R=R1, SV=SV,
   569  in {theory = thy', R=R1, SV=SV,
   570      rules = fold (fn a => fn b => Rules.MP b a) (Rules.CONJUNCTS bar) def',
   570      rules = fold (fn a => fn b => Rules.MP b a) (Rules.CONJUNCTS bar) def',
   571      full_pats_TCs = merge (map pat_of pats) (ListPair.zip (givens pats, TCl)),
   571      full_pats_TCs = merge (map pat_of pats) (ListPair.zip (givens pats, TCl)),
   572      patterns = pats}
   572      patterns = pats}
   573  end;
   573  end;
   574 
   574 
   631  val tych = Thry.typecheck thy
   631  val tych = Thry.typecheck thy
   632  fun tych_binding(x,y) = (tych x, tych y)
   632  fun tych_binding(x,y) = (tych x, tych y)
   633  fun fail s = raise TFL_ERR "mk_case" s
   633  fun fail s = raise TFL_ERR "mk_case" s
   634  fun mk{rows=[],...} = fail"no rows"
   634  fun mk{rows=[],...} = fail"no rows"
   635    | mk{path=[], rows = [([], (thm, bindings))]} =
   635    | mk{path=[], rows = [([], (thm, bindings))]} =
   636                          Rules.IT_EXISTS (map tych_binding bindings) thm
   636                          Rules.IT_EXISTS ctxt (map tych_binding bindings) thm
   637    | mk{path = u::rstp, rows as (p::_, _)::_} =
   637    | mk{path = u::rstp, rows as (p::_, _)::_} =
   638      let val (pat_rectangle,rights) = ListPair.unzip rows
   638      let val (pat_rectangle,rights) = ListPair.unzip rows
   639          val col0 = map hd pat_rectangle
   639          val col0 = map hd pat_rectangle
   640          val pat_rectangle' = map tl pat_rectangle
   640          val pat_rectangle' = map tl pat_rectangle
   641      in
   641      in
   691      val ex_th0 = Rules.EXISTS (tych (USyntax.mk_exists{Bvar=v,Body=a_eq_v}), tych a)
   691      val ex_th0 = Rules.EXISTS (tych (USyntax.mk_exists{Bvar=v,Body=a_eq_v}), tych a)
   692                            (Rules.REFL (tych a))
   692                            (Rules.REFL (tych a))
   693      val th0 = Rules.ASSUME (tych a_eq_v)
   693      val th0 = Rules.ASSUME (tych a_eq_v)
   694      val rows = map (fn x => ([x], (th0,[]))) pats
   694      val rows = map (fn x => ([x], (th0,[]))) pats
   695  in
   695  in
   696  Rules.GEN (tych a)
   696  Rules.GEN ctxt (tych a)
   697        (Rules.RIGHT_ASSOC ctxt
   697        (Rules.RIGHT_ASSOC ctxt
   698           (Rules.CHOOSE ctxt (tych v, ex_th0)
   698           (Rules.CHOOSE ctxt (tych v, ex_th0)
   699                 (mk_case ty_info (vname::aname::names)
   699                 (mk_case ty_info (vname::aname::names)
   700                  thy {path=[v], rows=rows})))
   700                  thy {path=[v], rows=rows})))
   701  end end;
   701  end end;
   772  *
   772  *
   773  * Input  is tm = "(!y. R y pat ==> P y) ==> P pat",
   773  * Input  is tm = "(!y. R y pat ==> P y) ==> P pat",
   774  *           TCs = TC_1[pat] ... TC_n[pat]
   774  *           TCs = TC_1[pat] ... TC_n[pat]
   775  *           thm = ih1 /\ ... /\ ih_n |- ih[pat]
   775  *           thm = ih1 /\ ... /\ ih_n |- ih[pat]
   776  *---------------------------------------------------------------------------*)
   776  *---------------------------------------------------------------------------*)
   777 fun prove_case f thy (tm,TCs_locals,thm) =
   777 fun prove_case ctxt f (tm,TCs_locals,thm) =
   778  let val tych = Thry.typecheck thy
   778  let val tych = Thry.typecheck (Proof_Context.theory_of ctxt)
   779      val antc = tych(#ant(USyntax.dest_imp tm))
   779      val antc = tych(#ant(USyntax.dest_imp tm))
   780      val thm' = Rules.SPEC_ALL thm
   780      val thm' = Rules.SPEC_ALL thm
   781      fun nested tm = is_some (USyntax.find_term (curry (op aconv) f) tm)
   781      fun nested tm = is_some (USyntax.find_term (curry (op aconv) f) tm)
   782      fun get_cntxt TC = tych(#ant(USyntax.dest_imp(#2(USyntax.strip_forall(concl TC)))))
   782      fun get_cntxt TC = tych(#ant(USyntax.dest_imp(#2(USyntax.strip_forall(concl TC)))))
   783      fun mk_ih ((TC,locals),th2,nested) =
   783      fun mk_ih ((TC,locals),th2,nested) =
   784          Rules.GENL (map tych locals)
   784          Rules.GENL ctxt (map tych locals)
   785             (if nested then Rules.DISCH (get_cntxt TC) th2 handle Utils.ERR _ => th2
   785             (if nested then Rules.DISCH (get_cntxt TC) th2 handle Utils.ERR _ => th2
   786              else if USyntax.is_imp (concl TC) then Rules.IMP_TRANS TC th2
   786              else if USyntax.is_imp (concl TC) then Rules.IMP_TRANS TC th2
   787              else Rules.MP th2 TC)
   787              else Rules.MP th2 TC)
   788  in
   788  in
   789  Rules.DISCH antc
   789  Rules.DISCH antc
   843     val Rassums_TCl' = map (build_ih fconst (P,SV)) pat_TCs_list
   843     val Rassums_TCl' = map (build_ih fconst (P,SV)) pat_TCs_list
   844     val (Rassums,TCl') = ListPair.unzip Rassums_TCl'
   844     val (Rassums,TCl') = ListPair.unzip Rassums_TCl'
   845     val Rinduct_assum = Rules.ASSUME (tych (USyntax.list_mk_conj Rassums))
   845     val Rinduct_assum = Rules.ASSUME (tych (USyntax.list_mk_conj Rassums))
   846     val cases = map (fn pat => Term.betapply (Sinduct_assumf, pat)) pats
   846     val cases = map (fn pat => Term.betapply (Sinduct_assumf, pat)) pats
   847     val tasks = Utils.zip3 cases TCl' (Rules.CONJUNCTS Rinduct_assum)
   847     val tasks = Utils.zip3 cases TCl' (Rules.CONJUNCTS Rinduct_assum)
   848     val proved_cases = map (prove_case fconst thy) tasks
   848     val proved_cases = map (prove_case ctxt fconst) tasks
   849     val v =
   849     val v =
   850       Free (singleton
   850       Free (singleton
   851         (Name.variant_list (List.foldr Misc_Legacy.add_term_names [] (map concl proved_cases))) "v",
   851         (Name.variant_list (List.foldr Misc_Legacy.add_term_names [] (map concl proved_cases))) "v",
   852           domain)
   852           domain)
   853     val vtyped = tych v
   853     val vtyped = tych v
   854     val substs = map (Rules.SYM o Rules.ASSUME o tych o (curry HOLogic.mk_eq v)) pats
   854     val substs = map (Rules.SYM o Rules.ASSUME o tych o (curry HOLogic.mk_eq v)) pats
   855     val proved_cases1 = ListPair.map (fn (th,th') => Rules.SUBS ctxt [th]th')
   855     val proved_cases1 = ListPair.map (fn (th,th') => Rules.SUBS ctxt [th]th')
   856                           (substs, proved_cases)
   856                           (substs, proved_cases)
   857     val abs_cases = map (LEFT_ABS_VSTRUCT ctxt tych) proved_cases1
   857     val abs_cases = map (LEFT_ABS_VSTRUCT ctxt tych) proved_cases1
   858     val dant = Rules.GEN vtyped (Rules.DISJ_CASESL (Rules.ISPEC vtyped case_thm) abs_cases)
   858     val dant = Rules.GEN ctxt vtyped (Rules.DISJ_CASESL (Rules.ISPEC vtyped case_thm) abs_cases)
   859     val dc = Rules.MP Sinduct dant
   859     val dc = Rules.MP Sinduct dant
   860     val Parg_ty = type_of(#Bvar(USyntax.dest_forall(concl dc)))
   860     val Parg_ty = type_of(#Bvar(USyntax.dest_forall(concl dc)))
   861     val vars = map (gvvariant[Pname]) (USyntax.strip_prod_type Parg_ty)
   861     val vars = map (gvvariant[Pname]) (USyntax.strip_prod_type Parg_ty)
   862     val dc' = fold_rev (Rules.GEN o tych) vars
   862     val dc' = fold_rev (Rules.GEN ctxt o tych) vars
   863                        (Rules.SPEC (tych(USyntax.mk_vstruct Parg_ty vars)) dc)
   863                        (Rules.SPEC (tych(USyntax.mk_vstruct Parg_ty vars)) dc)
   864 in
   864 in
   865    Rules.GEN (tych P) (Rules.DISCH (tych(concl Rinduct_assum)) dc')
   865    Rules.GEN ctxt (tych P) (Rules.DISCH (tych(concl Rinduct_assum)) dc')
   866 end
   866 end
   867 handle Utils.ERR _ => raise TFL_ERR "mk_induction" "failed derivation";
   867 handle Utils.ERR _ => raise TFL_ERR "mk_induction" "failed derivation";
   868 
   868 
   869 
   869 
   870 
   870 
   964     *   3. return |- tc = tc'
   964     *   3. return |- tc = tc'
   965     *---------------------------------------------------------------------*)
   965     *---------------------------------------------------------------------*)
   966    fun simplify_nested_tc tc =
   966    fun simplify_nested_tc tc =
   967       let val tc_eq = simplifier (tych (#2 (USyntax.strip_forall tc)))
   967       let val tc_eq = simplifier (tych (#2 (USyntax.strip_forall tc)))
   968       in
   968       in
   969       Rules.GEN_ALL
   969       Rules.GEN_ALL ctxt
   970        (Rules.MATCH_MP Thms.eqT tc_eq
   970        (Rules.MATCH_MP Thms.eqT tc_eq
   971         handle Utils.ERR _ =>
   971         handle Utils.ERR _ =>
   972           (Rules.MATCH_MP(Rules.MATCH_MP Thms.rev_eq_mp tc_eq)
   972           (Rules.MATCH_MP(Rules.MATCH_MP Thms.rev_eq_mp tc_eq)
   973                       (Rules.prove ctxt strict (HOLogic.mk_Trueprop (USyntax.rhs(concl tc_eq)),
   973                       (Rules.prove ctxt strict (HOLogic.mk_Trueprop (USyntax.rhs(concl tc_eq)),
   974                                terminator))
   974                                terminator))