src/Tools/Code/code_thingol.ML
changeset 77926 b41c8fce442d
parent 77924 55fb4572e062
child 77927 f041d5060892
equal deleted inserted replaced
77925:07e82441c19e 77926:b41c8fce442d
   584 
   584 
   585 fun is_undefined_clause ctxt (_, IConst { sym = Constant c, ... }) =
   585 fun is_undefined_clause ctxt (_, IConst { sym = Constant c, ... }) =
   586       Code.is_undefined (Proof_Context.theory_of ctxt) c
   586       Code.is_undefined (Proof_Context.theory_of ctxt) c
   587   | is_undefined_clause ctxt _ =
   587   | is_undefined_clause ctxt _ =
   588       false;
   588       false;
   589 
       
   590 fun satisfied_app wanted (ty, ts) =
       
   591   let
       
   592     val given = length ts;
       
   593     val delta = wanted - given;
       
   594     val rty = (drop wanted o binder_types) ty ---> body_type ty;
       
   595   in
       
   596     if delta = 0 then
       
   597       (([], (ts, rty)), [])
       
   598     else if delta < 0 then
       
   599       let
       
   600         val (ts1, ts2) = chop wanted ts
       
   601       in (([], (ts1, rty)), ts2) end
       
   602     else
       
   603       let
       
   604         val tys = (take delta o drop given o binder_types) ty;
       
   605         val vs_tys = invent_params ((fold o fold_aterms) Term.declare_term_frees ts) tys;
       
   606       in ((vs_tys, (ts @ map Free vs_tys, rty)), []) end
       
   607   end
       
   608 
   589 
   609 fun ensure_tyco ctxt algbr eqngr permissive tyco =
   590 fun ensure_tyco ctxt algbr eqngr permissive tyco =
   610   let
   591   let
   611     val thy = Proof_Context.theory_of ctxt;
   592     val thy = Proof_Context.theory_of ctxt;
   612     val ((vs, cos), _) = Code.get_type thy tyco;
   593     val ((vs, cos), _) = Code.get_type thy tyco;
   767     #>> (fn (((c, typargs), dss), range :: dom) =>
   748     #>> (fn (((c, typargs), dss), range :: dom) =>
   768       { sym = Constant c, typargs = typargs, dicts = dss,
   749       { sym = Constant c, typargs = typargs, dicts = dss,
   769         dom = dom, range = range, annotation =
   750         dom = dom, range = range, annotation =
   770           if annotate then SOME (dom `--> range) else NONE })
   751           if annotate then SOME (dom `--> range) else NONE })
   771   end
   752   end
   772 and translate_case ctxt algbr eqngr permissive some_thm (t_pos, []) (c_ty, ts) =
   753 and translate_case ctxt algbr eqngr permissive some_thm (t_pos, []) _ (const as { dom, ... }, ts) =
   773       let
   754       let
   774         fun project_term xs = nth xs t_pos;
   755         fun project_term xs = nth xs t_pos;
   775         val project_clause = the_single o nth_drop t_pos;
   756         val project_clause = the_single o nth_drop t_pos;
   776         val ty_case = project_term (binder_types (snd c_ty));
   757         val ty_case = project_term dom;
   777         fun distill_clauses ty_case t =
   758         fun distill_clauses t =
   778           map (fn ([pat], body) => (pat, body)) (distill_minimized_clause [ty_case] t)
   759           map (fn ([pat], body) => (pat, body)) (distill_minimized_clause [ty_case] t)
   779       in
   760       in
   780         translate_const ctxt algbr eqngr permissive some_thm NONE c_ty
   761         pair (ICase { term = project_term ts, typ = ty_case,
   781         ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm NONE) ts
   762           clauses = (filter_out (is_undefined_clause ctxt) o distill_clauses o project_clause) ts,
   782         ##>> translate_typ ctxt algbr eqngr permissive ty_case
   763           primitive = IConst const `$$ ts })
   783         #>> (fn ((const, ts), ty_case) =>
       
   784             ICase { term = project_term ts, typ = ty_case,
       
   785               clauses = (filter_out (is_undefined_clause ctxt) o distill_clauses ty_case o project_clause) ts,
       
   786               primitive = IConst const `$$ ts })
       
   787       end
   764       end
   788   | translate_case ctxt algbr eqngr permissive some_thm (t_pos, case_pats) (c_ty, ts) =
   765   | translate_case ctxt algbr eqngr permissive some_thm (t_pos, case_pats) ty (const as { dom, ... }, ts) =
   789       let
   766       let
   790         fun project_term xs = nth xs t_pos;
   767         fun project_term xs = nth xs t_pos;
   791         fun project_cases xs =
   768         fun project_cases xs =
   792           xs
   769           xs
   793           |> nth_drop t_pos
   770           |> nth_drop t_pos
   794           |> curry (op ~~) case_pats
   771           |> curry (op ~~) case_pats
   795           |> map_filter (fn (NONE, _) => NONE | (SOME _, x) => SOME x);
   772           |> map_filter (fn (NONE, _) => NONE | (SOME _, x) => SOME x);
   796         val ty_case = project_term (binder_types (snd c_ty));
   773         val tys = take (length case_pats + 1) (binder_types (snd (dest_tagged_type ty)));
   797         val constrs = map_filter I case_pats ~~ project_cases ts
   774         val ty_case = project_term tys;
   798           |> map (fn ((c, n), t) =>
   775         val ty_case' = project_term dom;
   799             ((c, (take n o binder_types o fastype_of_tagged_term) t ---> ty_case), n));
   776         val constrs = map_filter I case_pats ~~ project_cases tys
       
   777           |> map (fn ((c, n), ty) =>
       
   778             ((c, (take n o binder_types) ty ---> ty_case), n));
   800         fun distill_clauses constrs ts_clause =
   779         fun distill_clauses constrs ts_clause =
   801           maps (fn ((constr as { dom = tys, ... }, n), t) =>
   780           maps (fn ((constr as { dom = tys, ... }, n), t) =>
   802             map (fn (pat_args, body) => (IConst constr `$$ pat_args, body))
   781             map (fn (pat_args, body) => (IConst constr `$$ pat_args, body))
   803               (distill_minimized_clause (take n tys) t))
   782               (distill_minimized_clause (take n tys) t))
   804                 (constrs ~~ ts_clause);
   783                 (constrs ~~ ts_clause);
   805       in
   784       in
   806         translate_const ctxt algbr eqngr permissive some_thm NONE c_ty
   785         fold_map (fn (c_ty, n) =>
   807         ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm NONE) ts
       
   808         ##>> translate_typ ctxt algbr eqngr permissive ty_case
       
   809         ##>> fold_map (fn (c_ty, n) =>
       
   810           translate_const ctxt algbr eqngr permissive some_thm NONE c_ty #>> rpair n) constrs
   786           translate_const ctxt algbr eqngr permissive some_thm NONE c_ty #>> rpair n) constrs
   811         #>> (fn (((const, ts), ty_case), constrs) =>
   787         #>> (fn constrs =>
   812             ICase { term = project_term ts, typ = ty_case,
   788             ICase { term = project_term ts, typ = ty_case',
   813               clauses = (filter_out (is_undefined_clause ctxt) o distill_clauses constrs o project_cases) ts,
   789               clauses = (filter_out (is_undefined_clause ctxt) o distill_clauses constrs o project_cases) ts,
   814               primitive = IConst const `$$ ts })
   790               primitive = IConst const `$$ ts })
   815       end
   791       end
   816 and translate_app_case ctxt algbr eqngr permissive some_thm pattern_schema c_ty ((vs_tys, (ts1, rty)), ts2) =
   792 and translate_app_case ctxt algbr eqngr permissive some_thm pattern_schema ty const ((vs_tys, (ts1, rty)), ts2) =
   817   fold_map (fn (v, ty) => translate_typ ctxt algbr eqngr permissive ty #>> pair (SOME v)) vs_tys
   793   translate_case ctxt algbr eqngr permissive some_thm pattern_schema ty (const, ts1)
   818   ##>> translate_case ctxt algbr eqngr permissive some_thm pattern_schema (c_ty, ts1)
   794   #>> (fn t => (vs_tys `|==> (t, rty)) `$$ ts2)
   819   ##>> translate_typ ctxt algbr eqngr permissive rty
       
   820   ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm NONE) ts2
       
   821   #>> (fn (((vs_tys, t), rty), ts) => (vs_tys `|==> (t, rty)) `$$ ts)
       
   822 and translate_app ctxt algbr eqngr permissive some_thm some_abs (c_ty as (c, ty), ts) =
   795 and translate_app ctxt algbr eqngr permissive some_thm some_abs (c_ty as (c, ty), ts) =
   823   case Code.get_case_schema (Proof_Context.theory_of ctxt) c of
   796   case Code.get_case_schema (Proof_Context.theory_of ctxt) c of
   824     SOME (wanted, pattern_schema) =>
   797     SOME (wanted, pattern_schema) =>
   825       translate_app_case ctxt algbr eqngr permissive some_thm pattern_schema c_ty (satisfied_app wanted (ty, ts))
   798       translate_const ctxt algbr eqngr permissive some_thm some_abs c_ty
       
   799       ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm NONE) ts
       
   800       #-> (fn (const, ts) => translate_app_case ctxt algbr eqngr permissive some_thm pattern_schema
       
   801             ty const (satisfied_application wanted (const, ts)))
   826   | NONE =>
   802   | NONE =>
   827       translate_const ctxt algbr eqngr permissive some_thm some_abs c_ty
   803       translate_const ctxt algbr eqngr permissive some_thm some_abs c_ty
   828       ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm NONE) ts
   804       ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm NONE) ts
   829       #>> (fn (const, ts) => IConst const `$$ ts)
   805       #>> (fn (const, ts) => IConst const `$$ ts)
   830 and translate_tyvar_sort ctxt (algbr as (proj_sort, _)) eqngr permissive (v, sort) =
   806 and translate_tyvar_sort ctxt (algbr as (proj_sort, _)) eqngr permissive (v, sort) =