Nominal/nominal_function_core.ML
changeset 2821 c7d4bd9e89e0
parent 2819 4bd584ff4fab
child 2822 23befefc6e73
equal deleted inserted replaced
2820:77e1d9f2925e 2821:c7d4bd9e89e0
     4     heavily based on the code of Alexander Krauss
     4     heavily based on the code of Alexander Krauss
     5     (code forked on 14 January 2011)
     5     (code forked on 14 January 2011)
     6 
     6 
     7 Core of the nominal function package.
     7 Core of the nominal function package.
     8 *)
     8 *)
       
     9 
       
    10 
       
    11 structure Nominal_Function_Common =
       
    12 struct
       
    13 
       
    14 
       
    15 (* Configuration management *)
       
    16 datatype nominal_function_opt
       
    17   = Sequential
       
    18   | Default of string
       
    19   | DomIntros
       
    20   | No_Partials
       
    21   | Invariant of string
       
    22 
       
    23 datatype nominal_function_config = NominalFunctionConfig of
       
    24  {sequential: bool,
       
    25   default: string option,
       
    26   domintros: bool,
       
    27   partials: bool,
       
    28   inv: string option}
       
    29 
       
    30 fun apply_opt Sequential (NominalFunctionConfig {sequential, default, domintros, partials, inv}) =
       
    31     NominalFunctionConfig 
       
    32       {sequential=true, default=default, domintros=domintros, partials=partials, inv=inv}
       
    33   | apply_opt (Default d) (NominalFunctionConfig {sequential, default, domintros, partials, inv}) =
       
    34     NominalFunctionConfig 
       
    35       {sequential=sequential, default=SOME d, domintros=domintros, partials=partials, inv=inv}
       
    36   | apply_opt DomIntros (NominalFunctionConfig {sequential, default, domintros, partials, inv}) =
       
    37     NominalFunctionConfig 
       
    38       {sequential=sequential, default=default, domintros=true, partials=partials, inv=inv}
       
    39   | apply_opt No_Partials (NominalFunctionConfig {sequential, default, domintros, partials, inv}) =
       
    40     NominalFunctionConfig 
       
    41       {sequential=sequential, default=default, domintros=domintros, partials=false, inv=inv}
       
    42   | apply_opt (Invariant s) (NominalFunctionConfig {sequential, default, domintros, partials, inv}) =
       
    43     NominalFunctionConfig 
       
    44       {sequential=sequential, default=default, domintros=domintros, partials=partials, inv = SOME s}
       
    45 
       
    46 val nominal_default_config =
       
    47   NominalFunctionConfig { sequential=false, default=NONE,
       
    48     domintros=false, partials=true, inv=NONE}
       
    49 
       
    50 end
       
    51 
     9 
    52 
    10 signature NOMINAL_FUNCTION_CORE =
    53 signature NOMINAL_FUNCTION_CORE =
    11 sig
    54 sig
    12   val trace: bool Unsynchronized.ref
    55   val trace: bool Unsynchronized.ref
    13 
    56 
    16     -> ((bstring * typ) * mixfix) list (* defined symbol *)
    59     -> ((bstring * typ) * mixfix) list (* defined symbol *)
    17     -> ((bstring * typ) list * term list * term * term) list (* specification *)
    60     -> ((bstring * typ) list * term list * term * term) list (* specification *)
    18     -> local_theory
    61     -> local_theory
    19     -> (term   (* f *)
    62     -> (term   (* f *)
    20         * thm  (* goalstate *)
    63         * thm  (* goalstate *)
    21         * (thm -> Nominal_Function_Common.function_result) (* continuation *)
    64         * (thm -> Function_Common.function_result) (* continuation *)
    22        ) * local_theory
    65        ) * local_theory
    23 
    66 
    24 end
    67 end
    25 
    68 
    26 structure Nominal_Function_Core : NOMINAL_FUNCTION_CORE =
    69 structure Nominal_Function_Core : NOMINAL_FUNCTION_CORE =
    31 
    74 
    32 val boolT = HOLogic.boolT
    75 val boolT = HOLogic.boolT
    33 val mk_eq = HOLogic.mk_eq
    76 val mk_eq = HOLogic.mk_eq
    34 
    77 
    35 open Function_Lib
    78 open Function_Lib
       
    79 open Function_Common
    36 open Nominal_Function_Common
    80 open Nominal_Function_Common
    37 
    81 
    38 datatype globals = Globals of
    82 datatype globals = Globals of
    39  {fvar: term,
    83  {fvar: term,
    40   domT: typ,
    84   domT: typ,
   121   in
   165   in
   122     Const (@{const_name eqvt}, ty --> @{typ bool}) $ trm
   166     Const (@{const_name eqvt}, ty --> @{typ bool}) $ trm
   123     |> HOLogic.mk_Trueprop
   167     |> HOLogic.mk_Trueprop
   124   end
   168   end
   125 
   169 
       
   170 fun mk_inv inv (f_trm, arg_trm) = 
       
   171   betapplys (inv, [arg_trm, (f_trm $ arg_trm)])
       
   172   |> HOLogic.mk_Trueprop
       
   173 
       
   174 fun mk_invariant (Globals {x, y, ...}) G invariant = 
       
   175   let
       
   176     val prem = HOLogic.mk_Trueprop (G $ x $ y)
       
   177     val concl = HOLogic.mk_Trueprop (betapplys (invariant, [x, y]))
       
   178   in
       
   179     Logic.mk_implies (prem, concl)
       
   180     |> mk_forall_rename ("y", y)
       
   181     |> mk_forall_rename ("x", x)
       
   182   end  
       
   183 
   126 (** building proof obligations *)
   184 (** building proof obligations *)
   127 fun mk_eqvt_proof_obligation qs fvar (vs, assms, arg) = 
   185 fun mk_eqvt_proof_obligation qs fvar (vs, assms, arg) = 
   128   mk_eqvt_at (fvar, arg)
   186   mk_eqvt_at (fvar, arg)
   129   |> curry Logic.list_implies (map prop_of assms)
   187   |> curry Logic.list_implies (map prop_of assms)
   130   |> curry Term.list_all_free vs
   188   |> curry Term.list_all_free vs
   131   |> curry Term.list_abs_free qs
   189   |> curry Term.list_abs_free qs
   132   |> strip_abs_body
   190   |> strip_abs_body
   133 
   191 
       
   192 fun mk_inv_proof_obligation inv qs fvar (vs, assms, arg) = 
       
   193   mk_inv inv (fvar, arg)
       
   194   |> curry Logic.list_implies (map prop_of assms)
       
   195   |> curry Term.list_all_free vs
       
   196   |> curry Term.list_abs_free qs
       
   197   |> strip_abs_body
       
   198 
   134 (** building proof obligations *)
   199 (** building proof obligations *)
   135 fun mk_compat_proof_obligations domT ranT fvar f RCss glrs =
   200 fun mk_compat_proof_obligations domT ranT fvar f RCss inv glrs =
   136   let
   201   let
   137     fun mk_impl (((qs, gs, lhs, rhs), RCs), ((qs', gs', lhs', rhs'), _)) =
   202     fun mk_impl (((qs, gs, lhs, rhs), RCs), ((qs', gs', lhs', rhs'), _)) =
   138       let
   203       let
   139         val shift = incr_boundvars (length qs')
   204         val shift = incr_boundvars (length qs')
   140         val eqvts_proof_obligations = map (shift o mk_eqvt_proof_obligation qs fvar) RCs
   205         val eqvts_proof_obligations = map (shift o mk_eqvt_proof_obligation qs fvar) RCs
       
   206         val invs_proof_obligations = map (shift o mk_inv_proof_obligation inv qs fvar) RCs
   141       in
   207       in
   142         Logic.mk_implies
   208         Logic.mk_implies
   143           (HOLogic.mk_Trueprop (HOLogic.eq_const domT $ shift lhs $ lhs'),
   209           (HOLogic.mk_Trueprop (HOLogic.eq_const domT $ shift lhs $ lhs'),
   144             HOLogic.mk_Trueprop (HOLogic.eq_const ranT $ shift rhs $ rhs'))
   210             HOLogic.mk_Trueprop (HOLogic.eq_const ranT $ shift rhs $ rhs'))
   145         |> fold_rev (curry Logic.mk_implies) (map shift gs @ gs')
   211         |> fold_rev (curry Logic.mk_implies) (map shift gs @ gs')
       
   212         |> fold_rev (curry Logic.mk_implies) invs_proof_obligations (* nominal *)
   146         |> fold_rev (curry Logic.mk_implies) eqvts_proof_obligations (* nominal *)
   213         |> fold_rev (curry Logic.mk_implies) eqvts_proof_obligations (* nominal *)
   147         |> fold_rev (fn (n,T) => fn b => Term.all T $ Abs(n,T,b)) (qs @ qs')
   214         |> fold_rev (fn (n,T) => fn b => Term.all T $ Abs(n,T,b)) (qs @ qs')
   148         |> curry abstract_over fvar
   215         |> curry abstract_over fvar
   149         |> curry subst_bound f
   216         |> curry subst_bound f
   150       end
   217       end
   151   in
   218   in
   152     map mk_impl (unordered_pairs (glrs ~~ RCss))
   219     map mk_impl (unordered_pairs (glrs ~~ RCss))
   153   end
   220   end
   154 
       
   155 
   221 
   156 fun mk_completeness (Globals {x, Pbool, ...}) clauses qglrs =
   222 fun mk_completeness (Globals {x, Pbool, ...}) clauses qglrs =
   157   let
   223   let
   158     fun mk_case (ClauseContext {qs, gs, lhs, ...}, (oqs, _, _, _)) =
   224     fun mk_case (ClauseContext {qs, gs, lhs, ...}, (oqs, _, _, _)) =
   159       HOLogic.mk_Trueprop Pbool
   225       HOLogic.mk_Trueprop Pbool
   258   nth (nth cts (i - 1)) (j - i)
   324   nth (nth cts (i - 1)) (j - i)
   259 
   325 
   260 (* nominal *)
   326 (* nominal *)
   261 (* Returns "Gsi, Gsj, lhs_i = lhs_j |-- rhs_j_f = rhs_i_f" *)
   327 (* Returns "Gsi, Gsj, lhs_i = lhs_j |-- rhs_j_f = rhs_i_f" *)
   262 (* if j < i, then turn around *)
   328 (* if j < i, then turn around *)
   263 fun get_compat_thm thy cts eqvtsi eqvtsj i j ctxi ctxj =
   329 fun get_compat_thm thy cts eqvtsi eqvtsj invsi invsj i j ctxi ctxj =
   264   let
   330   let
   265     val ClauseContext {cqs=cqsi,ags=agsi,lhs=lhsi,case_hyp=case_hypi,...} = ctxi
   331     val ClauseContext {cqs=cqsi,ags=agsi,lhs=lhsi,case_hyp=case_hypi,...} = ctxi
   266     val ClauseContext {cqs=cqsj,ags=agsj,lhs=lhsj,case_hyp=case_hypj,...} = ctxj
   332     val ClauseContext {cqs=cqsj,ags=agsj,lhs=lhsj,case_hyp=case_hypj,...} = ctxj
   267 
   333 
   268     val lhsi_eq_lhsj = cterm_of thy (HOLogic.mk_Trueprop (mk_eq (lhsi, lhsj)))
   334     val lhsi_eq_lhsj = cterm_of thy (HOLogic.mk_Trueprop (mk_eq (lhsi, lhsj)))
   271       val compat = lookup_compat_thm j i cts
   337       val compat = lookup_compat_thm j i cts
   272     in
   338     in
   273       compat         (* "!!qj qi. Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *)
   339       compat         (* "!!qj qi. Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *)
   274       |> fold Thm.forall_elim (cqsj @ cqsi) (* "Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *)
   340       |> fold Thm.forall_elim (cqsj @ cqsi) (* "Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *)
   275       |> fold Thm.elim_implies eqvtsj (* nominal *)
   341       |> fold Thm.elim_implies eqvtsj (* nominal *)
       
   342       |> fold Thm.elim_implies invsj (* nominal *)
   276       |> fold Thm.elim_implies agsj
   343       |> fold Thm.elim_implies agsj
   277       |> fold Thm.elim_implies agsi
   344       |> fold Thm.elim_implies agsi
   278       |> Thm.elim_implies ((Thm.assume lhsi_eq_lhsj) RS sym) (* "Gsj, Gsi, lhsi = lhsj |-- rhsj = rhsi" *)
   345       |> Thm.elim_implies ((Thm.assume lhsi_eq_lhsj) RS sym) (* "Gsj, Gsi, lhsi = lhsj |-- rhsj = rhsi" *)
   279     end
   346     end
   280     else
   347     else
   282       val compat = lookup_compat_thm i j cts
   349       val compat = lookup_compat_thm i j cts
   283     in
   350     in
   284       compat        (* "!!qi qj. Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *)
   351       compat        (* "!!qi qj. Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *)
   285       |> fold Thm.forall_elim (cqsi @ cqsj) (* "Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *)
   352       |> fold Thm.forall_elim (cqsi @ cqsj) (* "Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *)
   286       |> fold Thm.elim_implies eqvtsi  (* nominal *)
   353       |> fold Thm.elim_implies eqvtsi  (* nominal *)
       
   354       |> fold Thm.elim_implies invsi  (* nominal *)
   287       |> fold Thm.elim_implies agsi
   355       |> fold Thm.elim_implies agsi
   288       |> fold Thm.elim_implies agsj
   356       |> fold Thm.elim_implies agsj
   289       |> Thm.elim_implies (Thm.assume lhsi_eq_lhsj)
   357       |> Thm.elim_implies (Thm.assume lhsi_eq_lhsj)
   290       |> (fn thm => thm RS sym) (* "Gsi, Gsj, lhsi = lhsj |-- rhsj = rhsi" *)
   358       |> (fn thm => thm RS sym) (* "Gsi, Gsj, lhsi = lhsj |-- rhsj = rhsi" *)
   291     end
   359     end
   345     |> map (fold_rev Thm.forall_intr cqs)
   413     |> map (fold_rev Thm.forall_intr cqs)
   346     |> map (Thm.close_derivation) 
   414     |> map (Thm.close_derivation) 
   347   end
   415   end
   348 
   416 
   349 (* nominal *)
   417 (* nominal *)
   350 fun mk_uniqueness_clause thy globals compat_store eqvts clausei clausej RLj =
   418 fun mk_invariant_lemma thy ih_inv clause =
       
   419   let
       
   420     val ClauseInfo {cdata=ClauseContext {cqs, ags, case_hyp, ...}, RCs, ...} = clause
       
   421      
       
   422     local open Conv in
       
   423       val ih_conv = arg1_conv o arg_conv o arg_conv
       
   424     end
       
   425 
       
   426     val ih_inv_case =
       
   427       Conv.fconv_rule (ih_conv (K (case_hyp RS eq_reflection))) ih_inv
       
   428 
       
   429     fun prep_inv (RCInfo {llRI, RIvs, CCas, ...}) = 
       
   430         (llRI RS ih_inv_case)
       
   431         |> fold_rev (Thm.implies_intr o cprop_of) CCas
       
   432         |> fold_rev (Thm.forall_intr o cterm_of thy o Free) RIvs 
       
   433   in
       
   434     map prep_inv RCs
       
   435     |> map (fold_rev (Thm.implies_intr o cprop_of) ags)
       
   436     |> map (Thm.implies_intr (cprop_of case_hyp))
       
   437     |> map (fold_rev Thm.forall_intr cqs)
       
   438     |> map (Thm.close_derivation) 
       
   439   end
       
   440 
       
   441 (* nominal *)
       
   442 fun mk_uniqueness_clause thy globals compat_store eqvts invs clausei clausej RLj =
   351   let
   443   let
   352     val Globals {h, y, x, fvar, ...} = globals
   444     val Globals {h, y, x, fvar, ...} = globals
   353     val ClauseInfo {no=i, cdata=cctxi as ClauseContext {ctxt=ctxti, lhs=lhsi, case_hyp, cqs = cqsi, 
   445     val ClauseInfo {no=i, cdata=cctxi as ClauseContext {ctxt=ctxti, lhs=lhsi, case_hyp, cqs = cqsi, 
   354       ags = agsi, ...}, ...} = clausei
   446       ags = agsi, ...}, ...} = clausei
   355     val ClauseInfo {no=j, qglr=cdescj, RCs=RCsj, ...} = clausej
   447     val ClauseInfo {no=j, qglr=cdescj, RCs=RCsj, ...} = clausej
   381     val eqvtsj = nth eqvts (j - 1)
   473     val eqvtsj = nth eqvts (j - 1)
   382       |> map (fold Thm.forall_elim cqsj')
   474       |> map (fold Thm.forall_elim cqsj')
   383       |> map (fold Thm.elim_implies [case_hypj'])
   475       |> map (fold Thm.elim_implies [case_hypj'])
   384       |> map (fold Thm.elim_implies agsj')
   476       |> map (fold Thm.elim_implies agsj')
   385 
   477 
   386     val compat = get_compat_thm thy compat_store eqvtsi eqvtsj i j cctxi cctxj
   478     val invsi = nth invs (i - 1)
       
   479       |> map (fold Thm.forall_elim cqsi)
       
   480       |> map (fold Thm.elim_implies [case_hyp])
       
   481       |> map (fold Thm.elim_implies agsi)
       
   482 
       
   483     val invsj = nth invs (j - 1)
       
   484       |> map (fold Thm.forall_elim cqsj')
       
   485       |> map (fold Thm.elim_implies [case_hypj'])
       
   486       |> map (fold Thm.elim_implies agsj')
       
   487 
       
   488     val compat = get_compat_thm thy compat_store eqvtsi eqvtsj invsi invsj i j cctxi cctxj
   387 
   489 
   388   in
   490   in
   389     (trans OF [case_hyp, lhsi_eq_lhsj']) (* lhs_i = lhs_j' |-- x = lhs_j' *)
   491     (trans OF [case_hyp, lhsi_eq_lhsj']) (* lhs_i = lhs_j' |-- x = lhs_j' *)
   390     |> Thm.implies_elim RLj_import
   492     |> Thm.implies_elim RLj_import
   391       (* Rj1' ... Rjk', lhs_i = lhs_j' |-- rhs_j'_h = rhs_j'_f *)
   493       (* Rj1' ... Rjk', lhs_i = lhs_j' |-- rhs_j'_h = rhs_j'_f *)
   400     |> Thm.implies_intr (cprop_of lhsi_eq_lhsj')
   502     |> Thm.implies_intr (cprop_of lhsi_eq_lhsj')
   401     |> fold_rev Thm.forall_intr (cterm_of thy h :: cqsj')
   503     |> fold_rev Thm.forall_intr (cterm_of thy h :: cqsj')
   402   end
   504   end
   403 
   505 
   404 (* nominal *)
   506 (* nominal *)
   405 fun mk_uniqueness_case thy globals G f ihyp ih_intro G_cases compat_store clauses replems eqvtlems clausei =
   507 fun mk_uniqueness_case thy globals G f ihyp ih_intro G_cases compat_store clauses replems eqvtlems invlems 
       
   508   clausei =
   406   let
   509   let
   407     val Globals {x, y, ranT, fvar, ...} = globals
   510     val Globals {x, y, ranT, fvar, ...} = globals
   408     val ClauseInfo {cdata = ClauseContext {lhs, rhs, cqs, ags, case_hyp, ...}, lGI, RCs, ...} = clausei
   511     val ClauseInfo {cdata = ClauseContext {lhs, rhs, cqs, ags, case_hyp, ...}, lGI, RCs, ...} = clausei
   409     val rhsC = Pattern.rewrite_term thy [(fvar, f)] [] rhs
   512     val rhsC = Pattern.rewrite_term thy [(fvar, f)] [] rhs
   410 
   513 
   419 
   522 
   420     val P = cterm_of thy (mk_eq (y, rhsC))
   523     val P = cterm_of thy (mk_eq (y, rhsC))
   421     val G_lhs_y = Thm.assume (cterm_of thy (HOLogic.mk_Trueprop (G $ lhs $ y)))
   524     val G_lhs_y = Thm.assume (cterm_of thy (HOLogic.mk_Trueprop (G $ lhs $ y)))
   422 
   525 
   423     val unique_clauses =
   526     val unique_clauses =
   424       map2 (mk_uniqueness_clause thy globals compat_store eqvtlems clausei) clauses replems
   527       map2 (mk_uniqueness_clause thy globals compat_store eqvtlems invlems clausei) clauses replems
   425 
   528 
   426     fun elim_implies_eta A AB =
   529     fun elim_implies_eta A AB =
   427       Thm.compose_no_flatten true (A, 0) 1 AB |> Seq.list_of |> the_single
   530       Thm.compose_no_flatten true (A, 0) 1 AB |> Seq.list_of |> the_single
   428  
   531  
   429     val uniqueness = G_cases
   532     val uniqueness = G_cases
   457     (exactly_one, function_value)
   560     (exactly_one, function_value)
   458   end
   561   end
   459 
   562 
   460 
   563 
   461 (* nominal *)
   564 (* nominal *)
   462 fun prove_stuff ctxt globals G f R clauses complete compat compat_store G_elim G_eqvt f_def =
   565 fun prove_stuff ctxt globals G f R clauses complete compat compat_store G_elim G_eqvt invariant f_def =
   463   let
   566   let
   464     val Globals {h, domT, ranT, x, ...} = globals
   567     val Globals {h, domT, ranT, x, ...} = globals
   465     val thy = ProofContext.theory_of ctxt
   568     val thy = ProofContext.theory_of ctxt
   466 
   569 
   467     (* Inductive Hypothesis: !!z. (z,x):R ==> EX!y. (z,y):G *)
   570     (* Inductive Hypothesis: !!z. (z,x):R ==> EX!y. (z,y):G *)
   474     val ihyp_thm = Thm.assume ihyp |> Thm.forall_elim_vars 0
   577     val ihyp_thm = Thm.assume ihyp |> Thm.forall_elim_vars 0
   475     val ih_intro = ihyp_thm RS (f_def RS ex1_implies_ex)
   578     val ih_intro = ihyp_thm RS (f_def RS ex1_implies_ex)
   476     val ih_elim = ihyp_thm RS (f_def RS ex1_implies_un)
   579     val ih_elim = ihyp_thm RS (f_def RS ex1_implies_un)
   477       |> instantiate' [] [NONE, SOME (cterm_of thy h)]
   580       |> instantiate' [] [NONE, SOME (cterm_of thy h)]
   478     val ih_eqvt = ihyp_thm RS (G_eqvt RS (f_def RS @{thm fundef_ex1_eqvt_at}))
   581     val ih_eqvt = ihyp_thm RS (G_eqvt RS (f_def RS @{thm fundef_ex1_eqvt_at}))
   479  
   582     val ih_inv =  ihyp_thm RS (invariant COMP (f_def RS @{thm fundef_ex1_prop}))
       
   583 
   480     val _ = trace_msg (K "Proving Replacement lemmas...")
   584     val _ = trace_msg (K "Proving Replacement lemmas...")
   481     val repLemmas = map (mk_replacement_lemma thy h ih_elim) clauses
   585     val repLemmas = map (mk_replacement_lemma thy h ih_elim) clauses
   482 
   586 
   483     val _ = trace_msg (K "Proving Equivariance lemmas...")
   587     val _ = trace_msg (K "Proving Equivariance lemmas...")
   484     val eqvtLemmas = map (mk_eqvt_lemma thy ih_eqvt) clauses
   588     val eqvtLemmas = map (mk_eqvt_lemma thy ih_eqvt) clauses
       
   589 
       
   590     val _ = trace_msg (K "Proving Invariance lemmas...")
       
   591     val invLemmas = map (mk_invariant_lemma thy ih_inv) clauses
   485 
   592 
   486     val _ = trace_msg (K "Proving cases for unique existence...")
   593     val _ = trace_msg (K "Proving cases for unique existence...")
   487     val (ex1s, values) =
   594     val (ex1s, values) =
   488       split_list (map (mk_uniqueness_case thy globals G f 
   595       split_list (map (mk_uniqueness_case thy globals G f 
   489         ihyp ih_intro G_elim compat_store clauses repLemmas eqvtLemmas) clauses)
   596         ihyp ih_intro G_elim compat_store clauses repLemmas eqvtLemmas invLemmas) clauses)
   490      
   597      
   491     val _ = trace_msg (K "Proving: Graph is a function")
   598     val _ = trace_msg (K "Proving: Graph is a function")
   492     val graph_is_function = complete
   599     val graph_is_function = complete
   493       |> Thm.forall_elim_vars 0
   600       |> Thm.forall_elim_vars 0
   494       |> fold (curry op COMP) ex1s
   601       |> fold (curry op COMP) ex1s
   497       |> Thm.forall_intr (cterm_of thy x)
   604       |> Thm.forall_intr (cterm_of thy x)
   498       |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *)
   605       |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *)
   499       |> (fn it => fold (Thm.forall_intr o cterm_of thy o Var) (Term.add_vars (prop_of it) []) it)
   606       |> (fn it => fold (Thm.forall_intr o cterm_of thy o Var) (Term.add_vars (prop_of it) []) it)
   500 
   607 
   501     val goalstate =  
   608     val goalstate =  
   502          Conjunction.intr (Conjunction.intr graph_is_function complete) G_eqvt 
   609          Conjunction.intr (Conjunction.intr (Conjunction.intr graph_is_function complete) invariant) G_eqvt 
   503       |> Thm.close_derivation
   610       |> Thm.close_derivation
   504       |> Goal.protect
   611       |> Goal.protect
   505       |> fold_rev (Thm.implies_intr o cprop_of) compat
   612       |> fold_rev (Thm.implies_intr o cprop_of) compat
   506       |> Thm.implies_intr (cprop_of complete)
   613       |> Thm.implies_intr (cprop_of complete)
       
   614       |> Thm.implies_intr (cprop_of invariant)
   507       |> Thm.implies_intr (cprop_of G_eqvt)
   615       |> Thm.implies_intr (cprop_of G_eqvt)
   508   in
   616   in
   509     (goalstate, values)
   617     (goalstate, values)
   510   end
   618   end
   511 
   619 
   903 
  1011 
   904 
  1012 
   905 (* nominal *)
  1013 (* nominal *)
   906 fun prepare_nominal_function config defname [((fname, fT), mixfix)] abstract_qglrs lthy =
  1014 fun prepare_nominal_function config defname [((fname, fT), mixfix)] abstract_qglrs lthy =
   907   let
  1015   let
   908     val NominalFunctionConfig {domintros, default=default_opt, ...} = config
  1016     val NominalFunctionConfig {domintros, default=default_opt, inv=invariant_opt,...} = config
   909 
  1017 
   910     val default_str = the_default "%x. undefined" default_opt (*FIXME dynamic scoping*)
  1018     val default_str = the_default "%x. undefined" default_opt (*FIXME dynamic scoping*)
       
  1019     val invariant_str = the_default "%x y. True" invariant_opt
   911     val fvar = Free (fname, fT)
  1020     val fvar = Free (fname, fT)
   912     val domT = domain_type fT
  1021     val domT = domain_type fT
   913     val ranT = range_type fT
  1022     val ranT = range_type fT
   914 
  1023 
   915     val default = Syntax.parse_term lthy default_str
  1024     val default = Syntax.parse_term lthy default_str
   916       |> Type.constraint fT |> Syntax.check_term lthy
  1025       |> Type.constraint fT |> Syntax.check_term lthy
   917 
  1026 
       
  1027     val invariant_trm = Syntax.parse_term lthy invariant_str
       
  1028       |> Type.constraint ([domT, ranT] ---> @{typ bool}) |> Syntax.check_term lthy
       
  1029     
   918     val (globals, ctxt') = fix_globals domT ranT fvar lthy
  1030     val (globals, ctxt') = fix_globals domT ranT fvar lthy
   919 
  1031 
   920     val Globals { x, h, ... } = globals
  1032     val Globals { x, h, ... } = globals
   921 
  1033 
   922     val clauses = map (mk_clause_context x ctxt') abstract_qglrs
  1034     val clauses = map (mk_clause_context x ctxt') abstract_qglrs
   955 
  1067 
   956     val complete =
  1068     val complete =
   957       mk_completeness globals clauses abstract_qglrs |> cert |> Thm.assume
  1069       mk_completeness globals clauses abstract_qglrs |> cert |> Thm.assume
   958 
  1070 
   959     val compat =
  1071     val compat =
   960       mk_compat_proof_obligations domT ranT fvar f RCss abstract_qglrs 
  1072       mk_compat_proof_obligations domT ranT fvar f RCss invariant_trm abstract_qglrs 
   961       |> map (cert #> Thm.assume)
  1073       |> map (cert #> Thm.assume)
   962 
  1074 
   963     val G_eqvt = mk_eqvt G |> cert |> Thm.assume
  1075     val G_eqvt = mk_eqvt G |> cert |> Thm.assume
   964  
  1076  
       
  1077     val invariant = mk_invariant globals G invariant_trm |> cert |> Thm.assume
       
  1078  
   965     val compat_store = store_compat_thms n compat
  1079     val compat_store = store_compat_thms n compat
   966 
  1080 
   967     val (goalstate, values) = PROFILE "prove_stuff"
  1081     val (goalstate, values) = PROFILE "prove_stuff"
   968       (prove_stuff lthy globals G f R xclauses complete compat
  1082       (prove_stuff lthy globals G f R xclauses complete compat
   969          compat_store G_elim G_eqvt) f_defthm
  1083          compat_store G_elim G_eqvt invariant) f_defthm
   970      
  1084      
   971     fun mk_partial_rules provedgoal =
  1085     fun mk_partial_rules provedgoal =
   972       let
  1086       let
   973         val newthy = theory_of_thm provedgoal (*FIXME*)
  1087         val newthy = theory_of_thm provedgoal (*FIXME*)
   974 
  1088 
   975         val ((graph_is_function, complete_thm), _) =
  1089         val (graph_is_function, complete_thm) =
   976           provedgoal
  1090           provedgoal
       
  1091           |> fst o Conjunction.elim
       
  1092           |> fst o Conjunction.elim
   977           |> Conjunction.elim
  1093           |> Conjunction.elim
   978           |>> Conjunction.elim
  1094           |> apfst (Thm.forall_elim_vars 0)
   979           |>> apfst (Thm.forall_elim_vars 0)
       
   980 
  1095 
   981         val f_iff = graph_is_function RS (f_defthm RS ex1_implies_iff)
  1096         val f_iff = graph_is_function RS (f_defthm RS ex1_implies_iff)
   982 
  1097 
   983         val psimps = PROFILE "Proving simplification rules"
  1098         val psimps = PROFILE "Proving simplification rules"
   984           (mk_psimps newthy globals R xclauses values f_iff) graph_is_function
  1099           (mk_psimps newthy globals R xclauses values f_iff) graph_is_function