src/HOL/Tools/Datatype/datatype_case.ML
changeset 45898 b619242b0439
parent 45894 629d123b7dbe
child 46003 c0fe5e8e4864
equal deleted inserted replaced
45897:65cef0298158 45898:b619242b0439
   128                 {constructor = c',
   128                 {constructor = c',
   129                  new_formals = gvars,
   129                  new_formals = gvars,
   130                  names = names,
   130                  names = names,
   131                  constraints = cnstrts,
   131                  constraints = cnstrts,
   132                  group = in_group'} :: part cs not_in_group
   132                  group = in_group'} :: part cs not_in_group
   133               end
   133               end;
   134       in part constructors rows end;
   134       in part constructors rows end;
   135 
   135 
   136 fun v_to_prfx (prfx, Free v :: pats) = (v :: prfx, pats)
   136 fun v_to_prfx (prfx, Free v :: pats) = (v :: prfx, pats)
   137   | v_to_prfx _ = raise CASE_ERROR ("mk_case: v_to_prfx", ~1);
   137   | v_to_prfx _ = raise CASE_ERROR ("mk_case: v_to_prfx", ~1);
   138 
   138 
   141 
   141 
   142 fun mk_case ctxt ty_match ty_inst type_of used range_ty =
   142 fun mk_case ctxt ty_match ty_inst type_of used range_ty =
   143   let
   143   let
   144     val get_info = Datatype_Data.info_of_constr_permissive (Proof_Context.theory_of ctxt);
   144     val get_info = Datatype_Data.info_of_constr_permissive (Proof_Context.theory_of ctxt);
   145 
   145 
   146     val name = singleton (Name.variant_list used) "a";
       
   147     fun expand constructors used ty ((_, []), _) = raise CASE_ERROR ("mk_case: expand_var_row", ~1)
   146     fun expand constructors used ty ((_, []), _) = raise CASE_ERROR ("mk_case: expand_var_row", ~1)
   148       | expand constructors used ty (row as ((prfx, p :: ps), (rhs, tag))) =
   147       | expand constructors used ty (row as ((prfx, p :: ps), (rhs, tag))) =
   149           if is_Free p then
   148           if is_Free p then
   150             let
   149             let
   151               val used' = add_row_used row used;
   150               val used' = add_row_used row used;
   152               fun expnd c =
   151               fun expnd c =
   153                 let val capp = list_comb (fresh_constr ty_match ty_inst ty used' c)
   152                 let val capp = list_comb (fresh_constr ty_match ty_inst ty used' c)
   154                 in ((prfx, capp :: ps), (subst_free [(p, capp)] rhs, tag)) end
   153                 in ((prfx, capp :: ps), (subst_free [(p, capp)] rhs, tag)) end
   155             in map expnd constructors end
   154             in map expnd constructors end
   156           else [row]
   155           else [row];
       
   156 
       
   157     val name = singleton (Name.variant_list used) "a";
       
   158 
   157     fun mk _ [] = raise CASE_ERROR ("no rows", ~1)
   159     fun mk _ [] = raise CASE_ERROR ("no rows", ~1)
   158       | mk [] (((_, []), (tm, tag)) :: _) = ([tag], tm) (* Done *)
   160       | mk [] (((_, []), (tm, tag)) :: _) = ([tag], tm) (* Done *)
   159       | mk path (rows as ((row as ((_, [Free _]), _)) :: _ :: _)) = mk path [row]
   161       | mk path (rows as ((row as ((_, [Free _]), _)) :: _ :: _)) = mk path [row]
   160       | mk (u :: us) (rows as ((_, _ :: _), _) :: _) =
   162       | mk (u :: us) (rows as ((_, _ :: _), _) :: _) =
   161           let val col0 = map (fn ((_, p :: _), (_, i)) => (p, i)) rows in
   163           let val col0 = map (fn ((_, p :: _), (_, i)) => (p, i)) rows in
   275               let
   277               let
   276                 val (t', used') = prep_pat t used;
   278                 val (t', used') = prep_pat t used;
   277                 val (u', used'') = prep_pat u used';
   279                 val (u', used'') = prep_pat u used';
   278               in (t' $ u', used'') end
   280               in (t' $ u', used'') end
   279           | prep_pat t used = case_error ("Bad pattern: " ^ Syntax.string_of_term ctxt t);
   281           | prep_pat t used = case_error ("Bad pattern: " ^ Syntax.string_of_term ctxt t);
       
   282 
   280         fun dest_case1 (t as Const (@{syntax_const "_case1"}, _) $ l $ r) =
   283         fun dest_case1 (t as Const (@{syntax_const "_case1"}, _) $ l $ r) =
   281               let val (l', cnstrts) = strip_constraints l
   284               let val (l', cnstrts) = strip_constraints l
   282               in ((fst (prep_pat l' (Term.add_free_names t [])), r), cnstrts) end
   285               in ((fst (prep_pat l' (Term.add_free_names t [])), r), cnstrts) end
   283           | dest_case1 t = case_error "dest_case1";
   286           | dest_case1 t = case_error "dest_case1";
       
   287 
   284         fun dest_case2 (Const (@{syntax_const "_case2"}, _) $ t $ u) = t :: dest_case2 u
   288         fun dest_case2 (Const (@{syntax_const "_case2"}, _) $ t $ u) = t :: dest_case2 u
   285           | dest_case2 t = [t];
   289           | dest_case2 t = [t];
       
   290 
   286         val (cases, cnstrts) = split_list (map dest_case1 (dest_case2 u));
   291         val (cases, cnstrts) = split_list (map dest_case1 (dest_case2 u));
   287         val case_tm =
   292       in
   288           make_case_untyped ctxt
   293         make_case_untyped ctxt
   289             (if err then Error else Warning) []
   294           (if err then Error else Warning) []
   290             (fold (fn tT => fn t => Syntax.const @{syntax_const "_constrain"} $ t $ tT)
   295           (fold (fn tT => fn t => Syntax.const @{syntax_const "_constrain"} $ t $ tT)
   291                (flat cnstrts) t) cases;
   296              (flat cnstrts) t) cases
   292       in case_tm end
   297       end
   293   | case_tr _ _ _ = case_error "case_tr";
   298   | case_tr _ _ _ = case_error "case_tr";
   294 
   299 
   295 val trfun_setup =
   300 val trfun_setup =
   296   Sign.add_advanced_trfuns ([],
   301   Sign.add_advanced_trfuns ([],
   297     [(@{syntax_const "_case_syntax"}, case_tr true)],
   302     [(@{syntax_const "_case_syntax"}, case_tr true)],