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') |