src/HOL/Tools/function_package/fundef_prep.ML
author wenzelm
Tue, 11 Jul 2006 12:17:08 +0200
changeset 20083 717b1eb434f1
parent 20071 8f3e1ddb50e6
child 20523 36a59e5d0039
permissions -rw-r--r--
removed obsolete mem_ix;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
     1
(*  Title:      HOL/Tools/function_package/fundef_prep.ML
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
     2
    ID:         $Id$
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
     3
    Author:     Alexander Krauss, TU Muenchen
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
     4
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
     5
A package for general recursive function definitions.
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
     6
Preparation step: makes auxiliary definitions and generates
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
     7
proof obligations.
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
     8
*)
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
     9
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    10
signature FUNDEF_PREP =
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    11
sig
19773
ebc3b67fbd2c HOL/Tools/fundef_package: Cleanup
krauss
parents: 19770
diff changeset
    12
    val prepare_fundef : theory -> thm list -> string -> term -> FundefCommon.glrs -> string list
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    13
                         -> FundefCommon.prep_result * theory
19770
be5c23ebe1eb HOL/Tools/function_package: Added support for mutual recursive definitions.
krauss
parents: 19583
diff changeset
    14
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    15
end
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    16
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    17
structure FundefPrep (*: FUNDEF_PREP*) =
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    18
struct
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    19
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    20
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    21
open FundefCommon
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    22
open FundefAbbrev
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    23
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    24
(* Theory dependencies. *)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    25
val Pair_inject = thm "Product_Type.Pair_inject";
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    26
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    27
val acc_induct_rule = thm "Accessible_Part.acc_induct_rule"
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    28
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    29
val ex1_implies_ex = thm "FunDef.fundef_ex1_existence"
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    30
val ex1_implies_un = thm "FunDef.fundef_ex1_uniqueness"
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    31
val ex1_implies_iff = thm "FunDef.fundef_ex1_iff"
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    32
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    33
val conjunctionI = thm "conjunctionI";
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    34
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    35
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    36
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    37
fun split_list3 [] = ([],[],[])
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    38
  | split_list3 ((x,y,z)::xyzs) =
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    39
    let
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    40
        val (xs, ys, zs) = split_list3 xyzs
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    41
    in
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    42
        (x::xs,y::ys,z::zs)
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    43
    end
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    44
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    45
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    46
fun build_tree thy f congs ctx (qs, gs, lhs, rhs) =
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    47
    let
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    48
        (* FIXME: Save precomputed dependencies in a theory data slot *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    49
        val congs_deps = map (fn c => (c, FundefCtxTree.cong_deps c)) (congs @ FundefCtxTree.add_congs)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    50
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    51
        val (_(*FIXME*), ctx') = ProofContext.add_fixes_i (map (fn Free (n, T) => (n, SOME T, NoSyn)) qs) ctx
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    52
    in
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    53
        FundefCtxTree.mk_tree thy congs_deps f ctx' rhs
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    54
    end
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    55
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    56
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    57
fun find_calls tree =
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    58
    let
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    59
      fun add_Ri (fixes,assumes) (_ $ arg) _ (_, xs) = ([], (fixes, assumes, arg) :: xs)
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    60
        | add_Ri _ _ _ _ = raise Match
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    61
    in
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    62
      rev (FundefCtxTree.traverse_tree add_Ri tree [])
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    63
    end
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    64
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    65
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    66
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    67
(* maps (qs,gs,lhs,ths) to (qs',gs',lhs',rhs') with primed variables *)
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    68
fun mk_primed_vars thy glrs =
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    69
    let
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    70
        val used = fold (fn (qs,_,_,_) => fold ((insert op =) o fst o dest_Free) qs) glrs []
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    71
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    72
        fun rename_vars (qs,gs,lhs,rhs) =
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    73
            let
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    74
                val qs' = map (fn Free (v,T) => Free (Name.variant used (v ^ "'"),T)) qs
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    75
                val rename_vars = Pattern.rewrite_term thy (qs ~~ qs') []
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    76
            in
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    77
                (qs', map rename_vars gs, rename_vars lhs, rename_vars rhs)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    78
            end
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    79
    in
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    80
        map rename_vars glrs
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    81
    end
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    82
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    83
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    84
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    85
(* Chooses fresh free names, declares G and R, defines f and returns a record
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    86
   with all the information *)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
    87
fun setup_context f glrs defname thy =
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    88
    let
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    89
        val Const (f_fullname, fT) = f
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    90
        val fname = Sign.base_name f_fullname
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    91
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    92
        val domT = domain_type fT
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    93
        val ranT = range_type fT
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    94
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    95
        val GT = mk_relT (domT, ranT)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    96
        val RT = mk_relT (domT, domT)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    97
        val G_name = defname ^ "_graph"
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
    98
        val R_name = defname ^ "_rel"
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
    99
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   100
        val gfixes = [("h_fd", domT --> ranT),
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   101
                      ("y_fd", ranT),
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   102
                      ("x_fd", domT),
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   103
                      ("z_fd", domT),
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   104
                      ("a_fd", domT),
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   105
                      ("D_fd", HOLogic.mk_setT domT),
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   106
                      ("P_fd", domT --> boolT),
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   107
                      ("Pb_fd", boolT),
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   108
                      ("f_fd", fT)]
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   109
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   110
        val (fxnames, ctx) = (ProofContext.init thy)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   111
                               |> ProofContext.add_fixes_i (map (fn (n,T) => (n, SOME T, NoSyn)) gfixes)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   112
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   113
        val [h, y, x, z, a, D, P, Pbool, fvar] = map (fn (n,(_,T)) => Free (n, T)) (fxnames ~~ gfixes)
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   114
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   115
        val Free (fvarname, _) = fvar
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   116
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   117
        val glrs' = mk_primed_vars thy glrs
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   118
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   119
        val thy = Sign.add_consts_i [(G_name, GT, NoSyn), (R_name, RT, NoSyn)] thy
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   120
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   121
        val G = Const (Sign.full_name thy G_name, GT)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   122
        val R = Const (Sign.full_name thy R_name, RT)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   123
        val acc_R = Const (acc_const_name, (fastype_of R) --> HOLogic.mk_setT domT) $ R
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   124
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   125
        val f_eq = Logic.mk_equals (f $ x,
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   126
                                    Const ("The", (ranT --> boolT) --> ranT) $
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   127
                                          Abs ("y", ranT, mk_relmemT domT ranT (x, Bound 0) G))
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   128
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   129
        val ([f_def], thy) = PureThy.add_defs_i false [((fname ^ "_def", f_eq), [])] thy
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   130
    in
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   131
        (Names {f=f, glrs=glrs, glrs'=glrs', fvar=fvar, fvarname=fvarname, domT=domT, ranT=ranT, G=G, R=R, acc_R=acc_R, h=h, x=x, y=y, z=z, a=a, D=D, P=P, Pbool=Pbool, f_def=f_def, ctx=ctx}, thy)
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   132
    end
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   133
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   134
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   135
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   136
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   137
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   138
(* !!qs' qs. Gs ==> Gs' ==> lhs = lhs' ==> rhs = rhs' *)
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   139
fun mk_compat_impl ((qs, gs, lhs, rhs),(qs', gs', lhs', rhs')) =
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   140
    (implies $ Trueprop (mk_eq (lhs, lhs'))
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   141
             $ Trueprop (mk_eq (rhs, rhs')))
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   142
        |> fold_rev (curry Logic.mk_implies) (gs @ gs')
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   143
        |> fold_rev mk_forall (qs @ qs')
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   144
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   145
(* all proof obligations *)
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   146
fun mk_compat_proof_obligations glrs glrs' =
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   147
    map (fn ((x,_), (_,y')) => mk_compat_impl (x,y')) (unordered_pairs (glrs ~~ glrs'))
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   148
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   149
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   150
fun mk_completeness names glrs =
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   151
    let
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   152
        val Names {domT, x, Pbool, ...} = names
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   153
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   154
        fun mk_case (qs, gs, lhs, _) = Trueprop Pbool
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   155
                                                |> curry Logic.mk_implies (Trueprop (mk_eq (x, lhs)))
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   156
                                                |> fold_rev (curry Logic.mk_implies) gs
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   157
                                                |> fold_rev mk_forall qs
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   158
    in
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   159
        Trueprop Pbool
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   160
                 |> fold_rev (curry Logic.mk_implies o mk_case) glrs
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   161
                 |> mk_forall_rename (x, "x")
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   162
                 |> mk_forall_rename (Pbool, "P")
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   163
    end
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   164
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   165
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   166
fun inductive_def_wrap defs (thy, const) =
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   167
    let
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   168
      val qdefs = map dest_all_all defs
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   169
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   170
      val (thy, {intrs = intrs_gen, elims = [elim_gen], ...}) =
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   171
          InductivePackage.add_inductive_i true (*verbose*)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   172
                                             false (*add_consts*)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   173
                                             "" (* no altname *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   174
                                             false (* no coind *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   175
                                             false (* elims, please *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   176
                                             false (* induction thm please *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   177
                                             [const] (* the constant *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   178
                                             (map (fn (_,t) => (("", t),[])) qdefs) (* the intros *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   179
                                             [] (* no special monos *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   180
                                             thy
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   181
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   182
(* It would be nice if this worked... But this is actually HO-Unification... *)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   183
(*      fun inst (qs, intr) intr_gen =
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   184
          Goal.init (cterm_of thy intr)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   185
                    |> curry op COMP intr_gen
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   186
                    |> Goal.finish
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   187
                    |> fold_rev (forall_intr o cterm_of thy) qs*)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   188
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   189
      fun inst (qs, intr) intr_gen =
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   190
          intr_gen
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   191
            |> Thm.freezeT
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   192
            |> fold_rev (forall_intr o (fn Free (n, T) => cterm_of thy (Var ((n,0), T)))) qs
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   193
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   194
      val intrs = map2 inst qdefs intrs_gen
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   195
      val elim = elim_gen
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   196
                   |> Thm.freezeT
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   197
                   |> forall_intr_vars (* FIXME *)
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   198
    in
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   199
      (intrs, (thy, const, elim))
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   200
    end
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   201
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   202
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   203
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   204
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   205
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   206
(*
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   207
 * "!!qs xs. CS ==> G => (r, lhs) : R"
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   208
 *)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   209
fun mk_RIntro R (qs, gs, lhs, rhs) (rcfix, rcassm, rcarg) =
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   210
    mk_relmem (rcarg, lhs) R
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   211
              |> fold_rev (curry Logic.mk_implies o prop_of) rcassm
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   212
              |> fold_rev (curry Logic.mk_implies) gs
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   213
              |> fold_rev (mk_forall o Free) rcfix
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   214
              |> fold_rev mk_forall qs
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   215
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   216
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   217
fun mk_GIntro thy f_const f_var G (qs, gs, lhs, rhs) RCs =
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   218
    let
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   219
      fun mk_h_assm (rcfix, rcassm, rcarg) =
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   220
          mk_relmem (rcarg, f_var $ rcarg) G
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   221
                    |> fold_rev (curry Logic.mk_implies o prop_of) rcassm
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   222
                    |> fold_rev (mk_forall o Free) rcfix
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   223
    in
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   224
      mk_relmem (lhs, rhs) G
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   225
                |> fold_rev (curry Logic.mk_implies o mk_h_assm) RCs
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   226
                |> fold_rev (curry Logic.mk_implies) gs
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   227
                |> Pattern.rewrite_term thy [(f_const, f_var)] []
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   228
                |> fold_rev mk_forall (f_var :: qs)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   229
    end
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   230
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   231
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   232
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   233
fun mk_clause_info thy names no (qs,gs,lhs,rhs) tree RCs GIntro_thm RIntro_thms =
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   234
    let
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   235
        val Names {G, h, f, fvar, x, ...} = names
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   236
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   237
        val cqs = map (cterm_of thy) qs
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   238
        val ags = map (assume o cterm_of thy) gs
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   239
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   240
        val used = [] (* XXX *)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   241
                  (* FIXME: What is the relationship between this and mk_primed_vars? *)
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   242
        val qs' = map (fn Free (v,T) => Free (Name.variant used (v ^ "'"),T)) qs
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   243
        val cqs' = map (cterm_of thy) qs'
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   244
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   245
        val rename_vars = Pattern.rewrite_term thy (qs ~~ qs') []
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   246
        val ags' = map (assume o cterm_of thy o rename_vars) gs
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   247
        val lhs' = rename_vars lhs
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   248
        val rhs' = rename_vars rhs
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   249
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   250
        val lGI = GIntro_thm
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   251
                    |> forall_elim (cterm_of thy f)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   252
                    |> fold forall_elim cqs
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   253
                    |> fold implies_elim_swp ags
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   254
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   255
        (* FIXME: Can be removed when inductive-package behaves nicely. *)
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   256
        val ordcqs' = map (cterm_of thy o Pattern.rewrite_term thy ((fvar,h)::(qs ~~ qs')) [])
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   257
                          (term_frees (snd (dest_all_all (prop_of GIntro_thm))))
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   258
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   259
        fun mk_call_info (rcfix, rcassm, rcarg) RI =
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   260
            let
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   261
                val crcfix = map (cterm_of thy o Free) rcfix
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   262
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   263
                val llRI = RI
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   264
                             |> fold forall_elim cqs
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   265
                             |> fold forall_elim crcfix
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   266
                             |> fold implies_elim_swp ags
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   267
                             |> fold implies_elim_swp rcassm
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   268
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   269
                val h_assum =
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   270
                    mk_relmem (rcarg, h $ rcarg) G
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   271
                              |> fold_rev (curry Logic.mk_implies o prop_of) rcassm
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   272
                              |> fold_rev (mk_forall o Free) rcfix
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   273
                              |> Pattern.rewrite_term thy [(f, h)] []
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   274
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   275
                val Gh = assume (cterm_of thy h_assum)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   276
                val Gh' = assume (cterm_of thy (rename_vars h_assum))
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   277
            in
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   278
                RCInfo {RIvs=rcfix, Gh=Gh, Gh'=Gh', rcarg=rcarg, CCas=rcassm, llRI=llRI}
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   279
            end
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   280
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   281
        val case_hyp = assume (cterm_of thy (Trueprop (mk_eq (x, lhs))))
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   282
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   283
        val RC_infos = map2 mk_call_info RCs RIntro_thms
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   284
    in
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   285
        ClauseInfo
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   286
            {
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   287
             no=no,
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   288
             qs=qs, gs=gs, lhs=lhs, rhs=rhs,
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   289
             cqs=cqs, ags=ags,
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   290
             cqs'=cqs', ags'=ags', lhs'=lhs', rhs'=rhs',
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   291
             lGI=lGI, RCs=RC_infos,
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   292
             tree=tree, case_hyp = case_hyp,
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   293
             ordcqs'=ordcqs'
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   294
            }
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   295
    end
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   296
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   297
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   298
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   299
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   300
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   301
(* Copied from fundef_proof.ML: *)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   302
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   303
(***********************************************)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   304
(* Compat thms are stored in normal form (with vars) *)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   305
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   306
(* replace this by a table later*)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   307
fun store_compat_thms 0 thms = []
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   308
  | store_compat_thms n thms =
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   309
    let
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   310
        val (thms1, thms2) = chop n thms
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   311
    in
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   312
        (thms1 :: store_compat_thms (n - 1) thms2)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   313
    end
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   314
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   315
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   316
(* needs i <= j *)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   317
fun lookup_compat_thm i j cts =
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   318
    nth (nth cts (i - 1)) (j - i)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   319
(***********************************************)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   320
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   321
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   322
(* Returns "Gsi, Gsj', lhs_i = lhs_j' |-- rhs_j'_f = rhs_i_f" *)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   323
(* if j < i, then turn around *)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   324
fun get_compat_thm thy cts clausei clausej =
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   325
    let
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   326
        val ClauseInfo {no=i, cqs=qsi, ags=gsi, lhs=lhsi, ...} = clausei
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   327
        val ClauseInfo {no=j, cqs'=qsj', ags'=gsj', lhs'=lhsj', ...} = clausej
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   328
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   329
        val lhsi_eq_lhsj' = cterm_of thy (Trueprop (mk_eq (lhsi, lhsj')))
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   330
    in if j < i then
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   331
           let
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   332
               val compat = lookup_compat_thm j i cts
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   333
           in
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   334
               compat         (* "!!qj qi'. Gsj => Gsi' => lhsj = lhsi' ==> rhsj = rhsi'" *)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   335
                |> fold forall_elim (qsj' @ qsi) (* "Gsj' => Gsi => lhsj' = lhsi ==> rhsj' = rhsi" *)
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   336
                |> fold implies_elim_swp gsj'
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   337
                |> fold implies_elim_swp gsi
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   338
                |> implies_elim_swp ((assume lhsi_eq_lhsj') RS sym) (* "Gsj', Gsi, lhsi = lhsj' |-- rhsj' = rhsi" *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   339
           end
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   340
       else
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   341
           let
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   342
               val compat = lookup_compat_thm i j cts
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   343
           in
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   344
               compat        (* "!!qi qj'. Gsi => Gsj' => lhsi = lhsj' ==> rhsi = rhsj'" *)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   345
                 |> fold forall_elim (qsi @ qsj') (* "Gsi => Gsj' => lhsi = lhsj' ==> rhsi = rhsj'" *)
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   346
                 |> fold implies_elim_swp gsi
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   347
                 |> fold implies_elim_swp gsj'
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   348
                 |> implies_elim_swp (assume lhsi_eq_lhsj')
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   349
                 |> (fn thm => thm RS sym) (* "Gsi, Gsj', lhsi = lhsj' |-- rhsj' = rhsi" *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   350
           end
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   351
    end
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   352
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   353
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   354
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   355
(* Generates the replacement lemma with primed variables. A problem here is that one should not do
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   356
the complete requantification at the end to replace the variables. One should find a way to be more efficient
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   357
here. *)
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   358
fun mk_replacement_lemma thy (names:naming_context) ih_elim clause =
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   359
    let
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   360
        val Names {fvar, f, x, y, h, Pbool, G, ranT, domT, R, ...} = names
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   361
        val ClauseInfo {qs,cqs,ags,lhs,rhs,cqs',ags',case_hyp, RCs, tree, ...} = clause
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   362
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   363
        val ih_elim_case = full_simplify (HOL_basic_ss addsimps [case_hyp]) ih_elim
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   364
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   365
        val Ris = map (fn RCInfo {llRI, ...} => llRI) RCs
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   366
        val h_assums = map (fn RCInfo {Gh, ...} => Gh) RCs
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   367
        val h_assums' = map (fn RCInfo {Gh', ...} => Gh') RCs
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   368
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   369
        val ih_elim_case_inst = instantiate' [] [NONE, SOME (cterm_of thy h)] ih_elim_case (* Should be done globally *)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   370
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   371
        val (eql, _) = FundefCtxTree.rewrite_by_tree thy f h ih_elim_case_inst (Ris ~~ h_assums) tree
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   372
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   373
        val replace_lemma = (eql RS meta_eq_to_obj_eq)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   374
                                |> implies_intr (cprop_of case_hyp)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   375
                                |> fold_rev (implies_intr o cprop_of) h_assums
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   376
                                |> fold_rev (implies_intr o cprop_of) ags
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   377
                                |> fold_rev forall_intr cqs
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   378
                                |> fold forall_elim cqs'
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   379
                                |> fold implies_elim_swp ags'
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   380
                                |> fold implies_elim_swp h_assums'
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   381
    in
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   382
      replace_lemma
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   383
    end
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   384
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   385
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   386
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   387
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   388
fun mk_uniqueness_clause thy names compat_store clausei clausej RLj =
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   389
    let
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   390
        val Names {f, h, y, ...} = names
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   391
        val ClauseInfo {no=i, lhs=lhsi, case_hyp, ...} = clausei
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   392
        val ClauseInfo {no=j, ags'=gsj', lhs'=lhsj', rhs'=rhsj', RCs=RCsj, ordcqs'=ordcqs'j, ...} = clausej
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   393
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   394
        val rhsj'h = Pattern.rewrite_term thy [(f,h)] [] rhsj'
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   395
        val compat = get_compat_thm thy compat_store clausei clausej
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   396
        val Ghsj' = map (fn RCInfo {Gh', ...} => Gh') RCsj
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   397
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   398
        val y_eq_rhsj'h = assume (cterm_of thy (Trueprop (mk_eq (y, rhsj'h))))
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   399
        val lhsi_eq_lhsj' = assume (cterm_of thy (Trueprop (mk_eq (lhsi, lhsj')))) (* lhs_i = lhs_j' |-- lhs_i = lhs_j' *)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   400
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   401
        val eq_pairs = assume (cterm_of thy (Trueprop (mk_eq (mk_prod (lhsi, y), mk_prod (lhsj',rhsj'h)))))
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   402
    in
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   403
        (trans OF [case_hyp, lhsi_eq_lhsj']) (* lhs_i = lhs_j' |-- x = lhs_j' *)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   404
        |> implies_elim RLj (* Rj1' ... Rjk', lhs_i = lhs_j' |-- rhs_j'_h = rhs_j'_f *)
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   405
        |> (fn it => trans OF [it, compat]) (* lhs_i = lhs_j', Gj', Rj1' ... Rjk' |-- rhs_j'_h = rhs_i_f *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   406
        |> (fn it => trans OF [y_eq_rhsj'h, it]) (* lhs_i = lhs_j', Gj', Rj1' ... Rjk', y = rhs_j_h' |-- y = rhs_i_f *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   407
        |> implies_intr (cprop_of y_eq_rhsj'h)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   408
        |> implies_intr (cprop_of lhsi_eq_lhsj') (* Gj', Rj1' ... Rjk' |-- [| lhs_i = lhs_j', y = rhs_j_h' |] ==> y = rhs_i_f *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   409
        |> (fn it => Drule.compose_single(it, 2, Pair_inject)) (* Gj', Rj1' ... Rjk' |-- (lhs_i, y) = (lhs_j', rhs_j_h') ==> y = rhs_i_f *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   410
        |> implies_elim_swp eq_pairs
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   411
        |> fold_rev (implies_intr o cprop_of) Ghsj'
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   412
        |> fold_rev (implies_intr o cprop_of) gsj' (* Gj', Rj1', ..., Rjk' ==> (lhs_i, y) = (lhs_j', rhs_j_h') ==> y = rhs_i_f *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   413
        |> implies_intr (cprop_of eq_pairs)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   414
        |> fold_rev forall_intr ordcqs'j
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   415
    end
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   416
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   417
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   418
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   419
fun mk_uniqueness_case thy names ihyp ih_intro G_cases compat_store clauses rep_lemmas clausei =
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   420
    let
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   421
        val Names {x, y, G, fvar, f, ranT, ...} = names
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   422
        val ClauseInfo {lhs, rhs, qs, cqs, ags, case_hyp, lGI, RCs, ...} = clausei
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   423
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   424
        val ih_intro_case = full_simplify (HOL_basic_ss addsimps [case_hyp]) ih_intro
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   425
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   426
        fun prep_RC (RCInfo {llRI, RIvs, CCas, ...}) = (llRI RS ih_intro_case)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   427
                                                            |> fold_rev (implies_intr o cprop_of) CCas
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   428
                                                            |> fold_rev (forall_intr o cterm_of thy o Free) RIvs
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   429
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   430
        val existence = lGI (*|> instantiate ([], [(cterm_of thy (free_to_var fvar), cterm_of thy f)])*)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   431
                            |> fold (curry op COMP o prep_RC) RCs
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   432
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   433
        val a = cterm_of thy (mk_prod (lhs, y))
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   434
        val P = cterm_of thy (mk_eq (y, rhs))
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   435
        val a_in_G = assume (cterm_of thy (Trueprop (mk_mem (term_of a, G))))
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   436
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   437
        val unique_clauses = map2 (mk_uniqueness_clause thy names compat_store clausei) clauses rep_lemmas
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   438
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   439
        val uniqueness = G_cases
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   440
                           |> forall_elim a
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   441
                           |> forall_elim P
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   442
                           |> implies_elim_swp a_in_G
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   443
                           |> fold implies_elim_swp unique_clauses
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   444
                           |> implies_intr (cprop_of a_in_G)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   445
                           |> forall_intr (cterm_of thy y)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   446
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   447
        val P2 = cterm_of thy (lambda y (mk_mem (mk_prod (lhs, y), G))) (* P2 y := (lhs, y): G *)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   448
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   449
        val exactly_one =
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   450
            ex1I |> instantiate' [SOME (ctyp_of thy ranT)] [SOME P2, SOME (cterm_of thy rhs)]
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   451
                 |> curry (op COMP) existence
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   452
                 |> curry (op COMP) uniqueness
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   453
                 |> simplify (HOL_basic_ss addsimps [case_hyp RS sym])
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   454
                 |> implies_intr (cprop_of case_hyp)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   455
                 |> fold_rev (implies_intr o cprop_of) ags
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   456
                 |> fold_rev forall_intr cqs
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   457
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   458
        val function_value =
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   459
            existence
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   460
                |> fold_rev (implies_intr o cprop_of) ags
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   461
                |> implies_intr ihyp
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   462
                |> implies_intr (cprop_of case_hyp)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   463
                |> forall_intr (cterm_of thy x)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   464
                |> forall_elim (cterm_of thy lhs)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   465
                |> curry (op RS) refl
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   466
    in
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   467
        (exactly_one, function_value)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   468
    end
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   469
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   470
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   471
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   472
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   473
fun prove_stuff thy congs names clauses complete compat compat_store G_elim R_elim =
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   474
    let
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   475
        val Names {G, R, acc_R, domT, ranT, f, f_def, x, z, fvarname, Pbool, ...}:naming_context = names
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   476
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   477
        val f_def_fr = Thm.freezeT f_def
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   478
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   479
        val instantiate_and_def = (instantiate' [SOME (ctyp_of thy domT), SOME (ctyp_of thy ranT)]
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   480
                                                [SOME (cterm_of thy f), SOME (cterm_of thy G)])
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   481
                                      #> curry op COMP (forall_intr_vars f_def_fr)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   482
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   483
        val inst_ex1_ex = instantiate_and_def ex1_implies_ex
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   484
        val inst_ex1_un = instantiate_and_def ex1_implies_un
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   485
        val inst_ex1_iff = instantiate_and_def ex1_implies_iff
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   486
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   487
        (* Inductive Hypothesis: !!z. (z,x):R ==> EX!y. (z,y):G *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   488
        val ihyp = all domT $ Abs ("z", domT,
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   489
                                   implies $ Trueprop (mk_relmemT domT domT (Bound 0, x) R)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   490
                                           $ Trueprop (Const ("Ex1", (ranT --> boolT) --> boolT) $
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   491
                                                             Abs ("y", ranT, mk_relmemT domT ranT (Bound 1, Bound 0) G)))
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   492
                       |> cterm_of thy
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   493
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   494
        val ihyp_thm = assume ihyp |> forall_elim_vars 0
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   495
        val ih_intro = ihyp_thm RS inst_ex1_ex
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   496
        val ih_elim = ihyp_thm RS inst_ex1_un
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   497
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   498
        val _ = Output.debug "Proving Replacement lemmas..."
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   499
        val repLemmas = map (mk_replacement_lemma thy names ih_elim) clauses
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   500
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   501
        val _ = Output.debug "Proving cases for unique existence..."
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   502
        val (ex1s, values) = split_list (map (mk_uniqueness_case thy names ihyp ih_intro G_elim compat_store clauses repLemmas) clauses)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   503
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   504
        val _ = Output.debug "Proving: Graph is a function" (* FIXME: Rewrite this proof. *)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   505
        val graph_is_function = complete
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   506
                                  |> forall_elim_vars 0
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   507
                                  |> fold (curry op COMP) ex1s
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   508
                                  |> implies_intr (ihyp)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   509
                                  |> implies_intr (cterm_of thy (Trueprop (mk_mem (x, acc_R))))
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   510
                                  |> forall_intr (cterm_of thy x)
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   511
                                  |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   512
                                  |> (fn it => fold (forall_intr o cterm_of thy) (term_vars (prop_of it)) it)
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   513
                                  |> Drule.close_derivation
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   514
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   515
        val goal = complete COMP (graph_is_function COMP conjunctionI)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   516
                            |> Drule.close_derivation
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   517
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   518
        val goalI = Goal.protect goal
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   519
                                 |> fold_rev (implies_intr o cprop_of) compat
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   520
                                 |> implies_intr (cprop_of complete)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   521
    in
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   522
      (prop_of goal, goalI, inst_ex1_iff, values)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   523
    end
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   524
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   525
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   526
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   527
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   528
19564
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   529
(*
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   530
 * This is the first step in a function definition.
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   531
 *
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   532
 * Defines the function, the graph and the termination relation, synthesizes completeness
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   533
 * and comatibility conditions and returns everything.
d3e2f532459a First usable version of the new function definition package (HOL/function_packake/...).
krauss
parents:
diff changeset
   534
 *)
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   535
fun prepare_fundef thy congs defname f qglrs used =
19770
be5c23ebe1eb HOL/Tools/function_package: Added support for mutual recursive definitions.
krauss
parents: 19583
diff changeset
   536
    let
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   537
      val (names, thy) = setup_context f qglrs defname thy
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   538
      val Names {G, R, ctx, glrs', fvar, ...} = names
19770
be5c23ebe1eb HOL/Tools/function_package: Added support for mutual recursive definitions.
krauss
parents: 19583
diff changeset
   539
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   540
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   541
      val n = length qglrs
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   542
      val trees = map (build_tree thy f congs ctx) qglrs
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   543
      val RCss = map find_calls trees
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   544
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   545
      val complete = mk_completeness names qglrs
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   546
                                     |> cterm_of thy
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   547
                                     |> assume
19770
be5c23ebe1eb HOL/Tools/function_package: Added support for mutual recursive definitions.
krauss
parents: 19583
diff changeset
   548
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   549
      val compat = mk_compat_proof_obligations qglrs glrs'
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   550
                           |> map (assume o cterm_of thy)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   551
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   552
      val compat_store = compat
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   553
                           |> store_compat_thms n
19770
be5c23ebe1eb HOL/Tools/function_package: Added support for mutual recursive definitions.
krauss
parents: 19583
diff changeset
   554
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   555
      val R_intross = map2 (fn qglr => map (mk_RIntro R qglr)) qglrs RCss
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   556
      val G_intros = map2 (mk_GIntro thy f fvar G) qglrs RCss
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   557
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   558
      val (GIntro_thms, (thy, _, G_elim)) = inductive_def_wrap G_intros (thy, G)
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   559
      val (RIntro_thmss, (thy, _, R_elim)) = fold_burrow inductive_def_wrap R_intross (thy, R)
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   560
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   561
      val clauses = map6 (mk_clause_info thy names) (1 upto n) qglrs trees RCss GIntro_thms RIntro_thmss
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   562
19922
984ae977f7aa Fixed name clash.
krauss
parents: 19876
diff changeset
   563
      val (goal, goalI, ex1_iff, values) = prove_stuff thy congs names clauses complete compat compat_store G_elim R_elim
19770
be5c23ebe1eb HOL/Tools/function_package: Added support for mutual recursive definitions.
krauss
parents: 19583
diff changeset
   564
    in
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   565
        (Prep {names = names, goal = goal, goalI = goalI, values = values, clauses = clauses, ex1_iff = ex1_iff, R_cases = R_elim},
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19922
diff changeset
   566
         thy)
19770
be5c23ebe1eb HOL/Tools/function_package: Added support for mutual recursive definitions.
krauss
parents: 19583
diff changeset
   567
    end
be5c23ebe1eb HOL/Tools/function_package: Added support for mutual recursive definitions.
krauss
parents: 19583
diff changeset
   568
be5c23ebe1eb HOL/Tools/function_package: Added support for mutual recursive definitions.
krauss
parents: 19583
diff changeset
   569
be5c23ebe1eb HOL/Tools/function_package: Added support for mutual recursive definitions.
krauss
parents: 19583
diff changeset
   570
be5c23ebe1eb HOL/Tools/function_package: Added support for mutual recursive definitions.
krauss
parents: 19583
diff changeset
   571
19876
wenzelm
parents: 19781
diff changeset
   572
end