src/HOL/Tools/datatype_case.ML
changeset 29266 4a478f9d2847
parent 26931 aa226d8405a8
child 29270 0eade173f77e
equal deleted inserted replaced
29265:5b4247055bd7 29266:4a478f9d2847
     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)