src/HOL/Library/old_recdef.ML
changeset 69593 3dda49e08b9d
parent 67710 cc2db3239932
child 69992 bd3c10813cc4
equal deleted inserted replaced
69592:a80d8ec6c998 69593:3dda49e08b9d
   458  *
   458  *
   459  *                            Types
   459  *                            Types
   460  *
   460  *
   461  *---------------------------------------------------------------------------*)
   461  *---------------------------------------------------------------------------*)
   462 val mk_prim_vartype = TVar;
   462 val mk_prim_vartype = TVar;
   463 fun mk_vartype s = mk_prim_vartype ((s, 0), @{sort type});
   463 fun mk_vartype s = mk_prim_vartype ((s, 0), \<^sort>\<open>type\<close>);
   464 
   464 
   465 (* But internally, it's useful *)
   465 (* But internally, it's useful *)
   466 fun dest_vtype (TVar x) = x
   466 fun dest_vtype (TVar x) = x
   467   | dest_vtype _ = raise USYN_ERR "dest_vtype" "not a flexible type variable";
   467   | dest_vtype _ = raise USYN_ERR "dest_vtype" "not a flexible type variable";
   468 
   468 
   512   | mk_abs{Bvar as Free(s,ty),Body}  = Abs(s,ty,abstract_over(Bvar,Body))
   512   | mk_abs{Bvar as Free(s,ty),Body}  = Abs(s,ty,abstract_over(Bvar,Body))
   513   | mk_abs _ = raise USYN_ERR "mk_abs" "Bvar is not a variable";
   513   | mk_abs _ = raise USYN_ERR "mk_abs" "Bvar is not a variable";
   514 
   514 
   515 
   515 
   516 fun mk_imp{ant,conseq} =
   516 fun mk_imp{ant,conseq} =
   517    let val c = Const(@{const_name HOL.implies},HOLogic.boolT --> HOLogic.boolT --> HOLogic.boolT)
   517    let val c = Const(\<^const_name>\<open>HOL.implies\<close>,HOLogic.boolT --> HOLogic.boolT --> HOLogic.boolT)
   518    in list_comb(c,[ant,conseq])
   518    in list_comb(c,[ant,conseq])
   519    end;
   519    end;
   520 
   520 
   521 fun mk_select (r as {Bvar,Body}) =
   521 fun mk_select (r as {Bvar,Body}) =
   522   let val ty = type_of Bvar
   522   let val ty = type_of Bvar
   523       val c = Const(@{const_name Eps},(ty --> HOLogic.boolT) --> ty)
   523       val c = Const(\<^const_name>\<open>Eps\<close>,(ty --> HOLogic.boolT) --> ty)
   524   in list_comb(c,[mk_abs r])
   524   in list_comb(c,[mk_abs r])
   525   end;
   525   end;
   526 
   526 
   527 fun mk_forall (r as {Bvar,Body}) =
   527 fun mk_forall (r as {Bvar,Body}) =
   528   let val ty = type_of Bvar
   528   let val ty = type_of Bvar
   529       val c = Const(@{const_name All},(ty --> HOLogic.boolT) --> HOLogic.boolT)
   529       val c = Const(\<^const_name>\<open>All\<close>,(ty --> HOLogic.boolT) --> HOLogic.boolT)
   530   in list_comb(c,[mk_abs r])
   530   in list_comb(c,[mk_abs r])
   531   end;
   531   end;
   532 
   532 
   533 fun mk_exists (r as {Bvar,Body}) =
   533 fun mk_exists (r as {Bvar,Body}) =
   534   let val ty = type_of Bvar
   534   let val ty = type_of Bvar
   535       val c = Const(@{const_name Ex},(ty --> HOLogic.boolT) --> HOLogic.boolT)
   535       val c = Const(\<^const_name>\<open>Ex\<close>,(ty --> HOLogic.boolT) --> HOLogic.boolT)
   536   in list_comb(c,[mk_abs r])
   536   in list_comb(c,[mk_abs r])
   537   end;
   537   end;
   538 
   538 
   539 
   539 
   540 fun mk_conj{conj1,conj2} =
   540 fun mk_conj{conj1,conj2} =
   541    let val c = Const(@{const_name HOL.conj},HOLogic.boolT --> HOLogic.boolT --> HOLogic.boolT)
   541    let val c = Const(\<^const_name>\<open>HOL.conj\<close>,HOLogic.boolT --> HOLogic.boolT --> HOLogic.boolT)
   542    in list_comb(c,[conj1,conj2])
   542    in list_comb(c,[conj1,conj2])
   543    end;
   543    end;
   544 
   544 
   545 fun mk_disj{disj1,disj2} =
   545 fun mk_disj{disj1,disj2} =
   546    let val c = Const(@{const_name HOL.disj},HOLogic.boolT --> HOLogic.boolT --> HOLogic.boolT)
   546    let val c = Const(\<^const_name>\<open>HOL.disj\<close>,HOLogic.boolT --> HOLogic.boolT --> HOLogic.boolT)
   547    in list_comb(c,[disj1,disj2])
   547    in list_comb(c,[disj1,disj2])
   548    end;
   548    end;
   549 
   549 
   550 fun prod_ty ty1 ty2 = HOLogic.mk_prodT (ty1,ty2);
   550 fun prod_ty ty1 ty2 = HOLogic.mk_prodT (ty1,ty2);
   551 
   551 
   552 local
   552 local
   553 fun mk_uncurry (xt, yt, zt) =
   553 fun mk_uncurry (xt, yt, zt) =
   554     Const(@{const_name case_prod}, (xt --> yt --> zt) --> prod_ty xt yt --> zt)
   554     Const(\<^const_name>\<open>case_prod\<close>, (xt --> yt --> zt) --> prod_ty xt yt --> zt)
   555 fun dest_pair(Const(@{const_name Pair},_) $ M $ N) = {fst=M, snd=N}
   555 fun dest_pair(Const(\<^const_name>\<open>Pair\<close>,_) $ M $ N) = {fst=M, snd=N}
   556   | dest_pair _ = raise USYN_ERR "dest_pair" "not a pair"
   556   | dest_pair _ = raise USYN_ERR "dest_pair" "not a pair"
   557 fun is_var (Var _) = true | is_var (Free _) = true | is_var _ = false
   557 fun is_var (Var _) = true | is_var (Free _) = true | is_var _ = false
   558 in
   558 in
   559 fun mk_pabs{varstruct,body} =
   559 fun mk_pabs{varstruct,body} =
   560  let fun mpa (varstruct, body) =
   560  let fun mpa (varstruct, body) =
   597        val v = Free(s', ty);
   597        val v = Free(s', ty);
   598      in ({Bvar = v, Body = Term.betapply (a,v)}, s'::used)
   598      in ({Bvar = v, Body = Term.betapply (a,v)}, s'::used)
   599      end
   599      end
   600   | dest_abs _ _ =  raise USYN_ERR "dest_abs" "not an abstraction";
   600   | dest_abs _ _ =  raise USYN_ERR "dest_abs" "not an abstraction";
   601 
   601 
   602 fun dest_eq(Const(@{const_name HOL.eq},_) $ M $ N) = {lhs=M, rhs=N}
   602 fun dest_eq(Const(\<^const_name>\<open>HOL.eq\<close>,_) $ M $ N) = {lhs=M, rhs=N}
   603   | dest_eq _ = raise USYN_ERR "dest_eq" "not an equality";
   603   | dest_eq _ = raise USYN_ERR "dest_eq" "not an equality";
   604 
   604 
   605 fun dest_imp(Const(@{const_name HOL.implies},_) $ M $ N) = {ant=M, conseq=N}
   605 fun dest_imp(Const(\<^const_name>\<open>HOL.implies\<close>,_) $ M $ N) = {ant=M, conseq=N}
   606   | dest_imp _ = raise USYN_ERR "dest_imp" "not an implication";
   606   | dest_imp _ = raise USYN_ERR "dest_imp" "not an implication";
   607 
   607 
   608 fun dest_forall(Const(@{const_name All},_) $ (a as Abs _)) = fst (dest_abs [] a)
   608 fun dest_forall(Const(\<^const_name>\<open>All\<close>,_) $ (a as Abs _)) = fst (dest_abs [] a)
   609   | dest_forall _ = raise USYN_ERR "dest_forall" "not a forall";
   609   | dest_forall _ = raise USYN_ERR "dest_forall" "not a forall";
   610 
   610 
   611 fun dest_exists(Const(@{const_name Ex},_) $ (a as Abs _)) = fst (dest_abs [] a)
   611 fun dest_exists(Const(\<^const_name>\<open>Ex\<close>,_) $ (a as Abs _)) = fst (dest_abs [] a)
   612   | dest_exists _ = raise USYN_ERR "dest_exists" "not an existential";
   612   | dest_exists _ = raise USYN_ERR "dest_exists" "not an existential";
   613 
   613 
   614 fun dest_neg(Const(@{const_name Not},_) $ M) = M
   614 fun dest_neg(Const(\<^const_name>\<open>Not\<close>,_) $ M) = M
   615   | dest_neg _ = raise USYN_ERR "dest_neg" "not a negation";
   615   | dest_neg _ = raise USYN_ERR "dest_neg" "not a negation";
   616 
   616 
   617 fun dest_conj(Const(@{const_name HOL.conj},_) $ M $ N) = {conj1=M, conj2=N}
   617 fun dest_conj(Const(\<^const_name>\<open>HOL.conj\<close>,_) $ M $ N) = {conj1=M, conj2=N}
   618   | dest_conj _ = raise USYN_ERR "dest_conj" "not a conjunction";
   618   | dest_conj _ = raise USYN_ERR "dest_conj" "not a conjunction";
   619 
   619 
   620 fun dest_disj(Const(@{const_name HOL.disj},_) $ M $ N) = {disj1=M, disj2=N}
   620 fun dest_disj(Const(\<^const_name>\<open>HOL.disj\<close>,_) $ M $ N) = {disj1=M, disj2=N}
   621   | dest_disj _ = raise USYN_ERR "dest_disj" "not a disjunction";
   621   | dest_disj _ = raise USYN_ERR "dest_disj" "not a disjunction";
   622 
   622 
   623 fun mk_pair{fst,snd} =
   623 fun mk_pair{fst,snd} =
   624    let val ty1 = type_of fst
   624    let val ty1 = type_of fst
   625        val ty2 = type_of snd
   625        val ty2 = type_of snd
   626        val c = Const(@{const_name Pair},ty1 --> ty2 --> prod_ty ty1 ty2)
   626        val c = Const(\<^const_name>\<open>Pair\<close>,ty1 --> ty2 --> prod_ty ty1 ty2)
   627    in list_comb(c,[fst,snd])
   627    in list_comb(c,[fst,snd])
   628    end;
   628    end;
   629 
   629 
   630 fun dest_pair(Const(@{const_name Pair},_) $ M $ N) = {fst=M, snd=N}
   630 fun dest_pair(Const(\<^const_name>\<open>Pair\<close>,_) $ M $ N) = {fst=M, snd=N}
   631   | dest_pair _ = raise USYN_ERR "dest_pair" "not a pair";
   631   | dest_pair _ = raise USYN_ERR "dest_pair" "not a pair";
   632 
   632 
   633 
   633 
   634 local  fun ucheck t = (if #Name (dest_const t) = @{const_name case_prod} then t
   634 local  fun ucheck t = (if #Name (dest_const t) = \<^const_name>\<open>case_prod\<close> then t
   635                        else raise Match)
   635                        else raise Match)
   636 in
   636 in
   637 fun dest_pabs used tm =
   637 fun dest_pabs used tm =
   638    let val ({Bvar,Body}, used') = dest_abs used tm
   638    let val ({Bvar,Body}, used') = dest_abs used tm
   639    in {varstruct = Bvar, body = Body, used = used'}
   639    in {varstruct = Bvar, body = Body, used = used'}
   725 
   725 
   726 
   726 
   727 (* Miscellaneous *)
   727 (* Miscellaneous *)
   728 
   728 
   729 fun mk_vstruct ty V =
   729 fun mk_vstruct ty V =
   730   let fun follow_prod_type (Type(@{type_name Product_Type.prod},[ty1,ty2])) vs =
   730   let fun follow_prod_type (Type(\<^type_name>\<open>Product_Type.prod\<close>,[ty1,ty2])) vs =
   731               let val (ltm,vs1) = follow_prod_type ty1 vs
   731               let val (ltm,vs1) = follow_prod_type ty1 vs
   732                   val (rtm,vs2) = follow_prod_type ty2 vs1
   732                   val (rtm,vs2) = follow_prod_type ty2 vs1
   733               in (mk_pair{fst=ltm, snd=rtm}, vs2) end
   733               in (mk_pair{fst=ltm, snd=rtm}, vs2) end
   734         | follow_prod_type _ (v::vs) = (v,vs)
   734         | follow_prod_type _ (v::vs) = (v,vs)
   735   in #1 (follow_prod_type ty V)  end;
   735   in #1 (follow_prod_type ty V)  end;
   746    in find
   746    in find
   747    end;
   747    end;
   748 
   748 
   749 fun dest_relation tm =
   749 fun dest_relation tm =
   750    if (type_of tm = HOLogic.boolT)
   750    if (type_of tm = HOLogic.boolT)
   751    then let val (Const(@{const_name Set.member},_) $ (Const(@{const_name Pair},_)$y$x) $ R) = tm
   751    then let val (Const(\<^const_name>\<open>Set.member\<close>,_) $ (Const(\<^const_name>\<open>Pair\<close>,_)$y$x) $ R) = tm
   752         in (R,y,x)
   752         in (R,y,x)
   753         end handle Bind => raise USYN_ERR "dest_relation" "unexpected term structure"
   753         end handle Bind => raise USYN_ERR "dest_relation" "unexpected term structure"
   754    else raise USYN_ERR "dest_relation" "not a boolean term";
   754    else raise USYN_ERR "dest_relation" "not a boolean term";
   755 
   755 
   756 fun is_WFR (Const(@{const_name Wellfounded.wf},_)$_) = true
   756 fun is_WFR (Const(\<^const_name>\<open>Wellfounded.wf\<close>,_)$_) = true
   757   | is_WFR _                 = false;
   757   | is_WFR _                 = false;
   758 
   758 
   759 fun ARB ty = mk_select{Bvar=Free("v",ty),
   759 fun ARB ty = mk_select{Bvar=Free("v",ty),
   760                        Body=Const(@{const_name True},HOLogic.boolT)};
   760                        Body=Const(\<^const_name>\<open>True\<close>,HOLogic.boolT)};
   761 
   761 
   762 end;
   762 end;
   763 
   763 
   764 
   764 
   765 
   765 
   786 
   786 
   787 (*---------------------------------------------------------------------------
   787 (*---------------------------------------------------------------------------
   788  * Some simple constructor functions.
   788  * Some simple constructor functions.
   789  *---------------------------------------------------------------------------*)
   789  *---------------------------------------------------------------------------*)
   790 
   790 
   791 val mk_hol_const = Thm.cterm_of @{theory_context HOL} o Const;
   791 val mk_hol_const = Thm.cterm_of \<^theory_context>\<open>HOL\<close> o Const;
   792 
   792 
   793 fun mk_exists (r as (Bvar, Body)) =
   793 fun mk_exists (r as (Bvar, Body)) =
   794   let val ty = Thm.typ_of_cterm Bvar
   794   let val ty = Thm.typ_of_cterm Bvar
   795       val c = mk_hol_const(@{const_name Ex}, (ty --> HOLogic.boolT) --> HOLogic.boolT)
   795       val c = mk_hol_const(\<^const_name>\<open>Ex\<close>, (ty --> HOLogic.boolT) --> HOLogic.boolT)
   796   in capply c (uncurry cabs r) end;
   796   in capply c (uncurry cabs r) end;
   797 
   797 
   798 
   798 
   799 local val c = mk_hol_const(@{const_name HOL.conj}, HOLogic.boolT --> HOLogic.boolT --> HOLogic.boolT)
   799 local val c = mk_hol_const(\<^const_name>\<open>HOL.conj\<close>, HOLogic.boolT --> HOLogic.boolT --> HOLogic.boolT)
   800 in fun mk_conj(conj1,conj2) = capply (capply c conj1) conj2
   800 in fun mk_conj(conj1,conj2) = capply (capply c conj1) conj2
   801 end;
   801 end;
   802 
   802 
   803 local val c = mk_hol_const(@{const_name HOL.disj}, HOLogic.boolT --> HOLogic.boolT --> HOLogic.boolT)
   803 local val c = mk_hol_const(\<^const_name>\<open>HOL.disj\<close>, HOLogic.boolT --> HOLogic.boolT --> HOLogic.boolT)
   804 in fun mk_disj(disj1,disj2) = capply (capply c disj1) disj2
   804 in fun mk_disj(disj1,disj2) = capply (capply c disj1) disj2
   805 end;
   805 end;
   806 
   806 
   807 
   807 
   808 (*---------------------------------------------------------------------------
   808 (*---------------------------------------------------------------------------
   840 fun dest_binder expected tm =
   840 fun dest_binder expected tm =
   841   dest_abs NONE (dest_monop expected tm)
   841   dest_abs NONE (dest_monop expected tm)
   842   handle Utils.ERR _ => raise ERR "dest_binder" ("Not a(n) " ^ quote expected);
   842   handle Utils.ERR _ => raise ERR "dest_binder" ("Not a(n) " ^ quote expected);
   843 
   843 
   844 
   844 
   845 val dest_neg    = dest_monop @{const_name Not}
   845 val dest_neg    = dest_monop \<^const_name>\<open>Not\<close>
   846 val dest_pair   = dest_binop @{const_name Pair}
   846 val dest_pair   = dest_binop \<^const_name>\<open>Pair\<close>
   847 val dest_eq     = dest_binop @{const_name HOL.eq}
   847 val dest_eq     = dest_binop \<^const_name>\<open>HOL.eq\<close>
   848 val dest_imp    = dest_binop @{const_name HOL.implies}
   848 val dest_imp    = dest_binop \<^const_name>\<open>HOL.implies\<close>
   849 val dest_conj   = dest_binop @{const_name HOL.conj}
   849 val dest_conj   = dest_binop \<^const_name>\<open>HOL.conj\<close>
   850 val dest_disj   = dest_binop @{const_name HOL.disj}
   850 val dest_disj   = dest_binop \<^const_name>\<open>HOL.disj\<close>
   851 val dest_exists = dest_binder @{const_name Ex}
   851 val dest_exists = dest_binder \<^const_name>\<open>Ex\<close>
   852 val dest_forall = dest_binder @{const_name All}
   852 val dest_forall = dest_binder \<^const_name>\<open>All\<close>
   853 
   853 
   854 (* Query routines *)
   854 (* Query routines *)
   855 
   855 
   856 val is_eq     = can dest_eq
   856 val is_eq     = can dest_eq
   857 val is_imp    = can dest_imp
   857 val is_imp    = can dest_imp
   894  * Going into and out of prop
   894  * Going into and out of prop
   895  *---------------------------------------------------------------------------*)
   895  *---------------------------------------------------------------------------*)
   896 
   896 
   897 fun is_Trueprop ct =
   897 fun is_Trueprop ct =
   898   (case Thm.term_of ct of
   898   (case Thm.term_of ct of
   899     Const (@{const_name Trueprop}, _) $ _ => true
   899     Const (\<^const_name>\<open>Trueprop\<close>, _) $ _ => true
   900   | _ => false);
   900   | _ => false);
   901 
   901 
   902 fun mk_prop ct = if is_Trueprop ct then ct else Thm.apply @{cterm Trueprop} ct;
   902 fun mk_prop ct = if is_Trueprop ct then ct else Thm.apply \<^cterm>\<open>Trueprop\<close> ct;
   903 fun drop_prop ct = if is_Trueprop ct then Thm.dest_arg ct else ct;
   903 fun drop_prop ct = if is_Trueprop ct then Thm.dest_arg ct else ct;
   904 
   904 
   905 end;
   905 end;
   906 
   906 
   907 
   907 
  1012  *        Disjunction
  1012  *        Disjunction
  1013  *---------------------------------------------------------------------------*)
  1013  *---------------------------------------------------------------------------*)
  1014 local
  1014 local
  1015   val prop = Thm.prop_of disjI1
  1015   val prop = Thm.prop_of disjI1
  1016   val [_,Q] = Misc_Legacy.term_vars prop
  1016   val [_,Q] = Misc_Legacy.term_vars prop
  1017   val disj1 = Thm.forall_intr (Thm.cterm_of @{context} Q) disjI1
  1017   val disj1 = Thm.forall_intr (Thm.cterm_of \<^context> Q) disjI1
  1018 in
  1018 in
  1019 fun DISJ1 thm tm = thm RS (Thm.forall_elim (Dcterm.drop_prop tm) disj1)
  1019 fun DISJ1 thm tm = thm RS (Thm.forall_elim (Dcterm.drop_prop tm) disj1)
  1020   handle THM (msg, _, _) => raise RULES_ERR "DISJ1" msg;
  1020   handle THM (msg, _, _) => raise RULES_ERR "DISJ1" msg;
  1021 end;
  1021 end;
  1022 
  1022 
  1023 local
  1023 local
  1024   val prop = Thm.prop_of disjI2
  1024   val prop = Thm.prop_of disjI2
  1025   val [P,_] = Misc_Legacy.term_vars prop
  1025   val [P,_] = Misc_Legacy.term_vars prop
  1026   val disj2 = Thm.forall_intr (Thm.cterm_of @{context} P) disjI2
  1026   val disj2 = Thm.forall_intr (Thm.cterm_of \<^context> P) disjI2
  1027 in
  1027 in
  1028 fun DISJ2 tm thm = thm RS (Thm.forall_elim (Dcterm.drop_prop tm) disj2)
  1028 fun DISJ2 tm thm = thm RS (Thm.forall_elim (Dcterm.drop_prop tm) disj2)
  1029   handle THM (msg, _, _) => raise RULES_ERR "DISJ2" msg;
  1029   handle THM (msg, _, _) => raise RULES_ERR "DISJ2" msg;
  1030 end;
  1030 end;
  1031 
  1031 
  1116  *---------------------------------------------------------------------------*)
  1116  *---------------------------------------------------------------------------*)
  1117 local (* this is fragile *)
  1117 local (* this is fragile *)
  1118   val prop = Thm.prop_of spec
  1118   val prop = Thm.prop_of spec
  1119   val x = hd (tl (Misc_Legacy.term_vars prop))
  1119   val x = hd (tl (Misc_Legacy.term_vars prop))
  1120   val TV = dest_TVar (type_of x)
  1120   val TV = dest_TVar (type_of x)
  1121   val gspec = Thm.forall_intr (Thm.cterm_of @{context} x) spec
  1121   val gspec = Thm.forall_intr (Thm.cterm_of \<^context> x) spec
  1122 in
  1122 in
  1123 fun SPEC tm thm =
  1123 fun SPEC tm thm =
  1124    let val gspec' = Drule.instantiate_normalize ([(TV, Thm.ctyp_of_cterm tm)], []) gspec
  1124    let val gspec' = Drule.instantiate_normalize ([(TV, Thm.ctyp_of_cterm tm)], []) gspec
  1125    in thm RS (Thm.forall_elim tm gspec') end
  1125    in thm RS (Thm.forall_elim tm gspec') end
  1126 end;
  1126 end;
  1144      ctm_theta ctxt (Vartab.dest tm_theta))
  1144      ctm_theta ctxt (Vartab.dest tm_theta))
  1145 in
  1145 in
  1146 fun GEN ctxt v th =
  1146 fun GEN ctxt v th =
  1147    let val gth = Thm.forall_intr v th
  1147    let val gth = Thm.forall_intr v th
  1148        val thy = Proof_Context.theory_of ctxt
  1148        val thy = Proof_Context.theory_of ctxt
  1149        val Const(@{const_name Pure.all},_)$Abs(x,ty,rst) = Thm.prop_of gth
  1149        val Const(\<^const_name>\<open>Pure.all\<close>,_)$Abs(x,ty,rst) = Thm.prop_of gth
  1150        val P' = Abs(x,ty, HOLogic.dest_Trueprop rst)  (* get rid of trueprop *)
  1150        val P' = Abs(x,ty, HOLogic.dest_Trueprop rst)  (* get rid of trueprop *)
  1151        val theta = Pattern.match thy (P,P') (Vartab.empty, Vartab.empty);
  1151        val theta = Pattern.match thy (P,P') (Vartab.empty, Vartab.empty);
  1152        val allI2 = Drule.instantiate_normalize (certify ctxt theta) allI
  1152        val allI2 = Drule.instantiate_normalize (certify ctxt theta) allI
  1153        val thm = Thm.implies_elim allI2 gth
  1153        val thm = Thm.implies_elim allI2 gth
  1154        val tp $ (A $ Abs(_,_,M)) = Thm.prop_of thm
  1154        val tp $ (A $ Abs(_,_,M)) = Thm.prop_of thm
  1251 
  1251 
  1252 
  1252 
  1253 (* Fragile: it's a cong if it is not "R y x ==> cut f R x y = f y" *)
  1253 (* Fragile: it's a cong if it is not "R y x ==> cut f R x y = f y" *)
  1254 fun is_cong thm =
  1254 fun is_cong thm =
  1255   case (Thm.prop_of thm) of
  1255   case (Thm.prop_of thm) of
  1256     (Const(@{const_name Pure.imp},_)$(Const(@{const_name Trueprop},_)$ _) $
  1256     (Const(\<^const_name>\<open>Pure.imp\<close>,_)$(Const(\<^const_name>\<open>Trueprop\<close>,_)$ _) $
  1257       (Const(@{const_name Pure.eq},_) $ (Const (@{const_name Wfrec.cut},_) $ _ $ _ $ _ $ _) $ _)) =>
  1257       (Const(\<^const_name>\<open>Pure.eq\<close>,_) $ (Const (\<^const_name>\<open>Wfrec.cut\<close>,_) $ _ $ _ $ _ $ _) $ _)) =>
  1258         false
  1258         false
  1259   | _ => true;
  1259   | _ => true;
  1260 
  1260 
  1261 
  1261 
  1262 fun dest_equal(Const (@{const_name Pure.eq},_) $
  1262 fun dest_equal(Const (\<^const_name>\<open>Pure.eq\<close>,_) $
  1263                (Const (@{const_name Trueprop},_) $ lhs)
  1263                (Const (\<^const_name>\<open>Trueprop\<close>,_) $ lhs)
  1264                $ (Const (@{const_name Trueprop},_) $ rhs)) = {lhs=lhs, rhs=rhs}
  1264                $ (Const (\<^const_name>\<open>Trueprop\<close>,_) $ rhs)) = {lhs=lhs, rhs=rhs}
  1265   | dest_equal(Const (@{const_name Pure.eq},_) $ lhs $ rhs) = {lhs=lhs, rhs=rhs}
  1265   | dest_equal(Const (\<^const_name>\<open>Pure.eq\<close>,_) $ lhs $ rhs) = {lhs=lhs, rhs=rhs}
  1266   | dest_equal tm = USyntax.dest_eq tm;
  1266   | dest_equal tm = USyntax.dest_eq tm;
  1267 
  1267 
  1268 fun get_lhs tm = #lhs(dest_equal (HOLogic.dest_Trueprop tm));
  1268 fun get_lhs tm = #lhs(dest_equal (HOLogic.dest_Trueprop tm));
  1269 
  1269 
  1270 fun dest_all used (Const(@{const_name Pure.all},_) $ (a as Abs _)) = USyntax.dest_abs used a
  1270 fun dest_all used (Const(\<^const_name>\<open>Pure.all\<close>,_) $ (a as Abs _)) = USyntax.dest_abs used a
  1271   | dest_all _ _ = raise RULES_ERR "dest_all" "not a !!";
  1271   | dest_all _ _ = raise RULES_ERR "dest_all" "not a !!";
  1272 
  1272 
  1273 val is_all = can (dest_all []);
  1273 val is_all = can (dest_all []);
  1274 
  1274 
  1275 fun strip_all used fm =
  1275 fun strip_all used fm =
  1278             val (bvs, core, used'') = strip_all used' Body
  1278             val (bvs, core, used'') = strip_all used' Body
  1279         in ((Bvar::bvs), core, used'')
  1279         in ((Bvar::bvs), core, used'')
  1280         end
  1280         end
  1281    else ([], fm, used);
  1281    else ([], fm, used);
  1282 
  1282 
  1283 fun list_break_all(Const(@{const_name Pure.all},_) $ Abs (s,ty,body)) =
  1283 fun list_break_all(Const(\<^const_name>\<open>Pure.all\<close>,_) $ Abs (s,ty,body)) =
  1284      let val (L,core) = list_break_all body
  1284      let val (L,core) = list_break_all body
  1285      in ((s,ty)::L, core)
  1285      in ((s,ty)::L, core)
  1286      end
  1286      end
  1287   | list_break_all tm = ([],tm);
  1287   | list_break_all tm = ([],tm);
  1288 
  1288 
  1381 
  1381 
  1382 
  1382 
  1383 
  1383 
  1384 local fun dest_pair M = let val {fst,snd} = USyntax.dest_pair M in (fst,snd) end
  1384 local fun dest_pair M = let val {fst,snd} = USyntax.dest_pair M in (fst,snd) end
  1385       fun mk_fst tm =
  1385       fun mk_fst tm =
  1386           let val ty as Type(@{type_name Product_Type.prod}, [fty,sty]) = type_of tm
  1386           let val ty as Type(\<^type_name>\<open>Product_Type.prod\<close>, [fty,sty]) = type_of tm
  1387           in  Const (@{const_name Product_Type.fst}, ty --> fty) $ tm  end
  1387           in  Const (\<^const_name>\<open>Product_Type.fst\<close>, ty --> fty) $ tm  end
  1388       fun mk_snd tm =
  1388       fun mk_snd tm =
  1389           let val ty as Type(@{type_name Product_Type.prod}, [fty,sty]) = type_of tm
  1389           let val ty as Type(\<^type_name>\<open>Product_Type.prod\<close>, [fty,sty]) = type_of tm
  1390           in  Const (@{const_name Product_Type.snd}, ty --> sty) $ tm  end
  1390           in  Const (\<^const_name>\<open>Product_Type.snd\<close>, ty --> sty) $ tm  end
  1391 in
  1391 in
  1392 fun XFILL tych x vstruct =
  1392 fun XFILL tych x vstruct =
  1393   let fun traverse p xocc L =
  1393   let fun traverse p xocc L =
  1394         if (is_Free p)
  1394         if (is_Free p)
  1395         then tych xocc::L
  1395         then tych xocc::L
  1441       val eq = Logic.strip_imp_concl tm
  1441       val eq = Logic.strip_imp_concl tm
  1442   in (ants,get_lhs eq)
  1442   in (ants,get_lhs eq)
  1443   end;
  1443   end;
  1444 
  1444 
  1445 fun restricted t = is_some (USyntax.find_term
  1445 fun restricted t = is_some (USyntax.find_term
  1446                             (fn (Const(@{const_name Wfrec.cut},_)) =>true | _ => false)
  1446                             (fn (Const(\<^const_name>\<open>Wfrec.cut\<close>,_)) =>true | _ => false)
  1447                             t)
  1447                             t)
  1448 
  1448 
  1449 fun CONTEXT_REWRITE_RULE main_ctxt (func, G, cut_lemma, congs) th =
  1449 fun CONTEXT_REWRITE_RULE main_ctxt (func, G, cut_lemma, congs) th =
  1450  let val globals = func::G
  1450  let val globals = func::G
  1451      val ctxt0 = empty_simpset main_ctxt
  1451      val ctxt0 = empty_simpset main_ctxt
  1523                  ant_th COMP thm
  1523                  ant_th COMP thm
  1524               end end
  1524               end end
  1525 
  1525 
  1526              fun eliminate thm =
  1526              fun eliminate thm =
  1527                case Thm.prop_of thm of
  1527                case Thm.prop_of thm of
  1528                  Const(@{const_name Pure.imp},_) $ imp $ _ =>
  1528                  Const(\<^const_name>\<open>Pure.imp\<close>,_) $ imp $ _ =>
  1529                    eliminate
  1529                    eliminate
  1530                     (if not(is_all imp)
  1530                     (if not(is_all imp)
  1531                      then uq_eliminate (thm, imp)
  1531                      then uq_eliminate (thm, imp)
  1532                      else q_eliminate (thm, imp))
  1532                      else q_eliminate (thm, imp))
  1533                             (* Assume that the leading constant is ==,   *)
  1533                             (* Assume that the leading constant is ==,   *)
  1537 
  1537 
  1538         fun restrict_prover ctxt thm =
  1538         fun restrict_prover ctxt thm =
  1539           let val _ = say "restrict_prover:"
  1539           let val _ = say "restrict_prover:"
  1540               val cntxt = rev (Simplifier.prems_of ctxt)
  1540               val cntxt = rev (Simplifier.prems_of ctxt)
  1541               val _ = print_thms ctxt "cntxt:" cntxt
  1541               val _ = print_thms ctxt "cntxt:" cntxt
  1542               val Const(@{const_name Pure.imp},_) $ (Const(@{const_name Trueprop},_) $ A) $ _ =
  1542               val Const(\<^const_name>\<open>Pure.imp\<close>,_) $ (Const(\<^const_name>\<open>Trueprop\<close>,_) $ A) $ _ =
  1543                 Thm.prop_of thm
  1543                 Thm.prop_of thm
  1544               fun genl tm = let val vlist = subtract (op aconv) globals
  1544               fun genl tm = let val vlist = subtract (op aconv) globals
  1545                                            (Misc_Legacy.add_term_frees(tm,[]))
  1545                                            (Misc_Legacy.add_term_frees(tm,[]))
  1546                             in fold_rev Forall vlist tm
  1546                             in fold_rev Forall vlist tm
  1547                             end
  1547                             end
  1992 
  1992 
  1993 
  1993 
  1994 (*For Isabelle, the lhs of a definition must be a constant.*)
  1994 (*For Isabelle, the lhs of a definition must be a constant.*)
  1995 fun const_def sign (c, Ty, rhs) =
  1995 fun const_def sign (c, Ty, rhs) =
  1996   singleton (Syntax.check_terms (Proof_Context.init_global sign))
  1996   singleton (Syntax.check_terms (Proof_Context.init_global sign))
  1997     (Const(@{const_name Pure.eq},dummyT) $ Const(c,Ty) $ rhs);
  1997     (Const(\<^const_name>\<open>Pure.eq\<close>,dummyT) $ Const(c,Ty) $ rhs);
  1998 
  1998 
  1999 (*Make all TVars available for instantiation by adding a ? to the front*)
  1999 (*Make all TVars available for instantiation by adding a ? to the front*)
  2000 fun poly_tvars (Type(a,Ts)) = Type(a, map (poly_tvars) Ts)
  2000 fun poly_tvars (Type(a,Ts)) = Type(a, map (poly_tvars) Ts)
  2001   | poly_tvars (TFree (a,sort)) = TVar (("?" ^ a, 0), sort)
  2001   | poly_tvars (TFree (a,sort)) = TVar (("?" ^ a, 0), sort)
  2002   | poly_tvars (TVar ((a,i),sort)) = TVar (("?" ^ a, i+1), sort);
  2002   | poly_tvars (TVar ((a,i),sort)) = TVar (("?" ^ a, i+1), sort);
  2537    handle Utils.ERR _ => false;
  2537    handle Utils.ERR _ => false;
  2538 
  2538 
  2539 val P_imp_P_eq_True = @{thm eqTrueI} RS eq_reflection;
  2539 val P_imp_P_eq_True = @{thm eqTrueI} RS eq_reflection;
  2540 fun mk_meta_eq r =
  2540 fun mk_meta_eq r =
  2541   (case Thm.concl_of r of
  2541   (case Thm.concl_of r of
  2542      Const(@{const_name Pure.eq},_)$_$_ => r
  2542      Const(\<^const_name>\<open>Pure.eq\<close>,_)$_$_ => r
  2543   |   _ $(Const(@{const_name HOL.eq},_)$_$_) => r RS eq_reflection
  2543   |   _ $(Const(\<^const_name>\<open>HOL.eq\<close>,_)$_$_) => r RS eq_reflection
  2544   |   _ => r RS P_imp_P_eq_True)
  2544   |   _ => r RS P_imp_P_eq_True)
  2545 
  2545 
  2546 (*Is this the best way to invoke the simplifier??*)
  2546 (*Is this the best way to invoke the simplifier??*)
  2547 fun rewrite ctxt L = rewrite_rule ctxt (map mk_meta_eq (filter_out id_thm L))
  2547 fun rewrite ctxt L = rewrite_rule ctxt (map mk_meta_eq (filter_out id_thm L))
  2548 
  2548 
  2605   rule_by_tactic ctxt
  2605   rule_by_tactic ctxt
  2606     (REPEAT (FIRSTGOAL (resolve_tac ctxt [allI, impI, conjI] ORELSE' eresolve_tac ctxt [conjE])));
  2606     (REPEAT (FIRSTGOAL (resolve_tac ctxt [allI, impI, conjI] ORELSE' eresolve_tac ctxt [conjE])));
  2607 
  2607 
  2608 (*Strip off the outer !P*)
  2608 (*Strip off the outer !P*)
  2609 val spec'=
  2609 val spec'=
  2610   Rule_Insts.read_instantiate @{context} [((("x", 0), Position.none), "P::'b=>bool")] [] spec;
  2610   Rule_Insts.read_instantiate \<^context> [((("x", 0), Position.none), "P::'b=>bool")] [] spec;
  2611 
  2611 
  2612 fun simplify_defn ctxt strict congs wfs pats def0 =
  2612 fun simplify_defn ctxt strict congs wfs pats def0 =
  2613   let
  2613   let
  2614     val thy = Proof_Context.theory_of ctxt;
  2614     val thy = Proof_Context.theory_of ctxt;
  2615     val def = HOLogic.mk_obj_eq (Thm.unvarify_global thy def0)
  2615     val def = HOLogic.mk_obj_eq (Thm.unvarify_global thy def0)
  2832     val ({lhs, rules = rules_idx, induct, tcs}, ctxt1) =
  2832     val ({lhs, rules = rules_idx, induct, tcs}, ctxt1) =
  2833       tfl_fn not_permissive congs wfs name R eqs ctxt;
  2833       tfl_fn not_permissive congs wfs name R eqs ctxt;
  2834     val rules = (map o map) fst (partition_eq (eq_snd (op = : int * int -> bool)) rules_idx);
  2834     val rules = (map o map) fst (partition_eq (eq_snd (op = : int * int -> bool)) rules_idx);
  2835     val simp_att =
  2835     val simp_att =
  2836       if null tcs then [Simplifier.simp_add,
  2836       if null tcs then [Simplifier.simp_add,
  2837         Named_Theorems.add @{named_theorems nitpick_simp}]
  2837         Named_Theorems.add \<^named_theorems>\<open>nitpick_simp\<close>]
  2838       else [];
  2838       else [];
  2839     val ((simps' :: rules', [induct']), thy2) =
  2839     val ((simps' :: rules', [induct']), thy2) =
  2840       Proof_Context.theory_of ctxt1
  2840       Proof_Context.theory_of ctxt1
  2841       |> Sign.add_path bname
  2841       |> Sign.add_path bname
  2842       |> Global_Theory.add_thmss
  2842       |> Global_Theory.add_thmss
  2860 
  2860 
  2861 (* setup theory *)
  2861 (* setup theory *)
  2862 
  2862 
  2863 val _ =
  2863 val _ =
  2864   Theory.setup
  2864   Theory.setup
  2865    (Attrib.setup @{binding recdef_simp} (Attrib.add_del simp_add simp_del)
  2865    (Attrib.setup \<^binding>\<open>recdef_simp\<close> (Attrib.add_del simp_add simp_del)
  2866       "declaration of recdef simp rule" #>
  2866       "declaration of recdef simp rule" #>
  2867     Attrib.setup @{binding recdef_cong} (Attrib.add_del cong_add cong_del)
  2867     Attrib.setup \<^binding>\<open>recdef_cong\<close> (Attrib.add_del cong_add cong_del)
  2868       "declaration of recdef cong rule" #>
  2868       "declaration of recdef cong rule" #>
  2869     Attrib.setup @{binding recdef_wf} (Attrib.add_del wf_add wf_del)
  2869     Attrib.setup \<^binding>\<open>recdef_wf\<close> (Attrib.add_del wf_add wf_del)
  2870       "declaration of recdef wf rule");
  2870       "declaration of recdef wf rule");
  2871 
  2871 
  2872 
  2872 
  2873 (* outer syntax *)
  2873 (* outer syntax *)
  2874 
  2874 
  2875 val hints =
  2875 val hints =
  2876   @{keyword "("} |--
  2876   \<^keyword>\<open>(\<close> |--
  2877     Parse.!!! ((Parse.token @{keyword "hints"} ::: Parse.args) --| @{keyword ")"});
  2877     Parse.!!! ((Parse.token \<^keyword>\<open>hints\<close> ::: Parse.args) --| \<^keyword>\<open>)\<close>);
  2878 
  2878 
  2879 val recdef_decl =
  2879 val recdef_decl =
  2880   Scan.optional
  2880   Scan.optional
  2881     (@{keyword "("} -- Parse.!!! (@{keyword "permissive"} -- @{keyword ")"}) >> K false) true --
  2881     (\<^keyword>\<open>(\<close> -- Parse.!!! (\<^keyword>\<open>permissive\<close> -- \<^keyword>\<open>)\<close>) >> K false) true --
  2882   Parse.name -- Parse.term -- Scan.repeat1 (Parse_Spec.opt_thm_name ":" -- Parse.prop)
  2882   Parse.name -- Parse.term -- Scan.repeat1 (Parse_Spec.opt_thm_name ":" -- Parse.prop)
  2883     -- Scan.option hints
  2883     -- Scan.option hints
  2884   >> (fn ((((p, f), R), eqs), src) =>
  2884   >> (fn ((((p, f), R), eqs), src) =>
  2885       #1 o add_recdef p f R (map (fn ((x, y), z) => ((x, z), y)) eqs) src);
  2885       #1 o add_recdef p f R (map (fn ((x, y), z) => ((x, z), y)) eqs) src);
  2886 
  2886 
  2887 val _ =
  2887 val _ =
  2888   Outer_Syntax.command @{command_keyword recdef} "define general recursive functions (obsolete TFL)"
  2888   Outer_Syntax.command \<^command_keyword>\<open>recdef\<close> "define general recursive functions (obsolete TFL)"
  2889     (recdef_decl >> Toplevel.theory);
  2889     (recdef_decl >> Toplevel.theory);
  2890 
  2890 
  2891 end;
  2891 end;