src/HOL/Tools/function_package/fundef_prep.ML
changeset 21051 c49467a9c1e1
parent 20797 c1f0bc7e7d80
child 21100 cda93bbf35db
equal deleted inserted replaced
21050:d0447a511edb 21051:c49467a9c1e1
    20 
    20 
    21 structure FundefPrep : FUNDEF_PREP =
    21 structure FundefPrep : FUNDEF_PREP =
    22 struct
    22 struct
    23 
    23 
    24 
    24 
       
    25 open FundefLib
    25 open FundefCommon
    26 open FundefCommon
    26 open FundefAbbrev
    27 open FundefAbbrev
    27 
    28 
    28 (* Theory dependencies. *)
    29 (* Theory dependencies. *)
    29 val Pair_inject = thm "Product_Type.Pair_inject";
    30 val Pair_inject = thm "Product_Type.Pair_inject";
    30 
    31 
    31 val acc_induct_rule = thm "Accessible_Part.acc_induct_rule"
    32 val acc_induct_rule = thm "FunDef.accP_induct_rule"
    32 
    33 
    33 val ex1_implies_ex = thm "FunDef.fundef_ex1_existence"
    34 val ex1_implies_ex = thm "FunDef.fundef_ex1_existence"
    34 val ex1_implies_un = thm "FunDef.fundef_ex1_uniqueness"
    35 val ex1_implies_un = thm "FunDef.fundef_ex1_uniqueness"
    35 val ex1_implies_iff = thm "FunDef.fundef_ex1_iff"
    36 val ex1_implies_iff = thm "FunDef.fundef_ex1_iff"
    36 
    37 
   141                              |> fold (forall_elim o cert o Free) rcfix
   142                              |> fold (forall_elim o cert o Free) rcfix
   142                              |> fold implies_elim_swp ags
   143                              |> fold implies_elim_swp ags
   143                              |> fold implies_elim_swp rcassm
   144                              |> fold implies_elim_swp rcassm
   144 
   145 
   145                 val h_assum =
   146                 val h_assum =
   146                     mk_relmem (rcarg, h $ rcarg) G
   147                     Trueprop (G $ rcarg $ (h $ rcarg))
   147                               |> fold_rev (curry Logic.mk_implies o prop_of) rcassm
   148                               |> fold_rev (curry Logic.mk_implies o prop_of) rcassm
   148                               |> fold_rev (mk_forall o Free) rcfix
   149                               |> fold_rev (mk_forall o Free) rcfix
   149                               |> Pattern.rewrite_term (ProofContext.theory_of ctxt) [(f, h)] []
   150                               |> Pattern.rewrite_term (ProofContext.theory_of ctxt) [(f, h)] []
   150                               |> abstract_over_list (rev qs)
   151                               |> abstract_over_list (rev qs)
   151             in
   152             in
   270                 |> fold implies_elim_swp agsj'
   271                 |> fold implies_elim_swp agsj'
   271                 |> fold implies_elim_swp Ghsj'
   272                 |> fold implies_elim_swp Ghsj'
   272 
   273 
   273         val y_eq_rhsj'h = assume (cterm_of thy (Trueprop (mk_eq (y, rhsj'h))))
   274         val y_eq_rhsj'h = assume (cterm_of thy (Trueprop (mk_eq (y, rhsj'h))))
   274         val lhsi_eq_lhsj' = assume (cterm_of thy (Trueprop (mk_eq (lhsi, lhsj')))) (* lhs_i = lhs_j' |-- lhs_i = lhs_j' *)
   275         val lhsi_eq_lhsj' = assume (cterm_of thy (Trueprop (mk_eq (lhsi, lhsj')))) (* lhs_i = lhs_j' |-- lhs_i = lhs_j' *)
   275 
       
   276         val eq_pairs = assume (cterm_of thy (Trueprop (mk_eq (mk_prod (lhsi, y), mk_prod (lhsj',rhsj'h)))))
       
   277     in
   276     in
   278         (trans OF [case_hyp, lhsi_eq_lhsj']) (* lhs_i = lhs_j' |-- x = lhs_j' *)
   277         (trans OF [case_hyp, lhsi_eq_lhsj']) (* lhs_i = lhs_j' |-- x = lhs_j' *)
   279         |> implies_elim RLj_import (* Rj1' ... Rjk', lhs_i = lhs_j' |-- rhs_j'_h = rhs_j'_f *)
   278         |> implies_elim RLj_import (* Rj1' ... Rjk', lhs_i = lhs_j' |-- rhs_j'_h = rhs_j'_f *)
   280         |> (fn it => trans OF [it, compat]) (* lhs_i = lhs_j', Gj', Rj1' ... Rjk' |-- rhs_j'_h = rhs_i_f *)
   279         |> (fn it => trans OF [it, compat]) (* lhs_i = lhs_j', Gj', Rj1' ... Rjk' |-- rhs_j'_h = rhs_i_f *)
   281         |> (fn it => trans OF [y_eq_rhsj'h, it]) (* lhs_i = lhs_j', Gj', Rj1' ... Rjk', y = rhs_j_h' |-- y = rhs_i_f *)
   280         |> (fn it => trans OF [y_eq_rhsj'h, it]) (* lhs_i = lhs_j', Gj', Rj1' ... Rjk', y = rhs_j_h' |-- y = rhs_i_f *)
       
   281         |> fold_rev (implies_intr o cprop_of) Ghsj'
       
   282         |> fold_rev (implies_intr o cprop_of) agsj' (* lhs_i = lhs_j' , y = rhs_j_h' |-- Gj', Rj1'...Rjk' ==> y = rhs_i_f *)
   282         |> implies_intr (cprop_of y_eq_rhsj'h)
   283         |> implies_intr (cprop_of y_eq_rhsj'h)
   283         |> implies_intr (cprop_of lhsi_eq_lhsj') (* Gj', Rj1' ... Rjk' |-- [| lhs_i = lhs_j', y = rhs_j_h' |] ==> y = rhs_i_f *)
   284         |> implies_intr (cprop_of lhsi_eq_lhsj')
   284         |> (fn it => Drule.compose_single(it, 2, Pair_inject)) (* Gj', Rj1' ... Rjk' |-- (lhs_i, y) = (lhs_j', rhs_j_h') ==> y = rhs_i_f *)
       
   285         |> implies_elim_swp eq_pairs
       
   286         |> fold_rev (implies_intr o cprop_of) Ghsj'
       
   287         |> fold_rev (implies_intr o cprop_of) agsj' (* Gj', Rj1', ..., Rjk' ==> (lhs_i, y) = (lhs_j', rhs_j_h') ==> y = rhs_i_f *)
       
   288         |> implies_intr (cprop_of eq_pairs)
       
   289         |> fold_rev forall_intr (cterm_of thy h :: cqsj')
   285         |> fold_rev forall_intr (cterm_of thy h :: cqsj')
   290     end
   286     end
   291 
   287 
   292 
   288 
   293 
   289 
   303                                                             |> fold_rev (implies_intr o cprop_of) CCas
   299                                                             |> fold_rev (implies_intr o cprop_of) CCas
   304                                                             |> fold_rev (forall_intr o cterm_of thy o Free) RIvs
   300                                                             |> fold_rev (forall_intr o cterm_of thy o Free) RIvs
   305 
   301 
   306         val existence = fold (curry op COMP o prep_RC) RCs lGI
   302         val existence = fold (curry op COMP o prep_RC) RCs lGI
   307 
   303 
   308         val a = cterm_of thy (mk_prod (lhs, y))
       
   309         val P = cterm_of thy (mk_eq (y, rhsC))
   304         val P = cterm_of thy (mk_eq (y, rhsC))
   310         val a_in_G = assume (cterm_of thy (Trueprop (mk_mem (term_of a, G))))
   305         val G_lhs_y = assume (cterm_of thy (Trueprop (G $ lhs $ y)))
   311 
   306 
   312         val unique_clauses = map2 (mk_uniqueness_clause thy globals f compat_store clausei) clauses rep_lemmas
   307         val unique_clauses = map2 (mk_uniqueness_clause thy globals f compat_store clausei) clauses rep_lemmas
   313 
   308 
   314         val uniqueness = G_cases
   309         val uniqueness = G_cases
   315                            |> forall_elim a
   310                            |> forall_elim (cterm_of thy lhs)
       
   311                            |> forall_elim (cterm_of thy y)
   316                            |> forall_elim P
   312                            |> forall_elim P
   317                            |> implies_elim_swp a_in_G
   313                            |> implies_elim_swp G_lhs_y
   318                            |> fold implies_elim_swp unique_clauses
   314                            |> fold implies_elim_swp unique_clauses
   319                            |> implies_intr (cprop_of a_in_G)
   315                            |> implies_intr (cprop_of G_lhs_y)
   320                            |> forall_intr (cterm_of thy y)
   316                            |> forall_intr (cterm_of thy y)
   321 
   317 
   322         val P2 = cterm_of thy (lambda y (mk_mem (mk_prod (lhs, y), G))) (* P2 y := (lhs, y): G *)
   318         val P2 = cterm_of thy (lambda y (G $ lhs $ y)) (* P2 y := (lhs, y): G *)
   323 
   319 
   324         val exactly_one =
   320         val exactly_one =
   325             ex1I |> instantiate' [SOME (ctyp_of thy ranT)] [SOME P2, SOME (cterm_of thy rhsC)]
   321             ex1I |> instantiate' [SOME (ctyp_of thy ranT)] [SOME P2, SOME (cterm_of thy rhsC)]
   326                  |> curry (op COMP) existence
   322                  |> curry (op COMP) existence
   327                  |> curry (op COMP) uniqueness
   323                  |> curry (op COMP) uniqueness
   330                  |> fold_rev (implies_intr o cprop_of) ags
   326                  |> fold_rev (implies_intr o cprop_of) ags
   331                  |> fold_rev forall_intr cqs
   327                  |> fold_rev forall_intr cqs
   332 
   328 
   333         val function_value =
   329         val function_value =
   334             existence
   330             existence
   335                 |> implies_intr ihyp
   331               |> implies_intr ihyp
   336                 |> implies_intr (cprop_of case_hyp)
   332               |> implies_intr (cprop_of case_hyp)
   337                 |> forall_intr (cterm_of thy x)
   333               |> forall_intr (cterm_of thy x)
   338                 |> forall_elim (cterm_of thy lhs)
   334               |> forall_elim (cterm_of thy lhs)
   339                 |> curry (op RS) refl
   335               |> curry (op RS) refl
   340     in
   336     in
   341         (exactly_one, function_value)
   337         (exactly_one, function_value)
   342     end
   338     end
   343 
   339 
   344 
   340 
   346 
   342 
   347 fun prove_stuff thy congs globals G f R clauses complete compat compat_store G_elim f_def =
   343 fun prove_stuff thy congs globals G f R clauses complete compat compat_store G_elim f_def =
   348     let
   344     let
   349         val Globals {h, domT, ranT, x, ...} = globals
   345         val Globals {h, domT, ranT, x, ...} = globals
   350 
   346 
   351         val inst_ex1_ex = f_def RS ex1_implies_ex
   347         val inst_ex1_ex =  f_def RS ex1_implies_ex
   352         val inst_ex1_un = f_def RS ex1_implies_un
   348         val inst_ex1_un =  f_def RS ex1_implies_un
   353         val inst_ex1_iff = f_def RS ex1_implies_iff
   349         val inst_ex1_iff = f_def RS ex1_implies_iff
   354 
   350 
   355         (* Inductive Hypothesis: !!z. (z,x):R ==> EX!y. (z,y):G *)
   351         (* Inductive Hypothesis: !!z. (z,x):R ==> EX!y. (z,y):G *)
   356         val ihyp = all domT $ Abs ("z", domT,
   352         val ihyp = all domT $ Abs ("z", domT,
   357                                    implies $ Trueprop (mk_relmemT domT domT (Bound 0, x) R)
   353                                    implies $ Trueprop (R $ Bound 0 $ x)
   358                                            $ Trueprop (Const ("Ex1", (ranT --> boolT) --> boolT) $
   354                                            $ Trueprop (Const ("Ex1", (ranT --> boolT) --> boolT) $
   359                                                              Abs ("y", ranT, mk_relmemT domT ranT (Bound 1, Bound 0) G)))
   355                                                              Abs ("y", ranT, G $ Bound 1 $ Bound 0)))
   360                        |> cterm_of thy
   356                        |> cterm_of thy
   361 
   357 
   362         val ihyp_thm = assume ihyp |> forall_elim_vars 0
   358         val ihyp_thm = assume ihyp |> forall_elim_vars 0
   363         val ih_intro = ihyp_thm RS inst_ex1_ex
   359         val ih_intro = ihyp_thm RS inst_ex1_ex
   364         val ih_elim = ihyp_thm RS inst_ex1_un
   360         val ih_elim = ihyp_thm RS inst_ex1_un
   373         val _ = Output.debug "Proving: Graph is a function" (* FIXME: Rewrite this proof. *)
   369         val _ = Output.debug "Proving: Graph is a function" (* FIXME: Rewrite this proof. *)
   374         val graph_is_function = complete
   370         val graph_is_function = complete
   375                                   |> forall_elim_vars 0
   371                                   |> forall_elim_vars 0
   376                                   |> fold (curry op COMP) ex1s
   372                                   |> fold (curry op COMP) ex1s
   377                                   |> implies_intr (ihyp)
   373                                   |> implies_intr (ihyp)
   378                                   |> implies_intr (cterm_of thy (Trueprop (mk_mem (x, mk_acc domT R))))
   374                                   |> implies_intr (cterm_of thy (Trueprop (mk_acc domT R $ x)))
   379                                   |> forall_intr (cterm_of thy x)
   375                                   |> forall_intr (cterm_of thy x)
   380                                   |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *)
   376                                   |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *)
   381                                   |> (fn it => fold (forall_intr o cterm_of thy) (term_vars (prop_of it)) it)
   377                                   |> (fn it => fold (forall_intr o cterm_of thy) (term_vars (prop_of it)) it)
   382                                   |> Drule.close_derivation
   378                                   |> Drule.close_derivation
   383 
   379 
   392     end
   388     end
   393 
   389 
   394 
   390 
   395 fun define_graph Gname fvar domT ranT clauses RCss lthy =
   391 fun define_graph Gname fvar domT ranT clauses RCss lthy =
   396     let
   392     let
   397       val GT = mk_relT (domT, ranT)
   393       val GT = domT --> ranT --> boolT
   398       val Gvar = Free (the_single (Variable.variant_frees lthy [] [(Gname, GT)]))
   394       val Gvar = Free (the_single (Variable.variant_frees lthy [] [(Gname, GT)]))
   399 
   395 
   400       fun mk_GIntro (ClauseContext {qs, gs, lhs, rhs, ...}) RCs =
   396       fun mk_GIntro (ClauseContext {qs, gs, lhs, rhs, ...}) RCs =
   401           let
   397           let
   402             fun mk_h_assm (rcfix, rcassm, rcarg) =
   398             fun mk_h_assm (rcfix, rcassm, rcarg) =
   403                 mk_relmem (rcarg, fvar $ rcarg) Gvar
   399                 Trueprop (Gvar $ rcarg $ (fvar $ rcarg))
   404                           |> fold_rev (curry Logic.mk_implies o prop_of) rcassm
   400                           |> fold_rev (curry Logic.mk_implies o prop_of) rcassm
   405                           |> fold_rev (mk_forall o Free) rcfix
   401                           |> fold_rev (mk_forall o Free) rcfix
   406           in
   402           in
   407             mk_relmem (lhs, rhs) Gvar
   403             Trueprop (Gvar $ lhs $ rhs)
   408                       |> fold_rev (curry Logic.mk_implies o mk_h_assm) RCs
   404                       |> fold_rev (curry Logic.mk_implies o mk_h_assm) RCs
   409                       |> fold_rev (curry Logic.mk_implies) gs
   405                       |> fold_rev (curry Logic.mk_implies) gs
   410                       |> fold_rev mk_forall (fvar :: qs)
   406                       |> fold_rev mk_forall (fvar :: qs)
   411           end
   407           end
   412           
   408           
   422 
   418 
   423 fun define_function fdefname (fname, mixfix) domT ranT G default lthy =
   419 fun define_function fdefname (fname, mixfix) domT ranT G default lthy =
   424     let
   420     let
   425       val f_def = 
   421       val f_def = 
   426           Abs ("x", domT, Const ("FunDef.THE_default", ranT --> (ranT --> boolT) --> ranT) $ (default $ Bound 0) $
   422           Abs ("x", domT, Const ("FunDef.THE_default", ranT --> (ranT --> boolT) --> ranT) $ (default $ Bound 0) $
   427                                 Abs ("y", ranT, mk_relmemT domT ranT (Bound 1, Bound 0) G))
   423                                 Abs ("y", ranT, G $ Bound 1 $ Bound 0))
       
   424               |> Envir.beta_norm (* Fixme: LocalTheory.def does not work if not beta-normal *)
   428           
   425           
   429       val ((f, (_, f_defthm)), lthy) = LocalTheory.def ((fname ^ "C", mixfix), ((fdefname, []), f_def)) lthy
   426       val ((f, (_, f_defthm)), lthy) = LocalTheory.def ((fname ^ "C", mixfix), ((fdefname, []), f_def)) lthy
   430     in
   427     in
   431       ((f, f_defthm), lthy)
   428       ((f, f_defthm), lthy)
   432     end
   429     end
   433 
   430 
   434 
   431 
   435 fun define_recursion_relation Rname domT ranT fvar f qglrs clauses RCss lthy =
   432 fun define_recursion_relation Rname domT ranT fvar f qglrs clauses RCss lthy =
   436     let
   433     let
   437 
   434 
   438       val RT = mk_relT (domT, domT)
   435       val RT = domT --> domT --> boolT
   439       val Rvar = Free (the_single (Variable.variant_frees lthy [] [(Rname, RT)]))
   436       val Rvar = Free (the_single (Variable.variant_frees lthy [] [(Rname, RT)]))
   440 
   437 
   441       fun mk_RIntro (ClauseContext {qs, gs, lhs, ...}, (oqs, _, _, _)) (rcfix, rcassm, rcarg) =
   438       fun mk_RIntro (ClauseContext {qs, gs, lhs, ...}, (oqs, _, _, _)) (rcfix, rcassm, rcarg) =
   442           mk_relmem (rcarg, lhs) Rvar
   439           Trueprop (Rvar $ rcarg $ lhs)
   443                     |> fold_rev (curry Logic.mk_implies o prop_of) rcassm
   440                     |> fold_rev (curry Logic.mk_implies o prop_of) rcassm
   444                     |> fold_rev (curry Logic.mk_implies) gs
   441                     |> fold_rev (curry Logic.mk_implies) gs
   445                     |> fold_rev (mk_forall o Free) rcfix
   442                     |> fold_rev (mk_forall o Free) rcfix
   446                     |> fold_rev mk_forall_rename (map fst oqs ~~ qs)
   443                     |> fold_rev mk_forall_rename (map fst oqs ~~ qs)
   447                     (* "!!qs xs. CS ==> G => (r, lhs) : R" *)
   444                     (* "!!qs xs. CS ==> G => (r, lhs) : R" *)
   463       (Globals {h = Free (h, domT --> ranT),
   460       (Globals {h = Free (h, domT --> ranT),
   464                 y = Free (y, ranT),
   461                 y = Free (y, ranT),
   465                 x = Free (x, domT),
   462                 x = Free (x, domT),
   466                 z = Free (z, domT),
   463                 z = Free (z, domT),
   467                 a = Free (a, domT),
   464                 a = Free (a, domT),
   468                 D = Free (D, HOLogic.mk_setT domT),
   465                 D = Free (D, domT --> boolT),
   469                 P = Free (P, domT --> boolT),
   466                 P = Free (P, domT --> boolT),
   470                 Pbool = Free (Pbool, boolT),
   467                 Pbool = Free (Pbool, boolT),
   471                 fvar = fvar,
   468                 fvar = fvar,
   472                 domT = domT,
   469                 domT = domT,
   473                 ranT = ranT
   470                 ranT = ranT
   519       val trees = map (FundefCtxTree.inst_tree (ProofContext.theory_of lthy) fvar f) trees
   516       val trees = map (FundefCtxTree.inst_tree (ProofContext.theory_of lthy) fvar f) trees
   520 
   517 
   521       val ((R, RIntro_thmss, R_elim), lthy) = 
   518       val ((R, RIntro_thmss, R_elim), lthy) = 
   522           define_recursion_relation (defname ^ "_rel") domT ranT fvar f abstract_qglrs clauses RCss lthy
   519           define_recursion_relation (defname ^ "_rel") domT ranT fvar f abstract_qglrs clauses RCss lthy
   523 
   520 
   524       val dom_abbrev = Logic.mk_equals (Free (defname ^ "_dom", fastype_of (mk_acc domT R)), mk_acc domT R)
   521       val dom_abbrev = Logic.mk_equals (Free (defname ^ "_dom", domT --> boolT), mk_acc domT R)
   525       val lthy = Specification.abbreviation_i ("", false) [(NONE, dom_abbrev)] lthy
   522       val lthy = Specification.abbreviation_i ("", false) [(NONE, dom_abbrev)] lthy
   526 
   523 
   527       val newthy = ProofContext.theory_of lthy
   524       val newthy = ProofContext.theory_of lthy
   528       val clauses = map (transfer_clause_ctx newthy) clauses
   525       val clauses = map (transfer_clause_ctx newthy) clauses
   529 
   526