src/Tools/Code/code_thingol.ML
changeset 75324 21897aad78ad
parent 75323 a82f7f8a3c7b
child 75325 96da582011ae
equal deleted inserted replaced
75323:a82f7f8a3c7b 75324:21897aad78ad
   470       (*avoid spurious fixed variables: there is no eigen context for equations*)
   470       (*avoid spurious fixed variables: there is no eigen context for equations*)
   471   in
   471   in
   472     map (apfst (fn (args, (rhs, some_abs)) => (args,
   472     map (apfst (fn (args, (rhs, some_abs)) => (args,
   473       (annotate ctxt' algbr eqngr (c, ty) args rhs, some_abs)))) eqns
   473       (annotate ctxt' algbr eqngr (c, ty) args rhs, some_abs)))) eqns
   474   end;
   474   end;
       
   475 
       
   476 
       
   477 (* preprocessing pattern schemas *)
       
   478 
       
   479 fun preprocess_pattern_schema ctxt (t_pos, case_pats) (c_ty, ts) =
       
   480   let
       
   481     val thy = Proof_Context.theory_of ctxt;
       
   482     val ty = nth (binder_types (snd c_ty)) t_pos;
       
   483     fun select_clauses xs =
       
   484       xs
       
   485       |> nth_drop t_pos
       
   486       |> curry (op ~~) case_pats
       
   487       |> map_filter (fn (NONE, _) => NONE | (SOME _, x) => SOME x);
       
   488     fun mk_constr c t =
       
   489       let
       
   490         val n = Code.args_number thy c;
       
   491       in ((c, (take n o binder_types o fastype_of o untag_term) t ---> ty), n) end;
       
   492     val constrs =
       
   493       if null case_pats then []
       
   494       else map2 mk_constr (case_pats |> map_filter I) (select_clauses ts);
       
   495     val split_clauses =
       
   496       if null case_pats then (fn ts => (nth ts t_pos, nth_drop t_pos ts))
       
   497         else (fn ts => (nth ts t_pos, select_clauses ts));
       
   498   in (ty, constrs, split_clauses) end;
       
   499 
   475 
   500 
   476 (* abstract dictionary construction *)
   501 (* abstract dictionary construction *)
   477 
   502 
   478 datatype typarg_witness =
   503 datatype typarg_witness =
   479     Weakening of (class * class) list * plain_typarg_witness
   504     Weakening of (class * class) list * plain_typarg_witness
   673   translate_const ctxt algbr eqngr permissive some_thm (c_ty, some_abs)
   698   translate_const ctxt algbr eqngr permissive some_thm (c_ty, some_abs)
   674   ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) ts
   699   ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) ts
   675   #>> (fn (t, ts) => t `$$ ts)
   700   #>> (fn (t, ts) => t `$$ ts)
   676 and translate_case ctxt algbr eqngr permissive some_thm (t_pos, case_pats) (c_ty, ts) =
   701 and translate_case ctxt algbr eqngr permissive some_thm (t_pos, case_pats) (c_ty, ts) =
   677   let
   702   let
       
   703     val (ty, constrs, split_clauses) = preprocess_pattern_schema ctxt (t_pos, case_pats) (c_ty, ts);
   678     val thy = Proof_Context.theory_of ctxt;
   704     val thy = Proof_Context.theory_of ctxt;
   679     val ty = nth (binder_types (snd c_ty)) t_pos;
       
   680     val is_let = null case_pats;
       
   681     fun select_clauses xs =
       
   682       xs
       
   683       |> nth_drop t_pos
       
   684       |> curry (op ~~) case_pats
       
   685       |> map_filter (fn (NONE, _) => NONE | (SOME _, x) => SOME x);
       
   686     fun mk_constr c t =
       
   687       let
       
   688         val n = Code.args_number thy c;
       
   689       in ((c, (take n o binder_types o fastype_of o untag_term) t ---> ty), n) end;
       
   690     val constrs =
       
   691       if is_let then []
       
   692       else map2 mk_constr (case_pats |> map_filter I) (select_clauses ts);
       
   693     val split_clauses =
       
   694       if is_let then (fn ts => (nth ts t_pos, nth_drop t_pos ts))
       
   695         else (fn ts => (nth ts t_pos, select_clauses ts));
       
   696     fun disjunctive_varnames ts =
   705     fun disjunctive_varnames ts =
   697       let
   706       let
   698         val vs = (fold o fold_varnames) (insert (op =)) ts [];
   707         val vs = (fold o fold_varnames) (insert (op =)) ts [];
   699       in fn pat => null (inter (op =) vs (fold_varnames (insert (op =)) pat [])) end;
   708       in fn pat => null (inter (op =) vs (fold_varnames (insert (op =)) pat [])) end;
   700     fun purge_unused_vars_in t =
   709     fun purge_unused_vars_in t =
   727         val ts = map (IVar o fst) vs;
   736         val ts = map (IVar o fst) vs;
   728       in collapse_clause vs_map ts body end;
   737       in collapse_clause vs_map ts body end;
   729     fun casify constrs ty t_app ts =
   738     fun casify constrs ty t_app ts =
   730       let
   739       let
   731         val (t, ts_clause) = split_clauses ts;
   740         val (t, ts_clause) = split_clauses ts;
   732         val clauses = if null case_pats
   741         val clauses = if null constrs
   733           then map (fn ([t], body) => (t, body)) (mk_clause [ty] (the_single ts_clause))
   742           then map (fn ([t], body) => (t, body)) (mk_clause [ty] (the_single ts_clause))
   734           else maps (fn ((constr as IConst { dom = tys, ... }, n), t) =>
   743           else maps (fn ((constr as IConst { dom = tys, ... }, n), t) =>
   735             map (fn (ts, body) => (constr `$$ ts, body)) (mk_clause (take n tys) t))
   744             map (fn (ts, body) => (constr `$$ ts, body)) (mk_clause (take n tys) t))
   736               (constrs ~~ ts_clause);
   745               (constrs ~~ ts_clause);
   737       in ICase { term = t, typ = ty, clauses = clauses, primitive = t_app `$$ ts } end;
   746       in ICase { term = t, typ = ty, clauses = clauses, primitive = t_app `$$ ts } end;