Nominal/Ex/LamTest.thy
changeset 2660 3342a2d13d95
parent 2657 1ea9c059fc0f
child 2661 16896fd8eff5
equal deleted inserted replaced
2659:619ecb57db38 2660:3342a2d13d95
    31   shows "finite (supp (f x))"
    31   shows "finite (supp (f x))"
    32 apply(rule finite_subset)
    32 apply(rule finite_subset)
    33 apply(rule supp_eqvt_at[OF asm fin])
    33 apply(rule supp_eqvt_at[OF asm fin])
    34 apply(rule fin)
    34 apply(rule fin)
    35 done
    35 done
       
    36 
       
    37 lemma fresh_eqvt_at:
       
    38   assumes asm: "eqvt_at f x"
       
    39   and     fin: "finite (supp x)"
       
    40   and     fresh: "as \<sharp>* x"
       
    41   shows "as \<sharp>* f x"
       
    42 using fresh
       
    43 unfolding fresh_star_def
       
    44 unfolding fresh_def
       
    45 using supp_eqvt_at[OF asm fin]
       
    46 by auto
    36 
    47 
    37 definition
    48 definition
    38  "eqvt f \<equiv> \<forall>p. p \<bullet> f = f"
    49  "eqvt f \<equiv> \<forall>p. p \<bullet> f = f"
    39 
    50 
    40 lemma eqvtI:
    51 lemma eqvtI:
   149 val acc_downward = @{thm accp_downward}
   160 val acc_downward = @{thm accp_downward}
   150 val accI = @{thm accp.accI}
   161 val accI = @{thm accp.accI}
   151 val case_split = @{thm HOL.case_split}
   162 val case_split = @{thm HOL.case_split}
   152 val fundef_default_value = @{thm FunDef.fundef_default_value}
   163 val fundef_default_value = @{thm FunDef.fundef_default_value}
   153 val not_acc_down = @{thm not_accp_down}
   164 val not_acc_down = @{thm not_accp_down}
   154 
   165 *}
   155 
   166 
   156 
   167 
       
   168 ML {*
   157 fun find_calls tree =
   169 fun find_calls tree =
   158   let
   170   let
   159     fun add_Ri (fixes,assumes) (_ $ arg) _ (_, xs) =
   171     fun add_Ri (fixes,assumes) (_ $ arg) _ (_, xs) =
   160       ([], (fixes, assumes, arg) :: xs)
   172       ([], (fixes, assumes, arg) :: xs)
   161       | add_Ri _ _ _ _ = raise Match
   173       | add_Ri _ _ _ _ = raise Match
   190 ML {*
   202 ML {*
   191 (** building proof obligations *)
   203 (** building proof obligations *)
   192 
   204 
   193 fun mk_compat_proof_obligations domT ranT fvar f glrs =
   205 fun mk_compat_proof_obligations domT ranT fvar f glrs =
   194   let
   206   let
   195     (*
       
   196     val _ = tracing ("domT: " ^ @{make_string} domT)
       
   197     val _ = tracing ("ranT: " ^ @{make_string} ranT)
       
   198     val _ = tracing ("fvar: " ^ @{make_string} fvar)
       
   199     val _ = tracing ("f: " ^ @{make_string} f)
       
   200     *)
       
   201  
       
   202     fun mk_impl ((qs, gs, lhs, rhs), (qs', gs', lhs', rhs')) =
   207     fun mk_impl ((qs, gs, lhs, rhs), (qs', gs', lhs', rhs')) =
   203       let
   208       let
   204         val shift = incr_boundvars (length qs')
   209         val shift = incr_boundvars (length qs')
   205 
   210 
   206         val RCs_rhs  = find_calls2 fvar rhs
   211         val RCs_rhs  = find_calls2 fvar rhs
   208       in
   213       in
   209         Logic.mk_implies
   214         Logic.mk_implies
   210           (HOLogic.mk_Trueprop (HOLogic.eq_const domT $ shift lhs $ lhs'),
   215           (HOLogic.mk_Trueprop (HOLogic.eq_const domT $ shift lhs $ lhs'),
   211             HOLogic.mk_Trueprop (HOLogic.eq_const ranT $ shift rhs $ rhs'))
   216             HOLogic.mk_Trueprop (HOLogic.eq_const ranT $ shift rhs $ rhs'))
   212         |> fold_rev (curry Logic.mk_implies) (map shift gs @ gs')
   217         |> fold_rev (curry Logic.mk_implies) (map shift gs @ gs')
   213         |> fold_rev (curry Logic.mk_implies) (map (shift o mk_eqvt_at) RCs_rhs) 
   218         |> fold_rev (curry Logic.mk_implies) (map (shift o mk_eqvt_at) RCs_rhs) (* HERE *) 
   214         |> fold_rev (curry Logic.mk_implies) (map mk_eqvt_at RCs_rhs')
   219         (*|> fold_rev (curry Logic.mk_implies) (map mk_eqvt_at RCs_rhs')*) (* HERE *) 
   215         (*|> (curry Logic.mk_implies) @{term "Trueprop True"}*)  (* HERE *)
       
   216         |> fold_rev (fn (n,T) => fn b => Term.all T $ Abs(n,T,b)) (qs @ qs')
   220         |> fold_rev (fn (n,T) => fn b => Term.all T $ Abs(n,T,b)) (qs @ qs')
   217         |> curry abstract_over fvar
   221         |> curry abstract_over fvar
   218         |> curry subst_bound f
   222         |> curry subst_bound f
   219       end
   223       end
   220   in
   224   in
   221     map mk_impl (unordered_pairs glrs)
   225     map mk_impl (unordered_pairs glrs)
   222     (*|> tap (fn ts => tracing ("compat_trms:\n" ^ cat_lines (map (Syntax.string_of_term @{context}) ts)))
       
   223     *)
       
   224   end
   226   end
   225 *}
   227 *}
   226 
   228 
   227 ML {*
   229 ML {*
   228 fun mk_completeness (Globals {x, Pbool, ...}) clauses qglrs =
   230 fun mk_completeness (Globals {x, Pbool, ...}) clauses qglrs =
   236     HOLogic.mk_Trueprop Pbool
   238     HOLogic.mk_Trueprop Pbool
   237     |> fold_rev (curry Logic.mk_implies o mk_case) (clauses ~~ qglrs)
   239     |> fold_rev (curry Logic.mk_implies o mk_case) (clauses ~~ qglrs)
   238     |> mk_forall_rename ("x", x)
   240     |> mk_forall_rename ("x", x)
   239     |> mk_forall_rename ("P", Pbool)
   241     |> mk_forall_rename ("P", Pbool)
   240   end
   242   end
       
   243 *}
   241 
   244 
   242 (** making a context with it's own local bindings **)
   245 (** making a context with it's own local bindings **)
       
   246 ML {*
   243 
   247 
   244 fun mk_clause_context x ctxt (pre_qs,pre_gs,pre_lhs,pre_rhs) =
   248 fun mk_clause_context x ctxt (pre_qs,pre_gs,pre_lhs,pre_rhs) =
   245   let
   249   let
   246     val (qs, ctxt') = Variable.variant_fixes (map fst pre_qs) ctxt
   250     val (qs, ctxt') = Variable.variant_fixes (map fst pre_qs) ctxt
   247       |>> map2 (fn (_, T) => fn n => Free (n, T)) pre_qs
   251       |>> map2 (fn (_, T) => fn n => Free (n, T)) pre_qs
   259     val case_hyp = Thm.assume (cterm_of thy (HOLogic.mk_Trueprop (mk_eq (x, lhs))))
   263     val case_hyp = Thm.assume (cterm_of thy (HOLogic.mk_Trueprop (mk_eq (x, lhs))))
   260   in
   264   in
   261     ClauseContext { ctxt = ctxt', qs = qs, gs = gs, lhs = lhs, rhs = rhs,
   265     ClauseContext { ctxt = ctxt', qs = qs, gs = gs, lhs = lhs, rhs = rhs,
   262       cqs = cqs, ags = ags, case_hyp = case_hyp }
   266       cqs = cqs, ags = ags, case_hyp = case_hyp }
   263   end
   267   end
   264 
   268 *}
   265 
   269 
       
   270 ML {*
   266 (* lowlevel term function. FIXME: remove *)
   271 (* lowlevel term function. FIXME: remove *)
   267 fun abstract_over_list vs body =
   272 fun abstract_over_list vs body =
   268   let
   273   let
   269     fun abs lev v tm =
   274     fun abs lev v tm =
   270       if v aconv tm then Bound lev
   275       if v aconv tm then Bound lev
   325   in
   330   in
   326     (thms1 :: store_compat_thms (n - 1) thms2)
   331     (thms1 :: store_compat_thms (n - 1) thms2)
   327   end
   332   end
   328 *}
   333 *}
   329 
   334 
   330 
   335 ML {*
   331 ML {*
   336 fun pp_thm thm =
   332 fun eqvt_at_elim thm =
   337   let
       
   338     val hyps = Thm.hyps_of thm
       
   339     val tpairs = Thm.terms_of_tpairs (Thm.tpairs_of thm)
       
   340   in
       
   341       (@{make_string} thm) ^ "\n    hyps: " ^ (commas (map (Syntax.string_of_term @{context}) hyps))
       
   342       ^ "    tpairs: " ^   (commas (map (Syntax.string_of_term @{context}) tpairs))
       
   343   end
       
   344 *}
       
   345 
       
   346 
       
   347 ML {*
       
   348 (*
       
   349 fun eqvt_at_elim thy (eqvts:thm list) thm =
   333   case (prop_of thm) of
   350   case (prop_of thm) of
   334     Const ("==>", _) $ (t as (@{term Trueprop} $ (Const (@{const_name eqvt_at}, _) $ _ $ _))) $ _ => 
   351     Const ("==>", _) $ (t as (@{term Trueprop} $ (Const (@{const_name eqvt_at}, _) $ _ $ _))) $ _ => 
   335       let
   352       let
   336         val el_thm = Skip_Proof.make_thm @{theory} t
   353         val el_thm = Skip_Proof.make_thm thy t
       
   354         val _ = tracing ("NEED TO PROVE  " ^ @{make_string} el_thm)
       
   355         val _ = tracing ("HAVE\n" ^ cat_lines (map @{make_string} eqvts))
   337       in
   356       in
   338         Thm.elim_implies el_thm thm 
   357         Thm.elim_implies el_thm thm 
   339         |> eqvt_at_elim
   358         |> eqvt_at_elim thy eqvts 
   340       end
   359       end
   341   | _ => thm
   360   | _ => thm
       
   361 *)
   342 *}
   362 *}
   343 
   363 
   344 ML {*
   364 ML {*
   345 (* expects i <= j *)
   365 (* expects i <= j *)
   346 fun lookup_compat_thm i j cts =
   366 fun lookup_compat_thm i j cts =
   347   nth (nth cts (i - 1)) (j - i)
   367   nth (nth cts (i - 1)) (j - i)
   348 
   368 
   349 (* Returns "Gsi, Gsj, lhs_i = lhs_j |-- rhs_j_f = rhs_i_f" *)
   369 (* Returns "Gsi, Gsj, lhs_i = lhs_j |-- rhs_j_f = rhs_i_f" *)
   350 (* if j < i, then turn around *)
   370 (* if j < i, then turn around *)
   351 fun get_compat_thm thy cts i j ctxi ctxj =
   371 fun get_compat_thm thy cts eqvtsi eqvtsj i j ctxi ctxj =
   352   let
   372   let
   353     val ClauseContext {cqs=cqsi,ags=agsi,lhs=lhsi,...} = ctxi
   373     val ClauseContext {cqs=cqsi,ags=agsi,lhs=lhsi,...} = ctxi
   354     val ClauseContext {cqs=cqsj,ags=agsj,lhs=lhsj,...} = ctxj
   374     val ClauseContext {cqs=cqsj,ags=agsj,lhs=lhsj,...} = ctxj
   355 
   375 
   356     val lhsi_eq_lhsj = cterm_of thy (HOLogic.mk_Trueprop (mk_eq (lhsi, lhsj)))
   376     val lhsi_eq_lhsj = cterm_of thy (HOLogic.mk_Trueprop (mk_eq (lhsi, lhsj)))
   357   in if j < i then
   377   in if j < i then
   358     let
   378     let
   359       val compat = lookup_compat_thm j i cts
   379       val compat = lookup_compat_thm j i cts
       
   380       val _ = tracing ("XXXX compat clause if:\n" ^ @{make_string} compat)
   360     in
   381     in
   361       compat         (* "!!qj qi. Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *)
   382       compat         (* "!!qj qi. Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *)
   362       |> fold Thm.forall_elim (cqsj @ cqsi) (* "Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *)
   383       |> fold Thm.forall_elim (cqsj @ cqsi) (* "Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *)
   363       (*|> tap (fn th => tracing ("NEED TO PROVE " ^ @{make_string} th))*)
   384       |> fold Thm.elim_implies (rev eqvtsj) (* HERE *)
   364       (*|> Thm.elim_implies @{thm TrueI}*) (* THERE *)
   385       (*|> eqvt_at_elim thy eqvtsj *)
   365       |> eqvt_at_elim 
       
   366       (*|> tap (fn th => tracing ("AFTER " ^ @{make_string} th))*)
       
   367       |> fold Thm.elim_implies agsj
   386       |> fold Thm.elim_implies agsj
   368       |> fold Thm.elim_implies agsi
   387       |> fold Thm.elim_implies agsi
   369       |> Thm.elim_implies ((Thm.assume lhsi_eq_lhsj) RS sym) (* "Gsj, Gsi, lhsi = lhsj |-- rhsj = rhsi" *)
   388       |> Thm.elim_implies ((Thm.assume lhsi_eq_lhsj) RS sym) (* "Gsj, Gsi, lhsi = lhsj |-- rhsj = rhsi" *)
   370     end
   389     end
   371     else
   390     else
   372     let
   391     let
   373       val compat = lookup_compat_thm i j cts
   392       val compat = lookup_compat_thm i j cts
       
   393       (* val _ = tracing ("XXXX compat clause else:\n" ^ @{make_string} compat) *)
   374     in
   394     in
   375       compat        (* "!!qi qj. Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *)
   395       compat        (* "!!qi qj. Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *)
   376       |> fold Thm.forall_elim (cqsi @ cqsj) (* "Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *)
   396       |> fold Thm.forall_elim (cqsi @ cqsj) (* "Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *)
   377       (*|> tap (fn th => tracing ("NEED TO PROVE " ^ @{make_string} th))*) 
   397       |> fold Thm.elim_implies (rev eqvtsi) (* HERE *)
   378       (*|> Thm.elim_implies @{thm TrueI}*)
   398       (* |> eqvt_at_elim thy eqvts *) 
   379       |> eqvt_at_elim 
       
   380       (*|> tap (fn th => tracing ("AFTER " ^ @{make_string} th))*)
       
   381       |> fold Thm.elim_implies agsi
   399       |> fold Thm.elim_implies agsi
   382       |> fold Thm.elim_implies agsj
   400       |> fold Thm.elim_implies agsj
   383       |> Thm.elim_implies (Thm.assume lhsi_eq_lhsj)
   401       |> Thm.elim_implies (Thm.assume lhsi_eq_lhsj)
   384       |> (fn thm => thm RS sym) (* "Gsi, Gsj, lhsi = lhsj |-- rhsj = rhsi" *)
   402       |> (fn thm => thm RS sym) (* "Gsi, Gsj, lhsi = lhsj |-- rhsj = rhsi" *)
   385     end
   403     end
   389 
   407 
   390 ML {*
   408 ML {*
   391 (* Generates the replacement lemma in fully quantified form. *)
   409 (* Generates the replacement lemma in fully quantified form. *)
   392 fun mk_replacement_lemma thy h ih_elim clause =
   410 fun mk_replacement_lemma thy h ih_elim clause =
   393   let
   411   let
   394     val ClauseInfo {cdata=ClauseContext {qs, lhs, cqs, ags, case_hyp, ...},
   412     val ClauseInfo {cdata=ClauseContext {qs, cqs, ags, case_hyp, ...},
   395       RCs, tree, ...} = clause
   413       RCs, tree, ...} = clause
   396     local open Conv in
   414     local open Conv in
   397       val ih_conv = arg1_conv o arg_conv o arg_conv
   415       val ih_conv = arg1_conv o arg_conv o arg_conv
   398     end
   416     end
   399 
   417 
   417     replace_lemma
   435     replace_lemma
   418   end
   436   end
   419 *}
   437 *}
   420 
   438 
   421 ML {*
   439 ML {*
   422 fun mk_uniqueness_clause thy globals compat_store clausei clausej RLj =
   440 fun mk_eqvt_lemma thy ih_eqvt clause =
       
   441   let
       
   442     val ClauseInfo {cdata=ClauseContext {cqs, case_hyp, ...}, RCs, ...} = clause
       
   443 
       
   444     local open Conv in
       
   445       val ih_conv = arg1_conv o arg_conv o arg_conv
       
   446     end
       
   447 
       
   448     val ih_eqvt_case =
       
   449       Conv.fconv_rule (ih_conv (K (case_hyp RS eq_reflection))) ih_eqvt
       
   450 
       
   451     fun prep_eqvt (RCInfo {llRI, RIvs, CCas, ...}) = 
       
   452         (llRI RS ih_eqvt_case)
       
   453         |> fold_rev (Thm.implies_intr o cprop_of) CCas
       
   454         |> fold_rev (Thm.forall_intr o cterm_of thy o Free) RIvs
       
   455   in
       
   456     map prep_eqvt RCs
       
   457     |> map (Thm.implies_intr (cprop_of case_hyp))
       
   458     |> map (fold_rev Thm.forall_intr cqs)
       
   459     |> map (Thm.close_derivation) 
       
   460   end
       
   461 *}
       
   462 
       
   463 ML {*
       
   464 fun mk_uniqueness_clause thy globals compat_store eqvts clausei clausej RLj =
   423   let
   465   let
   424     val Globals {h, y, x, fvar, ...} = globals
   466     val Globals {h, y, x, fvar, ...} = globals
   425     val ClauseInfo {no=i, cdata=cctxi as ClauseContext {ctxt=ctxti, lhs=lhsi, case_hyp, ...}, ...} = clausei
   467     val ClauseInfo {no=i, cdata=cctxi as ClauseContext {ctxt=ctxti, lhs=lhsi, case_hyp, cqs = cqsi, ...}, ...} = clausei
   426     val ClauseInfo {no=j, qglr=cdescj, RCs=RCsj, ...} = clausej
   468     val ClauseInfo {no=j, qglr=cdescj, RCs=RCsj, ...} = clausej
   427 
   469 
   428     val cctxj as ClauseContext {ags = agsj', lhs = lhsj', rhs = rhsj', qs = qsj', cqs = cqsj', ...} =
   470     val cctxj as ClauseContext {ags = agsj', lhs = lhsj', rhs = rhsj', qs = qsj', cqs = cqsj', ...} =
   429       mk_clause_context x ctxti cdescj
   471       mk_clause_context x ctxti cdescj 
   430 
   472 
   431     val rhsj'h = Pattern.rewrite_term thy [(fvar,h)] [] rhsj'
   473     val rhsj'h = Pattern.rewrite_term thy [(fvar,h)] [] rhsj'
   432     val compat = get_compat_thm thy compat_store i j cctxi cctxj
       
   433 
   474 
   434     val Ghsj' = map 
   475     val Ghsj' = map 
   435       (fn RCInfo {h_assum, ...} => Thm.assume (cterm_of thy (subst_bounds (rev qsj', h_assum)))) RCsj
   476       (fn RCInfo {h_assum, ...} => Thm.assume (cterm_of thy (subst_bounds (rev qsj', h_assum)))) RCsj
       
   477 
       
   478     val y_eq_rhsj'h = Thm.assume (cterm_of thy (HOLogic.mk_Trueprop (mk_eq (y, rhsj'h))))
       
   479     val lhsi_eq_lhsj' = Thm.assume (cterm_of thy (HOLogic.mk_Trueprop (mk_eq (lhsi, lhsj'))))
       
   480        (* lhs_i = lhs_j' |-- lhs_i = lhs_j' *) 
       
   481 
       
   482     val case_hypj' = trans OF [case_hyp, lhsi_eq_lhsj']
   436 
   483 
   437     val RLj_import = RLj
   484     val RLj_import = RLj
   438       |> fold Thm.forall_elim cqsj'
   485       |> fold Thm.forall_elim cqsj'
   439       |> fold Thm.elim_implies agsj'
   486       |> fold Thm.elim_implies agsj'
   440       |> fold Thm.elim_implies Ghsj'
   487       |> fold Thm.elim_implies Ghsj'
   441 
   488 
   442     val y_eq_rhsj'h = Thm.assume (cterm_of thy (HOLogic.mk_Trueprop (mk_eq (y, rhsj'h))))
   489     val eqvtsi = nth eqvts (i - 1)
   443     val lhsi_eq_lhsj' = Thm.assume (cterm_of thy (HOLogic.mk_Trueprop (mk_eq (lhsi, lhsj'))))
   490       |> map (fold Thm.forall_elim cqsi)
   444        (* lhs_i = lhs_j' |-- lhs_i = lhs_j' *)
   491       |> map (fold Thm.elim_implies [case_hyp])
       
   492 
       
   493     val eqvtsj = nth eqvts (j - 1)
       
   494       |> map (fold Thm.forall_elim cqsj')
       
   495       |> map (fold Thm.elim_implies [case_hypj'])
       
   496 
       
   497     val _ = tracing ("eqvtsi:\n" ^ cat_lines (map @{make_string} eqvtsi))
       
   498     val _ = tracing ("eqvtsj:\n" ^ cat_lines (map @{make_string} eqvtsj))
       
   499     val _ = tracing ("case_hypi:\n" ^ @{make_string} case_hyp)
       
   500     val _ = tracing ("case_hypj:\n" ^ @{make_string} case_hypj')
       
   501 
       
   502     val compat = get_compat_thm thy compat_store eqvtsi eqvtsj i j cctxi cctxj
       
   503     
       
   504     (* val _ = tracing ("compats:\n" ^ pp_thm compat)  *)
       
   505     
       
   506 
       
   507     fun pppp str = tap (fn thm => tracing (str ^ ": " ^ pp_thm thm))
       
   508     fun ppp str = I
   445   in
   509   in
   446     (trans OF [case_hyp, lhsi_eq_lhsj']) (* lhs_i = lhs_j' |-- x = lhs_j' *)
   510     (trans OF [case_hyp, lhsi_eq_lhsj']) (* lhs_i = lhs_j' |-- x = lhs_j' *)
       
   511     |> ppp "A"
   447     |> Thm.implies_elim RLj_import
   512     |> Thm.implies_elim RLj_import
   448       (* Rj1' ... Rjk', lhs_i = lhs_j' |-- rhs_j'_h = rhs_j'_f *)
   513       (* Rj1' ... Rjk', lhs_i = lhs_j' |-- rhs_j'_h = rhs_j'_f *)
       
   514     |> ppp "B"
   449     |> (fn it => trans OF [it, compat])
   515     |> (fn it => trans OF [it, compat])
   450       (* lhs_i = lhs_j', Gj', Rj1' ... Rjk' |-- rhs_j'_h = rhs_i_f *)
   516       (* lhs_i = lhs_j', Gj', Rj1' ... Rjk' |-- rhs_j'_h = rhs_i_f *)
       
   517     |> ppp "C"
   451     |> (fn it => trans OF [y_eq_rhsj'h, it])
   518     |> (fn it => trans OF [y_eq_rhsj'h, it])
   452       (* lhs_i = lhs_j', Gj', Rj1' ... Rjk', y = rhs_j_h' |-- y = rhs_i_f *)
   519       (* lhs_i = lhs_j', Gj', Rj1' ... Rjk', y = rhs_j_h' |-- y = rhs_i_f *)
       
   520     |> ppp "D"
   453     |> fold_rev (Thm.implies_intr o cprop_of) Ghsj'
   521     |> fold_rev (Thm.implies_intr o cprop_of) Ghsj'
       
   522     |> ppp "E"
   454     |> fold_rev (Thm.implies_intr o cprop_of) agsj'
   523     |> fold_rev (Thm.implies_intr o cprop_of) agsj'
   455       (* lhs_i = lhs_j' , y = rhs_j_h' |-- Gj', Rj1'...Rjk' ==> y = rhs_i_f *)
   524       (* lhs_i = lhs_j' , y = rhs_j_h' |-- Gj', Rj1'...Rjk' ==> y = rhs_i_f *)
       
   525     |> ppp "F"
   456     |> Thm.implies_intr (cprop_of y_eq_rhsj'h)
   526     |> Thm.implies_intr (cprop_of y_eq_rhsj'h)
       
   527     |> ppp "G"
   457     |> Thm.implies_intr (cprop_of lhsi_eq_lhsj')
   528     |> Thm.implies_intr (cprop_of lhsi_eq_lhsj')
       
   529     |> ppp "H"
   458     |> fold_rev Thm.forall_intr (cterm_of thy h :: cqsj')
   530     |> fold_rev Thm.forall_intr (cterm_of thy h :: cqsj')
   459   end
   531     |> ppp "I"
   460 *}
   532   end
   461 
   533 *}
   462 (* HERE *)
   534 
   463 
   535 
   464 ML {*
   536 ML {*
   465 fun mk_uniqueness_case thy globals G f ihyp ih_intro G_cases compat_store clauses rep_lemmas clausei =
   537 fun mk_uniqueness_case thy globals G f ihyp ih_intro G_cases compat_store clauses rep_lemmas eqvt_lemmas clausei =
   466   let
   538   let
   467     val Globals {x, y, ranT, fvar, ...} = globals
   539     val Globals {x, y, ranT, fvar, ...} = globals
   468     val ClauseInfo {cdata = ClauseContext {lhs, rhs, cqs, ags, case_hyp, ...}, lGI, RCs, ...} = clausei
   540     val ClauseInfo {cdata = ClauseContext {lhs, rhs, cqs, ags, case_hyp, ...}, lGI, RCs, ...} = clausei
   469     val rhsC = Pattern.rewrite_term thy [(fvar, f)] [] rhs
   541     val rhsC = Pattern.rewrite_term thy [(fvar, f)] [] rhs
   470 
   542 
   471     val ih_intro_case = full_simplify (HOL_basic_ss addsimps [case_hyp]) ih_intro
   543     val ih_intro_case = full_simplify (HOL_basic_ss addsimps [case_hyp]) ih_intro
   472 
   544 
   473     fun prep_RC (RCInfo {llRI, RIvs, CCas, ...}) = (llRI RS ih_intro_case)
   545     fun prep_RC (RCInfo {llRI, RIvs, CCas, ...}) = 
   474       |> fold_rev (Thm.implies_intr o cprop_of) CCas
   546         (llRI RS ih_intro_case)
   475       |> fold_rev (Thm.forall_intr o cterm_of thy o Free) RIvs
   547         |> fold_rev (Thm.implies_intr o cprop_of) CCas
       
   548         |> fold_rev (Thm.forall_intr o cterm_of thy o Free) RIvs
   476 
   549 
   477     val existence = fold (curry op COMP o prep_RC) RCs lGI
   550     val existence = fold (curry op COMP o prep_RC) RCs lGI
   478 
   551 
   479     val P = cterm_of thy (mk_eq (y, rhsC))
   552     val P = cterm_of thy (mk_eq (y, rhsC))
   480     val G_lhs_y = Thm.assume (cterm_of thy (HOLogic.mk_Trueprop (G $ lhs $ y)))
   553     val G_lhs_y = Thm.assume (cterm_of thy (HOLogic.mk_Trueprop (G $ lhs $ y)))
   481 
   554 
   482     val unique_clauses =
   555     val unique_clauses =
   483       map2 (mk_uniqueness_clause thy globals compat_store clausei) clauses rep_lemmas
   556       map2 (mk_uniqueness_clause thy globals compat_store eqvt_lemmas clausei) clauses rep_lemmas
   484      
       
   485     (*
       
   486     val _ = tracing ("unique_clauses\n" ^ cat_lines (map @{make_string} unique_clauses))
       
   487     *)
       
   488 
   557 
   489     fun elim_implies_eta A AB =
   558     fun elim_implies_eta A AB =
   490       Thm.compose_no_flatten true (A, 0) 1 AB |> Seq.list_of |> the_single
   559       Thm.compose_no_flatten true (A, 0) 1 AB |> Seq.list_of |> the_single
   491 
   560 
   492     val uniqueness = G_cases
   561     val uniqueness = G_cases
   519   in
   588   in
   520     (exactly_one, function_value)
   589     (exactly_one, function_value)
   521   end
   590   end
   522 *}
   591 *}
   523 
   592 
   524 ML Thm.forall_elim_vars
       
   525 ML Thm.implies_intr
       
   526 
   593 
   527 ML {* (ex1_implies_ex, ex1_implies_un) *}
   594 ML {* (ex1_implies_ex, ex1_implies_un) *}
   528 thm fundef_ex1_eqvt_at
   595 thm fundef_ex1_eqvt_at
   529 
   596 
   530 ML {*
   597 ML {*
   544     val ih_intro = ihyp_thm RS (f_def RS ex1_implies_ex)
   611     val ih_intro = ihyp_thm RS (f_def RS ex1_implies_ex)
   545     val ih_elim = ihyp_thm RS (f_def RS ex1_implies_un)
   612     val ih_elim = ihyp_thm RS (f_def RS ex1_implies_un)
   546       |> instantiate' [] [NONE, SOME (cterm_of thy h)]
   613       |> instantiate' [] [NONE, SOME (cterm_of thy h)]
   547     val ih_eqvt = ihyp_thm RS (G_eqvt RS (f_def RS @{thm fundef_ex1_eqvt_at}))
   614     val ih_eqvt = ihyp_thm RS (G_eqvt RS (f_def RS @{thm fundef_ex1_eqvt_at}))
   548 
   615 
   549 
   616     (*
   550     val _ = tracing ("ihyp_thm\n" ^ @{make_string} ihyp_thm)
   617     val _ = tracing ("ihyp_thm\n" ^ pp_thm ihyp_thm)
   551     val _ = tracing ("ih_intro\n" ^ @{make_string} ih_intro)
   618     val _ = tracing ("ih_intro\n" ^ pp_thm ih_intro)
   552     val _ = tracing ("ih_elim\n" ^ @{make_string} ih_elim)
   619     val _ = tracing ("ih_elim\n" ^ pp_thm ih_elim)
   553     val _ = tracing ("ih_eqvt\n" ^ @{make_string} ih_eqvt)
   620     val _ = tracing ("ih_eqvt\n" ^ pp_thm ih_eqvt)
       
   621     *)
   554 
   622 
   555     val _ = trace_msg (K "Proving Replacement lemmas...")
   623     val _ = trace_msg (K "Proving Replacement lemmas...")
   556     val repLemmas = map (mk_replacement_lemma thy h ih_elim) clauses
   624     val repLemmas = map (mk_replacement_lemma thy h ih_elim) clauses
   557 
   625 
   558     val _ = tracing (cat_lines (map @{make_string} repLemmas))
   626     val _ = trace_msg (K "Proving Equivariance lemmas...")
       
   627     val eqvtLemmas = map (mk_eqvt_lemma thy ih_eqvt) clauses
   559 
   628 
   560     val _ = trace_msg (K "Proving cases for unique existence...")
   629     val _ = trace_msg (K "Proving cases for unique existence...")
   561     val (ex1s, values) =
   630     val (ex1s, values) =
   562       split_list (map (mk_uniqueness_case thy globals G f 
   631       split_list (map (mk_uniqueness_case thy globals G f 
   563         ihyp ih_intro G_elim compat_store clauses repLemmas) clauses)
   632         ihyp ih_intro G_elim compat_store clauses repLemmas eqvtLemmas) clauses)
   564      
   633      
   565     val _ = tracing ("ex1s\n" ^ cat_lines (map @{make_string} ex1s))
       
   566     val _ = tracing ("values\n" ^ cat_lines (map @{make_string} values)) 
       
   567 
       
   568     val _ = trace_msg (K "Proving: Graph is a function")
   634     val _ = trace_msg (K "Proving: Graph is a function")
   569     val graph_is_function = complete
   635     val graph_is_function = complete
   570       |> tap (fn th => tracing ("A\n" ^ @{make_string} th))
       
   571       |> Thm.forall_elim_vars 0
   636       |> Thm.forall_elim_vars 0
   572       |> tap (fn th => tracing ("B\n" ^ @{make_string} th))
       
   573       |> fold (curry op COMP) ex1s
   637       |> fold (curry op COMP) ex1s
   574       |> tap (fn th => tracing ("C\n" ^ @{make_string} th))
       
   575       |> Thm.implies_intr (ihyp)
   638       |> Thm.implies_intr (ihyp)
   576       |> tap (fn th => tracing ("D\n" ^ @{make_string} th))
       
   577       |> Thm.implies_intr (cterm_of thy (HOLogic.mk_Trueprop (mk_acc domT R $ x)))
   639       |> Thm.implies_intr (cterm_of thy (HOLogic.mk_Trueprop (mk_acc domT R $ x)))
   578       |> tap (fn th => tracing ("E\n" ^ @{make_string} th))
       
   579       |> Thm.forall_intr (cterm_of thy x)
   640       |> Thm.forall_intr (cterm_of thy x)
   580       |> tap (fn th => tracing ("F\n" ^ @{make_string} th))
       
   581       |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *)
   641       |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *)
   582       |> tap (fn th => tracing ("G\n" ^ @{make_string} th))
       
   583       |> (fn it => fold (Thm.forall_intr o cterm_of thy o Var) (Term.add_vars (prop_of it) []) it)
   642       |> (fn it => fold (Thm.forall_intr o cterm_of thy o Var) (Term.add_vars (prop_of it) []) it)
   584       |> tap (fn th => tracing ("H\n" ^ @{make_string} th))
       
   585 
       
   586 
   643 
   587     val goalstate =  Conjunction.intr graph_is_function complete
   644     val goalstate =  Conjunction.intr graph_is_function complete
   588       |> Thm.close_derivation
   645       |> Thm.close_derivation
   589       |> Goal.protect
   646       |> Goal.protect
   590       |> fold_rev (Thm.implies_intr o cprop_of) compat
   647       |> fold_rev (Thm.implies_intr o cprop_of) compat
  1076 
  1133 
  1077     val ((G, GIntro_thms, G_elim, G_induct, G_eqvt), lthy) =
  1134     val ((G, GIntro_thms, G_elim, G_induct, G_eqvt), lthy) =
  1078       PROFILE "def_graph" (define_graph (graph_name defname) fvar domT ranT clauses RCss) lthy
  1135       PROFILE "def_graph" (define_graph (graph_name defname) fvar domT ranT clauses RCss) lthy
  1079 
  1136 
  1080     (* 
  1137     (* 
  1081     val _ = tracing ("Graph - name: " ^ @{make_string} G)
  1138     val _ = tracing ("Graph - name: " ^ pp_thm G)
  1082     val _ = tracing ("Graph intros:\n" ^ cat_lines (map @{make_string} GIntro_thms))
  1139     val _ = tracing ("Graph intros:\n" ^ cat_lines (map pp_thm GIntro_thms))
  1083     val _ = tracing ("Graph Equivariance " ^ @{make_string} G_eqvt)
  1140     val _ = tracing ("Graph Equivariance " ^ pp_thm G_eqvt)
  1084     *)
  1141     *)
  1085 
  1142 
  1086     val ((f, (_, f_defthm)), lthy) =
  1143     val ((f, (_, f_defthm)), lthy) =
  1087       PROFILE "def_fun" (define_function (defname ^ "_sumC_def") (fname, mixfix) domT ranT G default) lthy
  1144       PROFILE "def_fun" (define_function (defname ^ "_sumC_def") (fname, mixfix) domT ranT G default) lthy
  1088 
  1145 
  1089     (*
  1146     (*
  1090     val _ = tracing ("f - name: " ^ @{make_string} f)
  1147     val _ = tracing ("f - name: " ^ pp_thm f)
  1091     val _ = tracing ("f_defthm:\n" ^ @{make_string} f_defthm)
  1148     val _ = tracing ("f_defthm:\n" ^ pp_thm f_defthm)
  1092     *)
  1149     *)
  1093 
  1150 
  1094     val RCss = map (map (inst_RC (ProofContext.theory_of lthy) fvar f)) RCss
  1151     val RCss = map (map (inst_RC (ProofContext.theory_of lthy) fvar f)) RCss
  1095     val trees = map (Function_Ctx_Tree.inst_tree (ProofContext.theory_of lthy) fvar f) trees
  1152     val trees = map (Function_Ctx_Tree.inst_tree (ProofContext.theory_of lthy) fvar f) trees
  1096 
  1153 
  1097     (*
  1154     (*
  1098     val _ = tracing ("recursive calls:\n" ^ cat_lines (map @{make_string} RCss))
  1155     val _ = tracing ("recursive calls:\n" ^ cat_lines (map pp_thm RCss))
  1099     *)
  1156     *)
  1100 
  1157 
  1101     val ((R, RIntro_thmss, R_elim, R_eqvt), lthy) =
  1158     val ((R, RIntro_thmss, R_elim, R_eqvt), lthy) =
  1102       PROFILE "def_rel" (define_recursion_relation (rel_name defname) domT abstract_qglrs clauses RCss) lthy
  1159       PROFILE "def_rel" (define_recursion_relation (rel_name defname) domT abstract_qglrs clauses RCss) lthy
  1103 
  1160 
  1104     (*
  1161     (*
  1105     val _ = tracing ("Relation - name: " ^ @{make_string} R) 
  1162     val _ = tracing ("Relation - name: " ^ pp_thm R) 
  1106     val _ = tracing ("Relation intros:\n" ^ cat_lines (map @{make_string} RIntro_thmss))
  1163     val _ = tracing ("Relation intros:\n" ^ cat_lines (map pp_thm RIntro_thmss))
  1107     val _ = tracing ("Relation Equivariance " ^ @{make_string} R_eqvt)
  1164     val _ = tracing ("Relation Equivariance " ^ pp_thm R_eqvt)
  1108     *)    
  1165     *)    
  1109 
  1166 
  1110     val (_, lthy) =
  1167     val (_, lthy) =
  1111       Local_Theory.abbrev Syntax.mode_default ((Binding.name (dom_name defname), NoSyn), mk_acc domT R) lthy
  1168       Local_Theory.abbrev Syntax.mode_default ((Binding.name (dom_name defname), NoSyn), mk_acc domT R) lthy
  1112 
  1169 
  1127       |> map (cert #> Thm.assume)
  1184       |> map (cert #> Thm.assume)
  1128 
  1185 
  1129     val compat_store = store_compat_thms n compat
  1186     val compat_store = store_compat_thms n compat
  1130 
  1187 
  1131     (*
  1188     (*
  1132     val _ = tracing ("globals:\n" ^ @{make_string} globals)
  1189     val _ = tracing ("globals:\n" ^ pp_thm globals)
  1133     val _ = tracing ("complete:\n" ^ @{make_string} complete)
  1190     val _ = tracing ("complete:\n" ^ pp_thm complete)
  1134     val _ = tracing ("compat:\n" ^ @{make_string} compat)
  1191     val _ = tracing ("compat:\n" ^ pp_thm compat)
  1135     val _ = tracing ("compat_store:\n" ^ @{make_string} compat_store)
  1192     val _ = tracing ("compat_store:\n" ^ pp_thm compat_store)
  1136     *)
  1193     *)
  1137 
  1194 
  1138     val (goalstate, values) = PROFILE "prove_stuff"
  1195     val (goalstate, values) = PROFILE "prove_stuff"
  1139       (prove_stuff lthy globals G f R xclauses complete compat
  1196       (prove_stuff lthy globals G f R xclauses complete compat
  1140          compat_store G_elim G_eqvt) f_defthm
  1197          compat_store G_elim G_eqvt) f_defthm
  1141      
  1198      
  1142     val _ = tracing ("goalstate prove_stuff thm:\n" ^ @{make_string} goalstate)
       
  1143     val _ = tracing ("values prove_stuff thms:\n" ^ cat_lines (map @{make_string} values))
       
  1144 
       
  1145     val mk_trsimps =
  1199     val mk_trsimps =
  1146       mk_trsimps lthy globals f G R f_defthm R_elim G_induct xclauses
  1200       mk_trsimps lthy globals f G R f_defthm R_elim G_induct xclauses
  1147 
  1201 
  1148     fun mk_partial_rules provedgoal =
  1202     fun mk_partial_rules provedgoal =
  1149       let
  1203       let
  1583 ML {*
  1637 ML {*
  1584 fun gen_function is_external prep default_constraint fixspec eqns config lthy =
  1638 fun gen_function is_external prep default_constraint fixspec eqns config lthy =
  1585   let
  1639   let
  1586     val ((goal_state, afterqed), lthy') =
  1640     val ((goal_state, afterqed), lthy') =
  1587       prepare_function is_external prep default_constraint fixspec eqns config lthy
  1641       prepare_function is_external prep default_constraint fixspec eqns config lthy
  1588 
       
  1589     val _ = tracing ("goal state:\n" ^ @{make_string} goal_state)
       
  1590     val _ = tracing ("concl of goal state:\n" ^ Syntax.string_of_term lthy' (concl_of goal_state))
       
  1591   in
  1642   in
  1592     lthy'
  1643     lthy'
  1593     |> Proof.theorem NONE (snd oo afterqed) [[(Logic.unprotect (concl_of goal_state), [])]]
  1644     |> Proof.theorem NONE (snd oo afterqed) [[(Logic.unprotect (concl_of goal_state), [])]]
  1594  (*|> tap (fn x => tracing ("after thm:\n" ^ Pretty.string_of (Pretty.chunks (Proof.pretty_goals true x))))*)
       
  1595     |> Proof.refine (Method.primitive_text (K goal_state)) 
  1645     |> Proof.refine (Method.primitive_text (K goal_state)) 
  1596     |> Seq.hd
  1646     |> Seq.hd
  1597  (*|> tap (fn x => tracing ("after ref:\n" ^ Pretty.string_of (Pretty.chunks (Proof.pretty_goals true x))))*)
       
  1598   end
  1647   end
  1599 *}
  1648 *}
  1600 
  1649 
  1601 
  1650 
  1602 ML {*
  1651 ML {*
  1681 apply(rule_tac y="x" in lam.exhaust)
  1730 apply(rule_tac y="x" in lam.exhaust)
  1682 apply(simp_all)[3]
  1731 apply(simp_all)[3]
  1683 apply(simp_all only: lam.distinct)
  1732 apply(simp_all only: lam.distinct)
  1684 apply(simp add: lam.eq_iff)
  1733 apply(simp add: lam.eq_iff)
  1685 apply(simp add: lam.eq_iff)
  1734 apply(simp add: lam.eq_iff)
       
  1735 apply(subst (asm) Abs_eq_iff)
       
  1736 apply(erule exE)
       
  1737 apply(simp add: alphas)
       
  1738 apply(clarify)
       
  1739 oops
       
  1740 
       
  1741 lemma removeAll_eqvt[eqvt]:
       
  1742   shows "p \<bullet> (removeAll x xs) = removeAll (p \<bullet> x) (p \<bullet> xs)"
       
  1743 by (induct xs) (auto)
       
  1744 
       
  1745 nominal_primrec 
       
  1746   frees_lst :: "lam \<Rightarrow> atom list"
       
  1747 where
       
  1748   "frees_lst (Var x) = [atom x]"
       
  1749 | "frees_lst (App t1 t2) = (frees_lst t1) @ (frees_lst t2)"
       
  1750 | "frees_lst (Lam x t) = removeAll (atom x) (frees_lst t)"
       
  1751 apply(rule_tac y="x" in lam.exhaust)
       
  1752 apply(simp_all)[3]
       
  1753 apply(simp_all only: lam.distinct)
       
  1754 apply(simp add: lam.eq_iff)
       
  1755 apply(simp add: lam.eq_iff)
       
  1756 apply(simp add: lam.eq_iff)
       
  1757 apply(simp add: Abs_eq_iff)
       
  1758 apply(erule exE)
       
  1759 apply(simp add: alphas)
       
  1760 apply(simp add: atom_eqvt)
       
  1761 apply(clarify)
       
  1762 oops
       
  1763 
       
  1764 nominal_primrec
       
  1765   subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_ [_ ::= _]" [100,100,100] 100)
       
  1766 where
       
  1767   "(Var x)[y ::= s] = (if x=y then s else (Var x))"
       
  1768 | "(App t\<^isub>1 t\<^isub>2)[y ::= s] = App (t\<^isub>1[y ::= s]) (t\<^isub>2[y ::= s])"
       
  1769 | "atom x \<sharp> (y, s) \<Longrightarrow> (Lam x t)[y ::= s] = Lam x (t[y ::= s])"
       
  1770 apply(case_tac x)
       
  1771 apply(simp)
       
  1772 apply(rule_tac y="a" and c="(b, c)" in lam.strong_exhaust)
       
  1773 apply(simp add: lam.eq_iff lam.distinct)
       
  1774 apply(auto)[1]
       
  1775 apply(simp add: lam.eq_iff lam.distinct)
       
  1776 apply(auto)[1]
       
  1777 apply(simp add: fresh_star_def lam.eq_iff lam.distinct)
       
  1778 apply(simp_all add: lam.distinct)[5]
       
  1779 apply(simp add: lam.eq_iff)
       
  1780 apply(simp add: lam.eq_iff)
       
  1781 apply(simp add: lam.eq_iff)
       
  1782 apply(erule conjE)+
       
  1783 apply(subst (asm) Abs_eq_iff3) 
       
  1784 apply(erule exE)
       
  1785 
       
  1786 
       
  1787 
       
  1788 nominal_primrec
       
  1789   depth :: "lam \<Rightarrow> nat"
       
  1790 where
       
  1791   "depth (Var x) = 1"
       
  1792 | "depth (App t1 t2) = (max (depth t1) (depth t2)) + 1"
       
  1793 | "depth (Lam x t) = (depth t) + 1"
       
  1794 apply(rule_tac y="x" in lam.exhaust)
       
  1795 apply(simp_all)[3]
       
  1796 apply(simp_all only: lam.distinct)
       
  1797 apply(simp add: lam.eq_iff)
       
  1798 apply(simp add: lam.eq_iff)
       
  1799 (*
       
  1800 apply(subst (asm) Abs_eq_iff)
       
  1801 apply(erule exE)
       
  1802 apply(simp add: alphas)
       
  1803 apply(clarify)
       
  1804 *)
  1686 apply(subgoal_tac "finite (supp (x, xa, t, ta, depth_sumC t, depth_sumC ta))")
  1805 apply(subgoal_tac "finite (supp (x, xa, t, ta, depth_sumC t, depth_sumC ta))")
  1687 apply(erule_tac ?'a="name" in obtain_at_base)
  1806 apply(erule_tac ?'a="name" in obtain_at_base)
  1688 unfolding fresh_def[symmetric]
  1807 unfolding fresh_def[symmetric]
  1689 apply(drule_tac a="atom x" and b="atom xa" and c="atom a" in test3)
  1808 apply(drule_tac a="atom x" and b="atom xa" and c="atom a" in test3)
  1690 apply(simp add: Abs_fresh_iff)
  1809 apply(simp add: Abs_fresh_iff)
  1717   assumes a: "a \<notin> S" "b \<notin> S"
  1836   assumes a: "a \<notin> S" "b \<notin> S"
  1718   shows "(a \<leftrightarrow> b) \<bullet> S = S"
  1837   shows "(a \<leftrightarrow> b) \<bullet> S = S"
  1719   unfolding permute_set_eq
  1838   unfolding permute_set_eq
  1720   using a by (auto simp add: permute_flip_at)
  1839   using a by (auto simp add: permute_flip_at)
  1721 
  1840 
       
  1841 lemma removeAll_eqvt[eqvt]:
       
  1842   shows "p \<bullet> (removeAll x xs) = removeAll (p \<bullet> x) (p \<bullet> xs)"
       
  1843 by (induct xs) (auto)
       
  1844 
       
  1845 nominal_primrec 
       
  1846   frees_lst :: "lam \<Rightarrow> atom list"
       
  1847 where
       
  1848   "frees_lst (Var x) = [atom x]"
       
  1849 | "frees_lst (App t1 t2) = (frees_lst t1) @ (frees_lst t2)"
       
  1850 | "frees_lst (Lam x t) = removeAll (atom x) (frees_lst t)"
       
  1851 apply(rule_tac y="x" in lam.exhaust)
       
  1852 apply(simp_all)[3]
       
  1853 apply(simp_all only: lam.distinct)
       
  1854 apply(simp add: lam.eq_iff)
       
  1855 apply(simp add: lam.eq_iff)
       
  1856 apply(simp add: lam.eq_iff)
       
  1857 apply(simp add: Abs_eq_iff)
       
  1858 apply(erule exE)
       
  1859 apply(simp add: alphas)
       
  1860 apply(simp add: atom_eqvt)
       
  1861 apply(clarify)
       
  1862 apply(rule trans)
       
  1863 apply(rule sym)
       
  1864 apply(rule_tac p="p" in supp_perm_eq)
       
  1865 oops
  1722 
  1866 
  1723 nominal_primrec 
  1867 nominal_primrec 
  1724   frees :: "lam \<Rightarrow> name set"
  1868   frees :: "lam \<Rightarrow> name set"
  1725 where
  1869 where
  1726   "frees (Var x) = {x}"
  1870   "frees (Var x) = {x}"
  1742 apply(simp add: Abs_fresh_iff)
  1886 apply(simp add: Abs_fresh_iff)
  1743 apply(simp)
  1887 apply(simp)
  1744 apply(drule test)
  1888 apply(drule test)
  1745 apply(rule_tac t="frees_sumC t - {x}" and s="(x \<leftrightarrow> a) \<bullet> (frees_sumC t - {x})" in subst)
  1889 apply(rule_tac t="frees_sumC t - {x}" and s="(x \<leftrightarrow> a) \<bullet> (frees_sumC t - {x})" in subst)
  1746 oops
  1890 oops
       
  1891 
       
  1892 thm Abs_eq_iff[simplified alphas]
       
  1893 
       
  1894 lemma Abs_set_eq_iff2:
       
  1895   fixes x y::"'a::fs"
       
  1896   shows "[bs]set. x = [cs]set. y \<longleftrightarrow>
       
  1897     (\<exists>p. supp ([bs]set. x) = supp ([cs]set. y) \<and>
       
  1898          supp ([bs]set. x) \<sharp>* p \<and>
       
  1899          p \<bullet> x = y \<and> p \<bullet> bs = cs)"
       
  1900 unfolding Abs_eq_iff
       
  1901 unfolding alphas
       
  1902 unfolding supp_Abs
       
  1903 by simp
       
  1904 
       
  1905 lemma Abs_set_eq_iff3:
       
  1906   fixes x y::"'a::fs"
       
  1907   assumes a: "finite bs" "finite cs"
       
  1908   shows "[bs]set. x = [cs]set. y \<longleftrightarrow>
       
  1909     (\<exists>p. supp ([bs]set. x) = supp ([cs]set. y) \<and>
       
  1910          supp ([bs]set. x) \<sharp>* p \<and>
       
  1911          p \<bullet> x = y \<and> p \<bullet> bs = cs \<and>
       
  1912          supp p \<subseteq> bs \<union> cs)"
       
  1913 unfolding Abs_eq_iff
       
  1914 unfolding alphas
       
  1915 unfolding supp_Abs
       
  1916 apply(auto)
       
  1917 using set_renaming_perm
       
  1918 sorry
       
  1919 
       
  1920 lemma Abs_eq_iff2:
       
  1921   fixes x y::"'a::fs"
       
  1922   shows "[bs]lst. x = [cs]lst. y \<longleftrightarrow>
       
  1923     (\<exists>p. supp ([bs]lst. x) = supp ([cs]lst. y) \<and>
       
  1924          supp ([bs]lst. x) \<sharp>* p \<and>
       
  1925          p \<bullet> x = y \<and> p \<bullet> bs = cs)"
       
  1926 unfolding Abs_eq_iff
       
  1927 unfolding alphas
       
  1928 unfolding supp_Abs
       
  1929 by simp
       
  1930 
       
  1931 lemma Abs_eq_iff3:
       
  1932   fixes x y::"'a::fs"
       
  1933   shows "[bs]lst. x = [cs]lst. y \<longleftrightarrow>
       
  1934     (\<exists>p. supp ([bs]lst. x) = supp ([cs]lst. y) \<and>
       
  1935          supp ([bs]lst. x) \<sharp>* p \<and>
       
  1936          p \<bullet> x = y \<and> p \<bullet> bs = cs \<and>
       
  1937          supp p \<subseteq> set bs \<union> set cs)"
       
  1938 unfolding Abs_eq_iff
       
  1939 unfolding alphas
       
  1940 unfolding supp_Abs
       
  1941 apply(auto)
       
  1942 using list_renaming_perm
       
  1943 apply -
       
  1944 apply(drule_tac x="bs" in meta_spec)
       
  1945 apply(drule_tac x="p" in meta_spec)
       
  1946 apply(erule exE)
       
  1947 apply(rule_tac x="q" in exI)
       
  1948 apply(simp add: set_eqvt)
       
  1949 sorry
       
  1950 
       
  1951 nominal_primrec
       
  1952   subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_ [_ ::= _]" [100,100,100] 100)
       
  1953 where
       
  1954   "(Var x)[y ::= s] = (if x=y then s else (Var x))"
       
  1955 | "(App t\<^isub>1 t\<^isub>2)[y ::= s] = App (t\<^isub>1[y ::= s]) (t\<^isub>2[y ::= s])"
       
  1956 | "atom x \<sharp> (y, s) \<Longrightarrow> (Lam x t)[y ::= s] = Lam x (t[y ::= s])"
       
  1957 apply(case_tac x)
       
  1958 apply(simp)
       
  1959 apply(rule_tac y="a" and c="(b, c)" in lam.strong_exhaust)
       
  1960 apply(simp add: lam.eq_iff lam.distinct)
       
  1961 apply(auto)[1]
       
  1962 apply(simp add: lam.eq_iff lam.distinct)
       
  1963 apply(auto)[1]
       
  1964 apply(simp add: fresh_star_def lam.eq_iff lam.distinct)
       
  1965 apply(simp_all add: lam.distinct)[5]
       
  1966 apply(simp add: lam.eq_iff)
       
  1967 apply(simp add: lam.eq_iff)
       
  1968 apply(simp add: lam.eq_iff)
       
  1969 apply(erule conjE)+
       
  1970 apply(subst (asm) Abs_eq_iff3) 
       
  1971 apply(erule exE)
       
  1972 apply(erule conjE)+
       
  1973 apply(clarify)
       
  1974 apply(perm_simp)
       
  1975 apply(simp)
       
  1976 apply(rule trans)
       
  1977 apply(rule sym)
       
  1978 apply(rule_tac p="p" in supp_perm_eq)
       
  1979 apply(rule fresh_star_supp_conv)
       
  1980 apply(drule fresh_star_supp_conv)
       
  1981 apply(simp add: Abs_fresh_star_iff)
       
  1982 thm fresh_eqvt_at
       
  1983 apply(rule_tac f="subst_sumC" in fresh_eqvt_at)
       
  1984 apply(assumption)
       
  1985 apply(simp add: finite_supp)
       
  1986 prefer 2
       
  1987 apply(simp)
       
  1988 apply(simp add: eqvt_at_def)
       
  1989 apply(perm_simp)
       
  1990 apply(subgoal_tac "p \<bullet> ya = ya")
       
  1991 apply(subgoal_tac "p \<bullet> sa = sa")
       
  1992 apply(simp)
       
  1993 apply(rule supp_perm_eq)
       
  1994 apply(rule fresh_star_supp_conv)
       
  1995 apply(auto simp add: fresh_star_def fresh_Pair)[1]
       
  1996 apply(rule supp_perm_eq)
       
  1997 apply(rule fresh_star_supp_conv)
       
  1998 apply(auto simp add: fresh_star_def fresh_Pair)[1]
       
  1999 
       
  2000 
  1747 
  2001 
  1748 nominal_primrec
  2002 nominal_primrec
  1749   subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_ [_ ::= _]" [100,100,100] 100)
  2003   subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_ [_ ::= _]" [100,100,100] 100)
  1750 where
  2004 where
  1751   "(Var x)[y ::= s] = (if x=y then s else (Var x))"
  2005   "(Var x)[y ::= s] = (if x=y then s else (Var x))"