src/Tools/code/code_funcgr.ML
changeset 26971 160117247294
parent 26939 1035c89b4c02
child 26997 40552bbac005
equal deleted inserted replaced
26970:bc28e7bcb765 26971:160117247294
     7 *)
     7 *)
     8 
     8 
     9 signature CODE_FUNCGR =
     9 signature CODE_FUNCGR =
    10 sig
    10 sig
    11   type T
    11   type T
    12   val timing: bool ref
       
    13   val funcs: T -> string -> thm list
    12   val funcs: T -> string -> thm list
    14   val typ: T -> string -> typ
    13   val typ: T -> string -> (string * sort) list * typ
    15   val all: T -> string list
    14   val all: T -> string list
    16   val pretty: theory -> T -> Pretty.T
    15   val pretty: theory -> T -> Pretty.T
    17   val make: theory -> string list -> T
    16   val make: theory -> string list -> T
    18   val make_consts: theory -> string list -> string list * T
    17   val make_consts: theory -> string list -> string list * T
    19   val eval_conv: theory -> (term -> term * (T -> term -> thm)) -> cterm -> thm
    18   val eval_conv: theory -> (term -> term * (T -> term -> thm)) -> cterm -> thm
    20   val eval_term: theory -> (term -> term * (T -> term -> 'a)) -> term -> 'a
    19   val eval_term: theory -> (term -> term * (T -> term -> 'a)) -> term -> 'a
       
    20   val timing: bool ref
    21 end
    21 end
    22 
    22 
    23 structure CodeFuncgr : CODE_FUNCGR =
    23 structure CodeFuncgr : CODE_FUNCGR =
    24 struct
    24 struct
    25 
    25 
    26 (** the graph type **)
    26 (** the graph type **)
    27 
    27 
    28 type T = (typ * thm list) Graph.T;
    28 type T = (((string * sort) list * typ) * thm list) Graph.T;
    29 
    29 
    30 fun funcs funcgr =
    30 fun funcs funcgr =
    31   these o Option.map snd o try (Graph.get_node funcgr);
    31   these o Option.map snd o try (Graph.get_node funcgr);
    32 
    32 
    33 fun typ funcgr =
    33 fun typ funcgr =
    58   | consts_of (const, thms as _ :: _) = 
    58   | consts_of (const, thms as _ :: _) = 
    59       let
    59       let
    60         fun the_const (c, _) = if c = const then I else insert (op =) c
    60         fun the_const (c, _) = if c = const then I else insert (op =) c
    61       in fold_consts the_const thms [] end;
    61       in fold_consts the_const thms [] end;
    62 
    62 
    63 fun insts_of thy algebra c ty_decl ty =
    63 fun insts_of thy algebra tys sorts =
    64   let
    64   let
    65     val tys_decl = Sign.const_typargs thy (c, ty_decl);
       
    66     val tys = Sign.const_typargs thy (c, ty);
       
    67     fun class_relation (x, _) _ = x;
    65     fun class_relation (x, _) _ = x;
    68     fun type_constructor tyco xs class =
    66     fun type_constructor tyco xs class =
    69       (tyco, class) :: maps (maps fst) xs;
    67       (tyco, class) :: (maps o maps) fst xs;
    70     fun type_variable (TVar (_, sort)) = map (pair []) sort
    68     fun type_variable (TVar (_, sort)) = map (pair []) sort
    71       | type_variable (TFree (_, sort)) = map (pair []) sort;
    69       | type_variable (TFree (_, sort)) = map (pair []) sort;
    72     fun mk_inst ty (TVar (_, sort)) = cons (ty, sort)
    70     fun of_sort_deriv ty sort =
    73       | mk_inst ty (TFree (_, sort)) = cons (ty, sort)
       
    74       | mk_inst (Type (_, tys1)) (Type (_, tys2)) = fold2 mk_inst tys1 tys2;
       
    75     fun of_sort_deriv (ty, sort) =
       
    76       Sorts.of_sort_derivation (Syntax.pp_global thy) algebra
    71       Sorts.of_sort_derivation (Syntax.pp_global thy) algebra
    77         { class_relation = class_relation, type_constructor = type_constructor,
    72         { class_relation = class_relation, type_constructor = type_constructor,
    78           type_variable = type_variable }
    73           type_variable = type_variable }
    79         (ty, sort) handle Sorts.CLASS_ERROR _ => [] (*permissive!*)
    74         (ty, sort) handle Sorts.CLASS_ERROR _ => [] (*permissive!*)
    80   in
    75   in (flat o flat) (map2 of_sort_deriv tys sorts) end;
    81     flat (maps of_sort_deriv (fold2 mk_inst tys tys_decl []))
    76 
    82   end;
    77 fun meets_of thy algebra =
    83 
    78   let
    84 fun drop_classes thy tfrees thm =
    79     fun meet_of ty sort tab =
    85   let
    80       Sorts.meet_sort algebra (ty, sort) tab
    86     val (_, thm') = Thm.varifyT' [] thm;
    81         handle Sorts.CLASS_ERROR _ => tab (*permissive!*);
    87     val tvars = Term.add_tvars (Thm.prop_of thm') [];
    82   in fold2 meet_of end;
    88     val unconstr = map (Thm.ctyp_of thy o TVar) tvars;
       
    89     val instmap = map2 (fn (v_i, _) => fn (v, sort) => pairself (Thm.ctyp_of thy)
       
    90       (TVar (v_i, []), TFree (v, sort))) tvars tfrees;
       
    91   in
       
    92     thm'
       
    93     |> fold Thm.unconstrainT unconstr
       
    94     |> Thm.instantiate (instmap, [])
       
    95     |> Tactic.rule_by_tactic ((REPEAT o CHANGED o ALLGOALS o Tactic.resolve_tac) (AxClass.class_intros thy))
       
    96   end;
       
    97 
    83 
    98 
    84 
    99 (** graph algorithm **)
    85 (** graph algorithm **)
   100 
    86 
   101 val timing = ref false;
    87 val timing = ref false;
   102 
    88 
   103 local
    89 local
   104 
    90 
   105 exception CLASS_ERROR of string list * string;
    91 exception CLASS_ERROR of string list * string;
   106 
    92 
   107 fun resort_thms algebra tap_typ [] = []
    93 fun resort_thms thy algebra typ_of thms =
   108   | resort_thms algebra tap_typ (thms as thm :: _) =
    94   let
   109       let
    95     val cs = fold_consts (insert (op =)) thms [];
   110         val thy = Thm.theory_of_thm thm;
    96     fun meets (c, ty) = case typ_of c
   111         val pp = Syntax.pp_global thy;
    97        of SOME (vs, _) =>
   112         val cs = fold_consts (insert (op =)) thms [];
    98             meets_of thy algebra (Sign.const_typargs thy (c, ty)) (map snd vs)
   113         fun match_const c (ty, ty_decl) =
    99         | NONE => I;
       
   100     val tab = fold meets cs Vartab.empty;
       
   101   in map (CodeUnit.inst_thm tab) thms end;
       
   102 
       
   103 fun resort_funcss thy algebra funcgr =
       
   104   let
       
   105     val typ_funcgr = try (fst o Graph.get_node funcgr);
       
   106     val resort_dep = apsnd (resort_thms thy algebra typ_funcgr);
       
   107     fun resort_rec typ_of (const, []) = (true, (const, []))
       
   108       | resort_rec typ_of (const, thms as thm :: _) =
   114           let
   109           let
   115             val tys = Sign.const_typargs thy (c, ty);
   110             val (_, (vs, ty)) = CodeUnit.head_func thm;
   116             val sorts = map (snd o dest_TVar) (Sign.const_typargs thy (c, ty_decl));
   111             val thms' as thm' :: _ = resort_thms thy algebra typ_of thms
   117           in fn tab => fold2 (curry (Sorts.meet_sort algebra)) tys sorts tab
   112             val (_, (vs', ty')) = CodeUnit.head_func thm'; (*FIXME simplify check*)
   118             handle Sorts.CLASS_ERROR e => raise CLASS_ERROR ([c], Sorts.class_error pp e ^ ",\n"
       
   119               ^ "for constant " ^ CodeUnit.string_of_const thy c
       
   120               ^ "\nin defining equations(s)\n"
       
   121               ^ (cat_lines o map Display.string_of_thm) thms)
       
   122             (*handle Sorts.CLASS_ERROR _ => tab (*permissive!*)*)
       
   123           end;
       
   124         fun match (c, ty) = case tap_typ c
       
   125            of SOME ty_decl => match_const c (ty, ty_decl)
       
   126             | NONE => I;
       
   127         val tvars = fold match cs Vartab.empty;
       
   128       in map (CodeUnit.inst_thm tvars) thms end;
       
   129 
       
   130 fun resort_funcss thy algebra funcgr =
       
   131   let
       
   132     val typ_funcgr = try (fst o Graph.get_node funcgr);
       
   133     val resort_dep = apsnd (resort_thms algebra typ_funcgr);
       
   134     fun resort_rec tap_typ (const, []) = (true, (const, []))
       
   135       | resort_rec tap_typ (const, thms as thm :: _) =
       
   136           let
       
   137             val (_, ty) = CodeUnit.head_func thm;
       
   138             val thms' as thm' :: _ = resort_thms algebra tap_typ thms
       
   139             val (_, ty') = CodeUnit.head_func thm';
       
   140           in (Sign.typ_equiv thy (ty, ty'), (const, thms')) end;
   113           in (Sign.typ_equiv thy (ty, ty'), (const, thms')) end;
   141     fun resort_recs funcss =
   114     fun resort_recs funcss =
   142       let
   115       let
   143         fun tap_typ c =
   116         fun typ_of c = case these (AList.lookup (op =) funcss c)
   144           AList.lookup (op =) funcss c
   117          of thm :: _ => (SOME o snd o CodeUnit.head_func) thm
   145           |> these
   118           | [] => NONE;
   146           |> try hd
   119         val (unchangeds, funcss') = split_list (map (resort_rec typ_of) funcss);
   147           |> Option.map (snd o CodeUnit.head_func);
       
   148         val (unchangeds, funcss') = split_list (map (resort_rec tap_typ) funcss);
       
   149         val unchanged = fold (fn x => fn y => x andalso y) unchangeds true;
   120         val unchanged = fold (fn x => fn y => x andalso y) unchangeds true;
   150       in (unchanged, funcss') end;
   121       in (unchanged, funcss') end;
   151     fun resort_rec_until funcss =
   122     fun resort_rec_until funcss =
   152       let
   123       let
   153         val (unchanged, funcss') = resort_recs funcss;
   124         val (unchanged, funcss') = resort_recs funcss;
   168          (Graph.all_succs thy_classes classes))) tab [])
   139          (Graph.all_succs thy_classes classes))) tab [])
   169   end;
   140   end;
   170 
   141 
   171 fun instances_of_consts thy algebra funcgr consts =
   142 fun instances_of_consts thy algebra funcgr consts =
   172   let
   143   let
   173     fun inst (cexpr as (c, ty)) = insts_of thy algebra c
   144     fun inst (cexpr as (c, ty)) = insts_of thy algebra
   174       ((fst o Graph.get_node funcgr) c) ty;
   145       (Sign.const_typargs thy (c, ty)) ((map snd o fst) (typ funcgr c));
   175   in
   146   in
   176     []
   147     []
   177     |> fold (fold (insert (op =)) o inst) consts
   148     |> fold (fold (insert (op =)) o inst) consts
   178     |> instances_of thy algebra
   149     |> instances_of thy algebra
   179   end;
   150   end;
   214       |> filter_out (can (Graph.get_node funcgr) o fst);
   185       |> filter_out (can (Graph.get_node funcgr) o fst);
   215     fun typ_func c [] = Code.default_typ thy c
   186     fun typ_func c [] = Code.default_typ thy c
   216       | typ_func c (thms as thm :: _) = case AxClass.inst_of_param thy c
   187       | typ_func c (thms as thm :: _) = case AxClass.inst_of_param thy c
   217          of SOME (c', tyco) => 
   188          of SOME (c', tyco) => 
   218               let
   189               let
   219                 val (_, ty) = CodeUnit.head_func thm;
   190                 val (_, (vs, ty)) = CodeUnit.head_func thm;
   220                 val SOME class = AxClass.class_of_param thy c';
   191                 val SOME class = AxClass.class_of_param thy c';
   221                 val sorts_decl = Sorts.mg_domain algebra tyco [class];
   192                 val sorts_decl = Sorts.mg_domain algebra tyco [class];
   222                 val tys = Sign.const_typargs thy (c, ty);
   193               in if map snd vs = sorts_decl then (vs, ty)
   223                 val sorts = map (snd o dest_TVar) tys;
       
   224               in if sorts = sorts_decl then ty
       
   225                 else raise CLASS_ERROR ([c], "Illegal instantation for class operation "
   194                 else raise CLASS_ERROR ([c], "Illegal instantation for class operation "
   226                   ^ CodeUnit.string_of_const thy c
   195                   ^ CodeUnit.string_of_const thy c
   227                   ^ "\nin defining equations\n"
   196                   ^ "\nin defining equations\n"
   228                   ^ (cat_lines o map (Display.string_of_thm o AxClass.overload thy)) thms)
   197                   ^ (cat_lines o map (Display.string_of_thm o AxClass.overload thy)) thms)
   229               end
   198               end
   301       let
   270       let
   302         val thm2 = evaluator' funcgr t;
   271         val thm2 = evaluator' funcgr t;
   303         val thm3 = Code.postprocess_conv (Thm.rhs_of thm2);
   272         val thm3 = Code.postprocess_conv (Thm.rhs_of thm2);
   304       in
   273       in
   305         Thm.transitive thm1 (Thm.transitive thm2 thm3) handle THM _ =>
   274         Thm.transitive thm1 (Thm.transitive thm2 thm3) handle THM _ =>
   306           error ("could not construct evaluation proof (probably due to wellsortedness problem):\n"
   275           error ("could not construct evaluation proof:\n"
   307           ^ (cat_lines o map Display.string_of_thm) [thm1, thm2, thm3])
   276           ^ (cat_lines o map Display.string_of_thm) [thm1, thm2, thm3])
   308       end;
   277       end;
   309   in proto_eval thy I evaluator end;
   278   in proto_eval thy I evaluator end;
   310 
   279 
   311 fun proto_eval_term thy =
   280 fun proto_eval_term thy =