src/HOL/Tools/case_translation.ML
changeset 52159 432e29ff9f14
parent 52158 d5fa81343322
child 52265 bb907eba5902
equal deleted inserted replaced
52158:d5fa81343322 52159:432e29ff9f14
   157 
   157 
   158 
   158 
   159 (* print translation *)
   159 (* print translation *)
   160 
   160 
   161 fun case_tr' (_ :: x :: t :: ts) =
   161 fun case_tr' (_ :: x :: t :: ts) =
   162   let
   162       let
   163     fun mk_clause (Const (@{const_syntax case_abs}, _) $ Abs (s, T, t)) xs used =
   163         fun mk_clause (Const (@{const_syntax case_abs}, _) $ Abs (s, T, t)) xs used =
   164           let val (s', used') = Name.variant s used
   164               let val (s', used') = Name.variant s used
   165           in mk_clause t ((s', T) :: xs) used' end
   165               in mk_clause t ((s', T) :: xs) used' end
   166       | mk_clause (Const (@{const_syntax case_elem}, _) $ pat $ rhs) xs _ =
   166           | mk_clause (Const (@{const_syntax case_elem}, _) $ pat $ rhs) xs _ =
   167           Syntax.const @{syntax_const "_case1"} $
   167               Syntax.const @{syntax_const "_case1"} $
   168             subst_bounds (map Syntax_Trans.mark_bound_abs xs, pat) $
   168                 subst_bounds (map Syntax_Trans.mark_bound_abs xs, pat) $
   169             subst_bounds (map Syntax_Trans.mark_bound_body xs, rhs);
   169                 subst_bounds (map Syntax_Trans.mark_bound_body xs, rhs)
   170 
   170           | mk_clause _ _ _ = raise Match;
   171     fun mk_clauses (Const (@{const_syntax case_nil}, _)) = []
   171 
   172       | mk_clauses (Const (@{const_syntax case_cons}, _) $ t $ u) =
   172         fun mk_clauses (Const (@{const_syntax case_nil}, _)) = []
   173           mk_clause t [] (Term.declare_term_frees t Name.context) ::
   173           | mk_clauses (Const (@{const_syntax case_cons}, _) $ t $ u) =
   174           mk_clauses u
   174               mk_clause t [] (Term.declare_term_frees t Name.context) :: mk_clauses u
   175   in
   175           | mk_clauses _ = raise Match;
   176     list_comb (Syntax.const @{syntax_const "_case_syntax"} $ x $
   176       in
   177       foldr1 (fn (t, u) => Syntax.const @{syntax_const "_case2"} $ t $ u)
   177         list_comb (Syntax.const @{syntax_const "_case_syntax"} $ x $
   178         (mk_clauses t), ts)
   178           foldr1 (fn (t, u) => Syntax.const @{syntax_const "_case2"} $ t $ u)
   179   end;
   179             (mk_clauses t), ts)
       
   180       end
       
   181   | case_tr' _ = raise Match;
   180 
   182 
   181 val trfun_setup' = Sign.print_translation [(@{const_syntax "case_guard"}, K case_tr')];
   183 val trfun_setup' = Sign.print_translation [(@{const_syntax "case_guard"}, K case_tr')];
   182 
   184 
   183 
   185 
   184 (* declarations *)
   186 (* declarations *)
   210 
   212 
   211 (*Each pattern carries with it a tag i, which denotes the clause it
   213 (*Each pattern carries with it a tag i, which denotes the clause it
   212   came from. i = ~1 indicates that the clause was added by pattern
   214   came from. i = ~1 indicates that the clause was added by pattern
   213   completion.*)
   215   completion.*)
   214 
   216 
   215 fun add_row_used ((prfx, pats), (tm, tag)) =
   217 fun add_row_used ((prfx, pats), (tm, _)) =
   216   fold Term.declare_term_frees (tm :: pats @ map Free prfx);
   218   fold Term.declare_term_frees (tm :: pats @ map Free prfx);
   217 
   219 
   218 (*try to preserve names given by user*)
   220 (*try to preserve names given by user*)
   219 fun default_name "" (Free (name', _)) = name'
   221 fun default_name "" (Free (name', _)) = name'
   220   | default_name name _ = name;
   222   | default_name name _ = name;
   296 
   298 
   297 fun mk_case ctxt used range_ty =
   299 fun mk_case ctxt used range_ty =
   298   let
   300   let
   299     val get_info = lookup_by_constr_permissive ctxt;
   301     val get_info = lookup_by_constr_permissive ctxt;
   300 
   302 
   301     fun expand constructors used ty ((_, []), _) = raise CASE_ERROR ("mk_case: expand", ~1)
   303     fun expand _ _ _ ((_, []), _) = raise CASE_ERROR ("mk_case: expand", ~1)
   302       | expand constructors used ty (row as ((prfx, p :: ps), (rhs, tag))) =
   304       | expand constructors used ty (row as ((prfx, p :: ps), (rhs, tag))) =
   303           if is_Free p then
   305           if is_Free p then
   304             let
   306             let
   305               val used' = add_row_used row used;
   307               val used' = add_row_used row used;
   306               fun expnd c =
   308               fun expnd c =
   311 
   313 
   312     val (name, _) = Name.variant "a" used;
   314     val (name, _) = Name.variant "a" used;
   313 
   315 
   314     fun mk _ [] = raise CASE_ERROR ("no rows", ~1)
   316     fun mk _ [] = raise CASE_ERROR ("no rows", ~1)
   315       | mk [] (((_, []), (tm, tag)) :: _) = ([tag], tm) (* Done *)
   317       | mk [] (((_, []), (tm, tag)) :: _) = ([tag], tm) (* Done *)
   316       | mk path (rows as ((row as ((_, [Free _]), _)) :: _ :: _)) = mk path [row]
   318       | mk path ((row as ((_, [Free _]), _)) :: _ :: _) = mk path [row]
   317       | mk (u :: us) (rows as ((_, _ :: _), _) :: _) =
   319       | mk (u :: us) (rows as ((_, _ :: _), _) :: _) =
   318           let val col0 = map (fn ((_, p :: _), (_, i)) => (p, i)) rows in
   320           let val col0 = map (fn ((_, p :: _), (_, i)) => (p, i)) rows in
   319             (case Option.map (apfst head_of) (find_first (not o is_Free o fst) col0) of
   321             (case Option.map (apfst head_of) (find_first (not o is_Free o fst) col0) of
   320               NONE =>
   322               NONE =>
   321                 let
   323                 let