1 (* Title: HOL/Tools/datatype_case.ML |
1 (* Title: HOL/Tools/datatype_case.ML |
2 ID: $Id$ |
|
3 Author: Konrad Slind, Cambridge University Computer Laboratory |
2 Author: Konrad Slind, Cambridge University Computer Laboratory |
4 Stefan Berghofer, TU Muenchen |
3 Author: Stefan Berghofer, TU Muenchen |
5 |
4 |
6 Nested case expressions on datatypes. |
5 Nested case expressions on datatypes. |
7 *) |
6 *) |
8 |
7 |
9 signature DATATYPE_CASE = |
8 signature DATATYPE_CASE = |
424 (* destruct nested patterns *) |
423 (* destruct nested patterns *) |
425 |
424 |
426 fun strip_case' dest (pat, rhs) = |
425 fun strip_case' dest (pat, rhs) = |
427 case dest (add_term_free_names (pat, [])) rhs of |
426 case dest (add_term_free_names (pat, [])) rhs of |
428 SOME (exp as Free _, clauses) => |
427 SOME (exp as Free _, clauses) => |
429 if member op aconv (term_frees pat) exp andalso |
428 if member op aconv (OldTerm.term_frees pat) exp andalso |
430 not (exists (fn (_, rhs') => |
429 not (exists (fn (_, rhs') => |
431 member op aconv (term_frees rhs') exp) clauses) |
430 member op aconv (OldTerm.term_frees rhs') exp) clauses) |
432 then |
431 then |
433 maps (strip_case' dest) (map (fn (pat', rhs') => |
432 maps (strip_case' dest) (map (fn (pat', rhs') => |
434 (subst_free [(exp, pat')] pat, rhs')) clauses) |
433 (subst_free [(exp, pat')] pat, rhs')) clauses) |
435 else [(pat, rhs)] |
434 else [(pat, rhs)] |
436 | _ => [(pat, rhs)]; |
435 | _ => [(pat, rhs)]; |
449 fun case_tr' tab_of cname ctxt ts = |
448 fun case_tr' tab_of cname ctxt ts = |
450 let |
449 let |
451 val thy = ProofContext.theory_of ctxt; |
450 val thy = ProofContext.theory_of ctxt; |
452 val consts = ProofContext.consts_of ctxt; |
451 val consts = ProofContext.consts_of ctxt; |
453 fun mk_clause (pat, rhs) = |
452 fun mk_clause (pat, rhs) = |
454 let val xs = term_frees pat |
453 let val xs = Term.add_frees pat [] |
455 in |
454 in |
456 Syntax.const "_case1" $ |
455 Syntax.const "_case1" $ |
457 map_aterms |
456 map_aterms |
458 (fn Free p => Syntax.mark_boundT p |
457 (fn Free p => Syntax.mark_boundT p |
459 | Const (s, _) => Const (Consts.extern_early consts s, dummyT) |
458 | Const (s, _) => Const (Consts.extern_early consts s, dummyT) |
460 | t => t) pat $ |
459 | t => t) pat $ |
461 map_aterms |
460 map_aterms |
462 (fn x as Free (s, _) => |
461 (fn x as Free (s, T) => |
463 if member op aconv xs x then Syntax.mark_bound s else x |
462 if member (op =) xs (s, T) then Syntax.mark_bound s else x |
464 | t => t) rhs |
463 | t => t) rhs |
465 end |
464 end |
466 in case strip_case' (tab_of thy) true (list_comb (Syntax.const cname, ts)) of |
465 in case strip_case' (tab_of thy) true (list_comb (Syntax.const cname, ts)) of |
467 SOME (x, clauses) => Syntax.const "_case_syntax" $ x $ |
466 SOME (x, clauses) => Syntax.const "_case_syntax" $ x $ |
468 foldr1 (fn (t, u) => Syntax.const "_case2" $ t $ u) |
467 foldr1 (fn (t, u) => Syntax.const "_case2" $ t $ u) |