src/Tools/Code/code_thingol.ML
changeset 37440 a5d44161ba2a
parent 37437 4202e11ae7dc
child 37445 e372fa3c7239
equal deleted inserted replaced
37439:c72a43a7d2c5 37440:a5d44161ba2a
    79   type program = stmt Graph.T
    79   type program = stmt Graph.T
    80   val empty_funs: program -> string list
    80   val empty_funs: program -> string list
    81   val map_terms_bottom_up: (iterm -> iterm) -> iterm -> iterm
    81   val map_terms_bottom_up: (iterm -> iterm) -> iterm -> iterm
    82   val map_terms_stmt: (iterm -> iterm) -> stmt -> stmt
    82   val map_terms_stmt: (iterm -> iterm) -> stmt -> stmt
    83   val is_cons: program -> string -> bool
    83   val is_cons: program -> string -> bool
       
    84   val is_case: stmt -> bool
    84   val contr_classparam_typs: program -> string -> itype option list
    85   val contr_classparam_typs: program -> string -> itype option list
    85   val labelled_name: theory -> program -> string -> string
    86   val labelled_name: theory -> program -> string -> string
    86   val group_stmts: theory -> program
    87   val group_stmts: theory -> program
    87     -> ((string * stmt) list * (string * stmt) list
    88     -> ((string * stmt) list * (string * stmt) list
    88       * ((string * stmt) list * (string * stmt) list)) list
    89       * ((string * stmt) list * (string * stmt) list)) list
   443 
   444 
   444 fun is_cons program name = case Graph.get_node program name
   445 fun is_cons program name = case Graph.get_node program name
   445  of Datatypecons _ => true
   446  of Datatypecons _ => true
   446   | _ => false;
   447   | _ => false;
   447 
   448 
       
   449 fun is_case (Fun (_, (_, SOME _))) = true
       
   450   | is_case _ = false;
       
   451 
   448 fun contr_classparam_typs program name = case Graph.get_node program name
   452 fun contr_classparam_typs program name = case Graph.get_node program name
   449  of Classparam (_, class) => let
   453  of Classparam (_, class) => let
   450         val Class (_, (_, (_, params))) = Graph.get_node program class;
   454         val Class (_, (_, (_, params))) = Graph.get_node program class;
   451         val SOME ty = AList.lookup (op =) params name;
   455         val SOME ty = AList.lookup (op =) params name;
   452         val (tys, res_ty) = unfold_fun ty;
   456         val (tys, res_ty) = unfold_fun ty;
   470   | Classparam (c, _) => quote (Code.string_of_const thy c)
   474   | Classparam (c, _) => quote (Code.string_of_const thy c)
   471   | Classinst ((class, (tyco, _)), _) => let
   475   | Classinst ((class, (tyco, _)), _) => let
   472         val Class (class, _) = Graph.get_node program class
   476         val Class (class, _) = Graph.get_node program class
   473         val Datatype (tyco, _) = Graph.get_node program tyco
   477         val Datatype (tyco, _) = Graph.get_node program tyco
   474       in quote (Sign.extern_type thy tyco ^ " :: " ^ Sign.extern_class thy class) end
   478       in quote (Sign.extern_type thy tyco ^ " :: " ^ Sign.extern_class thy class) end
       
   479 
       
   480 fun linear_stmts program =
       
   481   rev (Graph.strong_conn program)
       
   482   |> map (AList.make (Graph.get_node program));
   475 
   483 
   476 fun group_stmts thy program =
   484 fun group_stmts thy program =
   477   let
   485   let
   478     fun is_fun (_, Fun _) = true | is_fun _ = false;
   486     fun is_fun (_, Fun _) = true | is_fun _ = false;
   479     fun is_datatypecons (_, Datatypecons _) = true | is_datatypecons _ = false;
   487     fun is_datatypecons (_, Datatypecons _) = true | is_datatypecons _ = false;
   490       else if forall (is_fun orf is_classinst) stmts
   498       else if forall (is_fun orf is_classinst) stmts
   491       then ([], [], List.partition is_fun stmts)
   499       then ([], [], List.partition is_fun stmts)
   492       else error ("Illegal mutual dependencies: " ^
   500       else error ("Illegal mutual dependencies: " ^
   493         (commas o map (labelled_name thy program o fst)) stmts)
   501         (commas o map (labelled_name thy program o fst)) stmts)
   494   in
   502   in
   495     rev (Graph.strong_conn program)
   503     linear_stmts program
   496     |> map (AList.make (Graph.get_node program))
       
   497     |> map group
   504     |> map group
   498   end;
   505   end;
   499 
   506 
   500 
   507 
   501 (** translation kernel **)
   508 (** translation kernel **)
   566       ensure_class thy algbr eqngr permissive class
   573       ensure_class thy algbr eqngr permissive class
   567       #>> (fn class => Classparam (c, class));
   574       #>> (fn class => Classparam (c, class));
   568     fun stmt_fun cert =
   575     fun stmt_fun cert =
   569       let
   576       let
   570         val ((vs, ty), eqns) = Code.equations_of_cert thy cert;
   577         val ((vs, ty), eqns) = Code.equations_of_cert thy cert;
       
   578         val some_case_cong = Code.get_case_cong thy c;
   571       in
   579       in
   572         fold_map (translate_tyvar_sort thy algbr eqngr permissive) vs
   580         fold_map (translate_tyvar_sort thy algbr eqngr permissive) vs
   573         ##>> translate_typ thy algbr eqngr permissive ty
   581         ##>> translate_typ thy algbr eqngr permissive ty
   574         ##>> (fold_map (translate_equation thy algbr eqngr permissive) eqns
   582         ##>> translate_eqns thy algbr eqngr permissive eqns
   575           #>> map_filter I)
   583         #>> (fn info => Fun (c, (info, some_case_cong)))
   576         #>> (fn info => Fun (c, (info, NONE)))
       
   577       end;
   584       end;
   578     val stmt_const = case Code.get_type_of_constr_or_abstr thy c
   585     val stmt_const = case Code.get_type_of_constr_or_abstr thy c
   579      of SOME (tyco, _) => stmt_datatypecons tyco
   586      of SOME (tyco, _) => stmt_datatypecons tyco
   580       | NONE => (case AxClass.class_of_param thy c
   587       | NONE => (case AxClass.class_of_param thy c
   581          of SOME class => stmt_classparam class
   588          of SOME class => stmt_classparam class
   665             #>> (fn (t, ts) => t `$$ ts)
   672             #>> (fn (t, ts) => t `$$ ts)
   666 and translate_eqn thy algbr eqngr permissive ((args, (rhs, some_abs)), (some_thm, proper)) =
   673 and translate_eqn thy algbr eqngr permissive ((args, (rhs, some_abs)), (some_thm, proper)) =
   667   fold_map (translate_term thy algbr eqngr permissive some_thm) args
   674   fold_map (translate_term thy algbr eqngr permissive some_thm) args
   668   ##>> translate_term thy algbr eqngr permissive some_thm (rhs, some_abs)
   675   ##>> translate_term thy algbr eqngr permissive some_thm (rhs, some_abs)
   669   #>> rpair (some_thm, proper)
   676   #>> rpair (some_thm, proper)
   670 and translate_equation thy algbr eqngr permissive eqn prgrm =
   677 and translate_eqns thy algbr eqngr permissive eqns prgrm =
   671   prgrm |> translate_eqn thy algbr eqngr permissive eqn |>> SOME
   678   prgrm |> fold_map (translate_eqn thy algbr eqngr permissive) eqns
   672     handle PERMISSIVE () => (NONE, prgrm)
   679     handle PERMISSIVE () => ([], prgrm)
   673 and translate_const thy algbr eqngr permissive some_thm ((c, ty), some_abs) =
   680 and translate_const thy algbr eqngr permissive some_thm ((c, ty), some_abs) =
   674   let
   681   let
   675     val _ = if (case some_abs of NONE => true | SOME abs => not (c = abs))
   682     val _ = if (case some_abs of NONE => true | SOME abs => not (c = abs))
   676         andalso Code.is_abstr thy c
   683         andalso Code.is_abstr thy c
   677         then translation_error thy permissive some_thm
   684         then translation_error thy permissive some_thm