src/HOL/Tools/function_package/sum_tools.ML
changeset 21237 b803f9870e97
parent 20523 36a59e5d0039
child 22622 25693088396b
equal deleted inserted replaced
21236:890fafbcf8b0 21237:b803f9870e97
    44 datatype sum_tree 
    44 datatype sum_tree 
    45   = Leaf of typ
    45   = Leaf of typ
    46   | Branch of (typ * (typ * sum_tree) * (typ * sum_tree))
    46   | Branch of (typ * (typ * sum_tree) * (typ * sum_tree))
    47 
    47 
    48 type sum_path = bool list (* true: left, false: right *)
    48 type sum_path = bool list (* true: left, false: right *)
    49 
    49                 
    50 fun sum_type_of (Leaf T) = T
    50 fun sum_type_of (Leaf T) = T
    51   | sum_type_of (Branch (ST,(LT,_),(RT,_))) = ST
    51   | sum_type_of (Branch (ST,(LT,_),(RT,_))) = ST
    52 
    52                                               
    53 
    53                                               
    54 fun mk_tree Ts =
    54 fun mk_tree Ts =
    55     let 
    55     let 
    56 	fun mk_tree' 1 [T] = (T, Leaf T, [[]])
    56       fun mk_tree' 1 [T] = (T, Leaf T, [[]])
    57 	  | mk_tree' n Ts =
    57         | mk_tree' n Ts =
    58 	    let 
    58           let 
    59 		val n2 = n div 2
    59             val n2 = n div 2
    60 		val (lTs, rTs) = chop n2 Ts
    60             val (lTs, rTs) = chop n2 Ts
    61 		val (TL, ltree, lpaths) = mk_tree' n2 lTs
    61             val (TL, ltree, lpaths) = mk_tree' n2 lTs
    62 		val (TR, rtree, rpaths) = mk_tree' (n - n2) rTs
    62             val (TR, rtree, rpaths) = mk_tree' (n - n2) rTs
    63 		val T = mk_sumT TL TR
    63             val T = mk_sumT TL TR
    64 		val pths = map (cons true) lpaths @ map (cons false) rpaths 
    64             val pths = map (cons true) lpaths @ map (cons false) rpaths 
    65 	    in
    65           in
    66 		(T, Branch (T, (TL, ltree), (TR, rtree)), pths)
    66             (T, Branch (T, (TL, ltree), (TR, rtree)), pths)
    67 	    end
    67           end
    68     in
    68     in
    69 	mk_tree' (length Ts) Ts
    69       mk_tree' (length Ts) Ts
    70     end
    70     end
    71 
    71     
    72 
    72     
    73 fun mk_tree_distinct Ts =
    73 fun mk_tree_distinct Ts =
    74     let
    74     let
    75       fun insert_once T Ts =
    75       fun insert_once T Ts =
    76           let
    76           let
    77             val i = find_index_eq T Ts
    77             val i = find_index_eq T Ts
    78           in
    78           in
    79             if i = ~1 then (length Ts, Ts @ [T]) else (i, Ts)
    79             if i = ~1 then (length Ts, Ts @ [T]) else (i, Ts)
    80           end
    80           end
    81 
    81           
    82       val (idxs, dist_Ts) = fold_map insert_once Ts []
    82       val (idxs, dist_Ts) = fold_map insert_once Ts []
    83 
    83                             
    84       val (ST, tree, pths) = mk_tree dist_Ts
    84       val (ST, tree, pths) = mk_tree dist_Ts
    85     in
    85     in
    86       (ST, tree, map (nth pths) idxs)
    86       (ST, tree, map (nth pths) idxs)
    87     end
    87     end
    88 
    88 
   102   | mk_proj _ _ _ = sys_error "mk_proj"
   102   | mk_proj _ _ _ = sys_error "mk_proj"
   103 
   103 
   104 
   104 
   105 fun mk_sumcases tree T ts =
   105 fun mk_sumcases tree T ts =
   106     let
   106     let
   107 	fun mk_sumcases' (Leaf _) (t::ts) = (t,ts)
   107       fun mk_sumcases' (Leaf _) (t::ts) = (t,ts)
   108 	  | mk_sumcases' (Branch (ST, (LT, ltr), (RT, rtr))) ts =
   108         | mk_sumcases' (Branch (ST, (LT, ltr), (RT, rtr))) ts =
   109 	    let
   109           let
   110 		val (lcase, ts') = mk_sumcases' ltr ts
   110             val (lcase, ts') = mk_sumcases' ltr ts
   111 		val (rcase, ts'') = mk_sumcases' rtr ts'
   111             val (rcase, ts'') = mk_sumcases' rtr ts'
   112 	    in
   112           in
   113 		(mk_sumcase LT RT T lcase rcase, ts'')
   113             (mk_sumcase LT RT T lcase rcase, ts'')
   114 	    end
   114           end
   115 	  | mk_sumcases' _ [] = sys_error "mk_sumcases"
   115         | mk_sumcases' _ [] = sys_error "mk_sumcases"
   116     in
   116     in
   117 	fst (mk_sumcases' tree ts)
   117       fst (mk_sumcases' tree ts)
   118     end
   118     end
   119 
   119     
   120 end
   120 end
   121 
   121 
   122 
   122 
   123 
   123 
   124 
   124