TFL/tfl.ML
changeset 15570 8d8c70b41bab
parent 15531 08c8dad8e399
child 15574 b1d1b5bfc464
equal deleted inserted replaced
15569:1b3115d1a8df 15570:8d8c70b41bab
   199  *---------------------------------------------------------------------------*)
   199  *---------------------------------------------------------------------------*)
   200 
   200 
   201 fun mk_pat (c,l) =
   201 fun mk_pat (c,l) =
   202   let val L = length (binder_types (type_of c))
   202   let val L = length (binder_types (type_of c))
   203       fun build (prfx,tag,plist) =
   203       fun build (prfx,tag,plist) =
   204           let val args   = take (L,plist)
   204           let val args   = Library.take (L,plist)
   205               and plist' = drop(L,plist)
   205               and plist' = Library.drop(L,plist)
   206           in (prfx,tag,list_comb(c,args)::plist') end
   206           in (prfx,tag,list_comb(c,args)::plist') end
   207   in map build l end;
   207   in map build l end;
   208 
   208 
   209 fun v_to_prfx (prfx, v::pats) = (v::prfx,pats)
   209 fun v_to_prfx (prfx, v::pats) = (v::prfx,pats)
   210   | v_to_prfx _ = raise TFL_ERR "mk_case" "v_to_prfx";
   210   | v_to_prfx _ = raise TFL_ERR "mk_case" "v_to_prfx";
   334      val atom = single (gen_distinct (op aconv) funcs)
   334      val atom = single (gen_distinct (op aconv) funcs)
   335      val (fname,ftype) = dest_atom atom
   335      val (fname,ftype) = dest_atom atom
   336      val dummy = map (no_repeat_vars thy) pats
   336      val dummy = map (no_repeat_vars thy) pats
   337      val rows = ListPair.zip (map (fn x => ([]:term list,[x])) pats,
   337      val rows = ListPair.zip (map (fn x => ([]:term list,[x])) pats,
   338                               map (fn (t,i) => (t,(i,true))) (enumerate R))
   338                               map (fn (t,i) => (t,(i,true))) (enumerate R))
   339      val names = foldr add_term_names (R,[])
   339      val names = Library.foldr add_term_names (R,[])
   340      val atype = type_of(hd pats)
   340      val atype = type_of(hd pats)
   341      and aname = variant names "a"
   341      and aname = variant names "a"
   342      val a = Free(aname,atype)
   342      val a = Free(aname,atype)
   343      val ty_info = Thry.match_info thy
   343      val ty_info = Thry.match_info thy
   344      val ty_match = Thry.match_type thy
   344      val ty_match = Thry.match_type thy
   431 in
   431 in
   432   pass (TCs, map (fn p => (p,[])) full_pats)
   432   pass (TCs, map (fn p => (p,[])) full_pats)
   433 end;
   433 end;
   434 
   434 
   435 
   435 
   436 fun givens pats = map pat_of (filter given pats);
   436 fun givens pats = map pat_of (List.filter given pats);
   437 
   437 
   438 fun post_definition meta_tflCongs (theory, (def, pats)) =
   438 fun post_definition meta_tflCongs (theory, (def, pats)) =
   439  let val tych = Thry.typecheck theory
   439  let val tych = Thry.typecheck theory
   440      val f = #lhs(S.dest_eq(concl def))
   440      val f = #lhs(S.dest_eq(concl def))
   441      val corollary = R.MATCH_MP Thms.WFREC_COROLLARY def
   441      val corollary = R.MATCH_MP Thms.WFREC_COROLLARY def
   442      val pats' = filter given pats
   442      val pats' = List.filter given pats
   443      val given_pats = map pat_of pats'
   443      val given_pats = map pat_of pats'
   444      val rows = map row_of_pat pats'
   444      val rows = map row_of_pat pats'
   445      val WFR = #ant(S.dest_imp(concl corollary))
   445      val WFR = #ant(S.dest_imp(concl corollary))
   446      val R = #Rand(S.dest_comb WFR)
   446      val R = #Rand(S.dest_comb WFR)
   447      val corollary' = R.UNDISCH corollary  (* put WF R on assums *)
   447      val corollary' = R.UNDISCH corollary  (* put WF R on assums *)
   497                  else ()
   497                  else ()
   498      val (case_rewrites,context_congs) = extraction_thms thy
   498      val (case_rewrites,context_congs) = extraction_thms thy
   499      val tych = Thry.typecheck thy
   499      val tych = Thry.typecheck thy
   500      val WFREC_THM0 = R.ISPEC (tych functional) Thms.WFREC_COROLLARY
   500      val WFREC_THM0 = R.ISPEC (tych functional) Thms.WFREC_COROLLARY
   501      val Const("All",_) $ Abs(Rname,Rtype,_) = concl WFREC_THM0
   501      val Const("All",_) $ Abs(Rname,Rtype,_) = concl WFREC_THM0
   502      val R = Free (variant (foldr add_term_names (eqns,[])) Rname,
   502      val R = Free (variant (Library.foldr add_term_names (eqns,[])) Rname,
   503                    Rtype)
   503                    Rtype)
   504      val WFREC_THM = R.ISPECL [tych R, tych g] WFREC_THM0
   504      val WFREC_THM = R.ISPECL [tych R, tych g] WFREC_THM0
   505      val ([proto_def, WFR],_) = S.strip_imp(concl WFREC_THM)
   505      val ([proto_def, WFR],_) = S.strip_imp(concl WFREC_THM)
   506      val dummy =
   506      val dummy =
   507            if !trace then
   507            if !trace then
   538      val dummy = if !trace
   538      val dummy = if !trace
   539                  then (writeln "Extractants = ";
   539                  then (writeln "Extractants = ";
   540                        prths extractants;
   540                        prths extractants;
   541                        ())
   541                        ())
   542                  else ()
   542                  else ()
   543      val TCs = foldr (gen_union (op aconv)) (TCl, [])
   543      val TCs = Library.foldr (gen_union (op aconv)) (TCl, [])
   544      val full_rqt = WFR::TCs
   544      val full_rqt = WFR::TCs
   545      val R' = S.mk_select{Bvar=R1, Body=S.list_mk_conj full_rqt}
   545      val R' = S.mk_select{Bvar=R1, Body=S.list_mk_conj full_rqt}
   546      val R'abs = S.rand R'
   546      val R'abs = S.rand R'
   547      val proto_def' = subst_free[(R1,R')] proto_def
   547      val proto_def' = subst_free[(R1,R')] proto_def
   548      val dummy = if !trace then writeln ("proto_def' = " ^
   548      val dummy = if !trace then writeln ("proto_def' = " ^
   620 
   620 
   621 fun alpha_ex_unroll (xlist, tm) =
   621 fun alpha_ex_unroll (xlist, tm) =
   622   let val (qvars,body) = S.strip_exists tm
   622   let val (qvars,body) = S.strip_exists tm
   623       val vlist = #2(S.strip_comb (S.rhs body))
   623       val vlist = #2(S.strip_comb (S.rhs body))
   624       val plist = ListPair.zip (vlist, xlist)
   624       val plist = ListPair.zip (vlist, xlist)
   625       val args = map (fn qv => the (gen_assoc (op aconv) (plist, qv))) qvars
   625       val args = map (fn qv => valOf (gen_assoc (op aconv) (plist, qv))) qvars
   626                    handle Option => sys_error
   626                    handle Option => sys_error
   627                        "TFL fault [alpha_ex_unroll]: no correspondence"
   627                        "TFL fault [alpha_ex_unroll]: no correspondence"
   628       fun build ex      []   = []
   628       fun build ex      []   = []
   629         | build (_$rex) (v::rst) =
   629         | build (_$rex) (v::rst) =
   630            let val ex1 = betapply(rex, v)
   630            let val ex1 = betapply(rex, v)
   680             fun expnd tm (pats,(th,b)) = (pats,(R.SUBS[R.ASSUME(tych tm)]th,b))
   680             fun expnd tm (pats,(th,b)) = (pats,(R.SUBS[R.ASSUME(tych tm)]th,b))
   681             val news = map (fn (nf,rows,c) => {path = nf@rstp,
   681             val news = map (fn (nf,rows,c) => {path = nf@rstp,
   682                                                rows = map (expnd c) rows})
   682                                                rows = map (expnd c) rows})
   683                            (U.zip3 new_formals groups constraints)
   683                            (U.zip3 new_formals groups constraints)
   684             val recursive_thms = map mk news
   684             val recursive_thms = map mk news
   685             val build_exists = foldr
   685             val build_exists = Library.foldr
   686                                 (fn((x,t), th) =>
   686                                 (fn((x,t), th) =>
   687                                  R.CHOOSE (tych x, R.ASSUME (tych t)) th)
   687                                  R.CHOOSE (tych x, R.ASSUME (tych t)) th)
   688             val thms' = ListPair.map build_exists (vexl, recursive_thms)
   688             val thms' = ListPair.map build_exists (vexl, recursive_thms)
   689             val same_concls = R.EVEN_ORS thms'
   689             val same_concls = R.EVEN_ORS thms'
   690         in R.DISJ_CASESL thm' same_concls
   690         in R.DISJ_CASESL thm' same_concls
   696 
   696 
   697 fun complete_cases thy =
   697 fun complete_cases thy =
   698  let val tych = Thry.typecheck thy
   698  let val tych = Thry.typecheck thy
   699      val ty_info = Thry.induct_info thy
   699      val ty_info = Thry.induct_info thy
   700  in fn pats =>
   700  in fn pats =>
   701  let val names = foldr add_term_names (pats,[])
   701  let val names = Library.foldr add_term_names (pats,[])
   702      val T = type_of (hd pats)
   702      val T = type_of (hd pats)
   703      val aname = Term.variant names "a"
   703      val aname = Term.variant names "a"
   704      val vname = Term.variant (aname::names) "v"
   704      val vname = Term.variant (aname::names) "v"
   705      val a = Free (aname, T)
   705      val a = Free (aname, T)
   706      val v = Free (vname, T)
   706      val v = Free (vname, T)
   731 local infix 5 ==>
   731 local infix 5 ==>
   732       fun (tm1 ==> tm2) = S.mk_imp{ant = tm1, conseq = tm2}
   732       fun (tm1 ==> tm2) = S.mk_imp{ant = tm1, conseq = tm2}
   733 in
   733 in
   734 fun build_ih f P (pat,TCs) =
   734 fun build_ih f P (pat,TCs) =
   735  let val globals = S.free_vars_lr pat
   735  let val globals = S.free_vars_lr pat
   736      fun nested tm = is_some (S.find_term (curry (op aconv) f) tm)
   736      fun nested tm = isSome (S.find_term (curry (op aconv) f) tm)
   737      fun dest_TC tm =
   737      fun dest_TC tm =
   738          let val (cntxt,R_y_pat) = S.strip_imp(#2(S.strip_forall tm))
   738          let val (cntxt,R_y_pat) = S.strip_imp(#2(S.strip_forall tm))
   739              val (R,y,_) = S.dest_relation R_y_pat
   739              val (R,y,_) = S.dest_relation R_y_pat
   740              val P_y = if (nested tm) then R_y_pat ==> P$y else P$y
   740              val P_y = if (nested tm) then R_y_pat ==> P$y else P$y
   741          in case cntxt
   741          in case cntxt
   760       fun (tm1 ==> tm2) = S.mk_imp{ant = tm1, conseq = tm2}
   760       fun (tm1 ==> tm2) = S.mk_imp{ant = tm1, conseq = tm2}
   761 in
   761 in
   762 fun build_ih f (P,SV) (pat,TCs) =
   762 fun build_ih f (P,SV) (pat,TCs) =
   763  let val pat_vars = S.free_vars_lr pat
   763  let val pat_vars = S.free_vars_lr pat
   764      val globals = pat_vars@SV
   764      val globals = pat_vars@SV
   765      fun nested tm = is_some (S.find_term (curry (op aconv) f) tm)
   765      fun nested tm = isSome (S.find_term (curry (op aconv) f) tm)
   766      fun dest_TC tm =
   766      fun dest_TC tm =
   767          let val (cntxt,R_y_pat) = S.strip_imp(#2(S.strip_forall tm))
   767          let val (cntxt,R_y_pat) = S.strip_imp(#2(S.strip_forall tm))
   768              val (R,y,_) = S.dest_relation R_y_pat
   768              val (R,y,_) = S.dest_relation R_y_pat
   769              val P_y = if (nested tm) then R_y_pat ==> P$y else P$y
   769              val P_y = if (nested tm) then R_y_pat ==> P$y else P$y
   770          in case cntxt
   770          in case cntxt
   793  *---------------------------------------------------------------------------*)
   793  *---------------------------------------------------------------------------*)
   794 fun prove_case f thy (tm,TCs_locals,thm) =
   794 fun prove_case f thy (tm,TCs_locals,thm) =
   795  let val tych = Thry.typecheck thy
   795  let val tych = Thry.typecheck thy
   796      val antc = tych(#ant(S.dest_imp tm))
   796      val antc = tych(#ant(S.dest_imp tm))
   797      val thm' = R.SPEC_ALL thm
   797      val thm' = R.SPEC_ALL thm
   798      fun nested tm = is_some (S.find_term (curry (op aconv) f) tm)
   798      fun nested tm = isSome (S.find_term (curry (op aconv) f) tm)
   799      fun get_cntxt TC = tych(#ant(S.dest_imp(#2(S.strip_forall(concl TC)))))
   799      fun get_cntxt TC = tych(#ant(S.dest_imp(#2(S.strip_forall(concl TC)))))
   800      fun mk_ih ((TC,locals),th2,nested) =
   800      fun mk_ih ((TC,locals),th2,nested) =
   801          R.GENL (map tych locals)
   801          R.GENL (map tych locals)
   802             (if nested then R.DISCH (get_cntxt TC) th2 handle U.ERR _ => th2
   802             (if nested then R.DISCH (get_cntxt TC) th2 handle U.ERR _ => th2
   803              else if S.is_imp (concl TC) then R.IMP_TRANS TC th2
   803              else if S.is_imp (concl TC) then R.IMP_TRANS TC th2
   830 fun LEFT_ABS_VSTRUCT tych thm =
   830 fun LEFT_ABS_VSTRUCT tych thm =
   831   let fun CHOOSER v (tm,thm) =
   831   let fun CHOOSER v (tm,thm) =
   832         let val ex_tm = S.mk_exists{Bvar=v,Body=tm}
   832         let val ex_tm = S.mk_exists{Bvar=v,Body=tm}
   833         in (ex_tm, R.CHOOSE(tych v, R.ASSUME (tych ex_tm)) thm)
   833         in (ex_tm, R.CHOOSE(tych v, R.ASSUME (tych ex_tm)) thm)
   834         end
   834         end
   835       val [veq] = filter (can S.dest_eq) (#1 (R.dest_thm thm))
   835       val [veq] = List.filter (can S.dest_eq) (#1 (R.dest_thm thm))
   836       val {lhs,rhs} = S.dest_eq veq
   836       val {lhs,rhs} = S.dest_eq veq
   837       val L = S.free_vars_lr rhs
   837       val L = S.free_vars_lr rhs
   838   in  #2 (U.itlist CHOOSER L (veq,thm))  end;
   838   in  #2 (U.itlist CHOOSER L (veq,thm))  end;
   839 
   839 
   840 
   840 
   849 let val tych = Thry.typecheck thy
   849 let val tych = Thry.typecheck thy
   850     val Sinduction = R.UNDISCH (R.ISPEC (tych R) Thms.WF_INDUCTION_THM)
   850     val Sinduction = R.UNDISCH (R.ISPEC (tych R) Thms.WF_INDUCTION_THM)
   851     val (pats,TCsl) = ListPair.unzip pat_TCs_list
   851     val (pats,TCsl) = ListPair.unzip pat_TCs_list
   852     val case_thm = complete_cases thy pats
   852     val case_thm = complete_cases thy pats
   853     val domain = (type_of o hd) pats
   853     val domain = (type_of o hd) pats
   854     val Pname = Term.variant (foldr (foldr add_term_names)
   854     val Pname = Term.variant (Library.foldr (Library.foldr add_term_names)
   855                               (pats::TCsl, [])) "P"
   855                               (pats::TCsl, [])) "P"
   856     val P = Free(Pname, domain --> HOLogic.boolT)
   856     val P = Free(Pname, domain --> HOLogic.boolT)
   857     val Sinduct = R.SPEC (tych P) Sinduction
   857     val Sinduct = R.SPEC (tych P) Sinduction
   858     val Sinduct_assumf = S.rand ((#ant o S.dest_imp o concl) Sinduct)
   858     val Sinduct_assumf = S.rand ((#ant o S.dest_imp o concl) Sinduct)
   859     val Rassums_TCl' = map (build_ih fconst (P,SV)) pat_TCs_list
   859     val Rassums_TCl' = map (build_ih fconst (P,SV)) pat_TCs_list
   860     val (Rassums,TCl') = ListPair.unzip Rassums_TCl'
   860     val (Rassums,TCl') = ListPair.unzip Rassums_TCl'
   861     val Rinduct_assum = R.ASSUME (tych (S.list_mk_conj Rassums))
   861     val Rinduct_assum = R.ASSUME (tych (S.list_mk_conj Rassums))
   862     val cases = map (fn pat => betapply (Sinduct_assumf, pat)) pats
   862     val cases = map (fn pat => betapply (Sinduct_assumf, pat)) pats
   863     val tasks = U.zip3 cases TCl' (R.CONJUNCTS Rinduct_assum)
   863     val tasks = U.zip3 cases TCl' (R.CONJUNCTS Rinduct_assum)
   864     val proved_cases = map (prove_case fconst thy) tasks
   864     val proved_cases = map (prove_case fconst thy) tasks
   865     val v = Free (variant (foldr add_term_names (map concl proved_cases, []))
   865     val v = Free (variant (Library.foldr add_term_names (map concl proved_cases, []))
   866                     "v",
   866                     "v",
   867                   domain)
   867                   domain)
   868     val vtyped = tych v
   868     val vtyped = tych v
   869     val substs = map (R.SYM o R.ASSUME o tych o (curry HOLogic.mk_eq v)) pats
   869     val substs = map (R.SYM o R.ASSUME o tych o (curry HOLogic.mk_eq v)) pats
   870     val proved_cases1 = ListPair.map (fn (th,th') => R.SUBS[th]th')
   870     val proved_cases1 = ListPair.map (fn (th,th') => R.SUBS[th]th')