fundamental treatment of undefined vs. universally partial replaces code_abort
authorhaftmann
Wed, 01 Jan 2014 01:05:48 +0100
changeset 54890 cb892d835803
parent 54889 4121d64fde90
child 54891 2f4491f15fe6
child 54893 4061ec8adb1c
fundamental treatment of undefined vs. universally partial replaces code_abort
NEWS
src/Doc/Codegen/Foundations.thy
src/Doc/IsarRef/HOL_Specific.thy
src/HOL/Enum.thy
src/HOL/HOL.thy
src/HOL/Library/Product_Vector.thy
src/HOL/List.thy
src/HOL/Real_Vector_Spaces.thy
src/Tools/Code/code_target.ML
src/Tools/Code_Generator.thy
--- a/NEWS	Wed Jan 01 01:05:46 2014 +0100
+++ b/NEWS	Wed Jan 01 01:05:48 2014 +0100
@@ -33,6 +33,12 @@
 
 *** HOL ***
 
+* "declare [[code abort: …]]" replaces "code_abort …".
+INCOMPATIBILITY.
+
+* "declare [[code drop: …]]" drops all code equations associated
+with the given constants.
+
 * Abolished slightly odd global lattice interpretation for min/max.
 
 Fact consolidations:
--- a/src/Doc/Codegen/Foundations.thy	Wed Jan 01 01:05:46 2014 +0100
+++ b/src/Doc/Codegen/Foundations.thy	Wed Jan 01 01:05:48 2014 +0100
@@ -308,10 +308,11 @@
   of as function definitions which always fail,
   since there is never a successful pattern match on the left hand
   side.  In order to categorise a constant into that category
-  explicitly, use @{command_def "code_abort"}:
+  explicitly, use the @{attribute code} attribute with
+  @{text abort}:
 *}
 
-code_abort %quote empty_queue
+declare %quote [[code abort: empty_queue]]
 
 text {*
   \noindent Then the code generator will just insert an error or
@@ -324,9 +325,9 @@
 
 text {*
   \noindent This feature however is rarely needed in practice.  Note
-  also that the HOL default setup already declares @{const undefined}
-  as @{command "code_abort"}, which is most likely to be used in such
-  situations.
+  also that the HOL default setup already declares @{const undefined},
+  which is most likely to be used in such situations, as
+  @{text "code abort"}.
 *}
 
 
--- a/src/Doc/IsarRef/HOL_Specific.thy	Wed Jan 01 01:05:46 2014 +0100
+++ b/src/Doc/IsarRef/HOL_Specific.thy	Wed Jan 01 01:05:48 2014 +0100
@@ -2391,7 +2391,6 @@
   \begin{matharray}{rcl}
     @{command_def (HOL) "export_code"}@{text "\<^sup>*"} & : & @{text "context \<rightarrow>"} \\
     @{attribute_def (HOL) code} & : & @{text attribute} \\
-    @{command_def (HOL) "code_abort"} & : & @{text "theory \<rightarrow> theory"} \\
     @{command_def (HOL) "code_datatype"} & : & @{text "theory \<rightarrow> theory"} \\
     @{command_def (HOL) "print_codesetup"}@{text "\<^sup>*"} & : & @{text "context \<rightarrow>"} \\
     @{attribute_def (HOL) code_unfold} & : & @{text attribute} \\
@@ -2435,10 +2434,8 @@
     target: 'SML' | 'OCaml' | 'Haskell' | 'Scala' | 'Eval'
     ;
 
-    @@{attribute (HOL) code} ( 'del' | 'equation' | 'abstype' | 'abstract' )?
-    ;
-
-    @@{command (HOL) code_abort} ( const + )
+    @@{attribute (HOL) code} ( 'del' | 'equation' | 'abstype' | 'abstract'
+      | 'drop:' ( const + ) | 'abort:' ( const + ) )?
     ;
 
     @@{command (HOL) code_datatype} ( const + )
@@ -2600,13 +2597,15 @@
   of the underlying equation.  Variant @{text "code del"}
   deselects a code equation for code generation.
 
+  Variants @{text "code drop:"} and @{text "code abort:"} take
+  a list of constant as arguments and drop all code equations declared
+  for them.  In the case of {text abort}, these constants then are
+  are not required to have a definition by means of code equations;
+  if needed these are implemented by program abort (exception) instead.
+
   Usually packages introducing code equations provide a reasonable
   default setup for selection.  
 
-  \item @{command (HOL) "code_abort"} declares constants which are not
-  required to have a definition by means of code equations; if needed
-  these are implemented by program abort instead.
-
   \item @{command (HOL) "code_datatype"} specifies a constructor set
   for a logical type.
 
--- a/src/HOL/Enum.thy	Wed Jan 01 01:05:46 2014 +0100
+++ b/src/HOL/Enum.thy	Wed Jan 01 01:05:48 2014 +0100
@@ -116,7 +116,7 @@
     unfolding enum_the_def by (auto split: list.split)
 qed
 
-code_abort enum_the
+declare [[code abort: enum_the]]
 
 code_printing
   constant enum_the \<rightharpoonup> (Eval) "(fn '_ => raise Match)"
--- a/src/HOL/HOL.thy	Wed Jan 01 01:05:46 2014 +0100
+++ b/src/HOL/HOL.thy	Wed Jan 01 01:05:48 2014 +0100
@@ -1832,7 +1832,7 @@
   #> Code.add_undefined @{const_name undefined}
 *}
 
-code_abort undefined
+declare [[code abort: undefined]]
 
 
 subsubsection {* Generic code generator target languages *}
--- a/src/HOL/Library/Product_Vector.thy	Wed Jan 01 01:05:46 2014 +0100
+++ b/src/HOL/Library/Product_Vector.thy	Wed Jan 01 01:05:48 2014 +0100
@@ -87,7 +87,7 @@
 
 end
 
-code_abort "open::('a::topological_space*'b::topological_space) set \<Rightarrow> bool"
+declare [[code abort: "open::('a::topological_space*'b::topological_space) set \<Rightarrow> bool"]]
 
 lemma open_Times: "open S \<Longrightarrow> open T \<Longrightarrow> open (S \<times> T)"
 unfolding open_prod_def by auto
@@ -346,7 +346,7 @@
 
 end
 
-code_abort "dist::('a::metric_space*'b::metric_space)\<Rightarrow>('a*'b) \<Rightarrow> real"
+declare [[code abort: "dist::('a::metric_space*'b::metric_space)\<Rightarrow>('a*'b) \<Rightarrow> real"]]
 
 lemma Cauchy_fst: "Cauchy X \<Longrightarrow> Cauchy (\<lambda>n. fst (X n))"
   unfolding Cauchy_def by (fast elim: le_less_trans [OF dist_fst_le])
@@ -426,7 +426,7 @@
 
 end
 
-code_abort "norm::('a::real_normed_vector*'b::real_normed_vector) \<Rightarrow> real"
+declare [[code abort: "norm::('a::real_normed_vector*'b::real_normed_vector) \<Rightarrow> real"]]
 
 instance prod :: (banach, banach) banach ..
 
--- a/src/HOL/List.thy	Wed Jan 01 01:05:46 2014 +0100
+++ b/src/HOL/List.thy	Wed Jan 01 01:05:48 2014 +0100
@@ -6133,7 +6133,7 @@
 
 definition "abort_Bleast S P = (LEAST x. x \<in> S \<and> P x)"
 
-code_abort abort_Bleast
+declare [[code abort: abort_Bleast]]
 
 lemma Bleast_code [code]:
  "Bleast (set xs) P = (case filter P (sort xs) of
--- a/src/HOL/Real_Vector_Spaces.thy	Wed Jan 01 01:05:46 2014 +0100
+++ b/src/HOL/Real_Vector_Spaces.thy	Wed Jan 01 01:05:48 2014 +0100
@@ -968,7 +968,7 @@
 
 end
 
-code_abort "open :: real set \<Rightarrow> bool"
+declare [[code abort: "open :: real set \<Rightarrow> bool"]]
 
 instance real :: linorder_topology
 proof
--- a/src/Tools/Code/code_target.ML	Wed Jan 01 01:05:46 2014 +0100
+++ b/src/Tools/Code/code_target.ML	Wed Jan 01 01:05:48 2014 +0100
@@ -64,7 +64,6 @@
   val add_instance_syntax: string -> class * string -> unit option -> theory -> theory
   val add_reserved: string -> string -> theory -> theory
   val add_include: string -> string * (string * string list) option -> theory -> theory
-  val allow_abort: string -> theory -> theory
 
   val codegen_tool: string (*theory name*) -> string (*export_code expr*) -> unit
 
@@ -231,23 +230,20 @@
 
 structure Targets = Theory_Data
 (
-  type T = (target Symtab.table * string list) * int;
-  val empty = ((Symtab.empty, []), 80);
+  type T = target Symtab.table * int;
+  val empty = (Symtab.empty, 80);
   val extend = I;
-  fun merge (((target1, exc1), width1), ((target2, exc2), width2)) : T =
-    ((Symtab.join (merge_target true) (target1, target2),
-      Library.merge (op =) (exc1, exc2)), Int.max (width1, width2));
+  fun merge ((target1, width1), (target2, width2)) : T =
+    (Symtab.join (merge_target true) (target1, target2), Int.max (width1, width2));
 );
 
-val abort_allowed = snd o fst o Targets.get;
-
-fun assert_target thy target = if Symtab.defined ((fst o fst) (Targets.get thy)) target
+fun assert_target thy target = if Symtab.defined (fst (Targets.get thy)) target
   then target
   else error ("Unknown code target language: " ^ quote target);
 
 fun put_target (target, seri) thy =
   let
-    val lookup_target = Symtab.lookup ((fst o fst) (Targets.get thy));
+    val lookup_target = Symtab.lookup (fst (Targets.get thy));
     val _ = case seri
      of Extension (super, _) => if is_some (lookup_target super) then ()
           else error ("Unknown code target language: " ^ quote super)
@@ -263,7 +259,7 @@
       else ();
   in
     thy
-    |> (Targets.map o apfst o apfst o Symtab.update)
+    |> (Targets.map o apfst o Symtab.update)
         (target, make_target ((serial (), seri),
           ([], (Code_Symbol.empty_data, Code_Symbol.empty_data))))
   end;
@@ -277,7 +273,7 @@
     val _ = assert_target thy target;
   in
     thy
-    |> (Targets.map o apfst o apfst o Symtab.map_entry target o map_target o apsnd) f
+    |> (Targets.map o apfst o Symtab.map_entry target o map_target o apsnd) f
   end;
 
 fun map_reserved target =
@@ -296,7 +292,7 @@
 
 fun the_fundamental thy =
   let
-    val ((targets, _), _) = Targets.get thy;
+    val (targets, _) = Targets.get thy;
     fun fundamental target = case Symtab.lookup targets target
      of SOME data => (case the_description data
          of Fundamental data => data
@@ -308,7 +304,7 @@
 
 fun collapse_hierarchy thy =
   let
-    val ((targets, _), _) = Targets.get thy;
+    val (targets, _) = Targets.get thy;
     fun collapse target =
       let
         val data = case Symtab.lookup targets target
@@ -326,9 +322,9 @@
 
 fun activate_target thy target =
   let
-    val ((_, abortable), default_width) = Targets.get thy;
+    val (_, default_width) = Targets.get thy;
     val (modify, data) = collapse_hierarchy thy target;
-  in (default_width, abortable, data, modify) end;
+  in (default_width, data, modify) end;
 
 fun activate_const_syntax thy literals cs_data naming =
   (Symtab.empty, naming)
@@ -363,14 +359,13 @@
       (const_syntax, tyco_syntax, class_syntax))
   end;
 
-fun project_program thy abortable names_hidden names1 program2 =
+fun project_program thy names_hidden names1 program2 =
   let
     val ctxt = Proof_Context.init_global thy;
     val names2 = subtract (op =) names_hidden names1;
     val program3 = Graph.restrict (not o member (op =) names_hidden) program2;
     val names4 = Graph.all_succs program3 names2;
-    val unimplemented = filter_out (member (op =) abortable)
-      (Code_Thingol.unimplemented program3);
+    val unimplemented = Code_Thingol.unimplemented program3;
     val _ =
       if null unimplemented then ()
       else error ("No code equations for " ^
@@ -378,12 +373,12 @@
     val program4 = Graph.restrict (member (op =) names4) program3;
   in (names4, program4) end;
 
-fun prepare_serializer thy abortable (serializer : serializer) literals reserved identifiers
+fun prepare_serializer thy (serializer : serializer) literals reserved identifiers
     printings module_name args naming proto_program names =
   let
     val (names_hidden, (const_syntax, tyco_syntax, class_syntax)) =
       activate_symbol_syntax thy literals naming printings;
-    val (names_all, program) = project_program thy abortable names_hidden names proto_program;
+    val (names_all, program) = project_program thy names_hidden names proto_program;
     fun select_include (name, (content, cs)) =
       if null cs orelse exists (fn c => case Code_Thingol.lookup_const naming c
        of SOME name => member (op =) names_all name
@@ -405,11 +400,11 @@
 
 fun mount_serializer thy target some_width module_name args naming program names =
   let
-    val (default_width, abortable, data, modify) = activate_target thy target;
+    val (default_width, data, modify) = activate_target thy target;
     val serializer = case the_description data
      of Fundamental seri => #serializer seri;
     val (prepared_serializer, prepared_program) =
-      prepare_serializer thy abortable serializer (the_literals thy target)
+      prepare_serializer thy serializer (the_literals thy target)
         (the_reserved data) (the_identifiers data) (the_printings data)
         module_name args naming (modify naming program) names
     val width = the_default default_width some_width;
@@ -502,7 +497,7 @@
 
 fun implemented_functions thy naming program =
   let
-    val cs = subtract (op =) (abort_allowed thy) (Code_Thingol.unimplemented program);
+    val cs = Code_Thingol.unimplemented program;
     val names = map_filter (Code_Thingol.lookup_const naming) cs;
   in subtract (op =) (Graph.all_preds program names) (Graph.keys program) end;
 
@@ -699,14 +694,6 @@
     target name some_content thy;
 
 
-(* abortable constants *)
-
-fun gen_allow_abort prep_const raw_c thy =
-  let
-    val c = prep_const thy raw_c;
-  in thy |> (Targets.map o apfst o apsnd) (insert (op =) c) end;
-
-
 (* concrete syntax *)
 
 local
@@ -732,14 +719,12 @@
 val add_class_syntax = gen_add_class_syntax cert_class;
 val add_instance_syntax = gen_add_instance_syntax cert_inst;
 val add_include = gen_add_include (K I);
-val allow_abort = gen_allow_abort (K I);
 
 val add_const_syntax_cmd = gen_add_const_syntax Code.read_const;
 val add_tyco_syntax_cmd = gen_add_tyco_syntax read_tyco;
 val add_class_syntax_cmd = gen_add_class_syntax read_class;
 val add_instance_syntax_cmd = gen_add_instance_syntax read_inst;
 val add_include_cmd = gen_add_include Code.read_const;
-val allow_abort_cmd = gen_allow_abort Code.read_const;
 
 fun parse_args f args =
   case Scan.read Token.stopper f args
@@ -842,11 +827,6 @@
           (Toplevel.theory o add_include_cmd target) (name, content_consts)));
 
 val _ =
-  Outer_Syntax.command @{command_spec "code_abort"}
-    "permit constant to be implemented as program abort"
-    (Scan.repeat1 Parse.term >> (Toplevel.theory o fold allow_abort_cmd));
-
-val _ =
   Outer_Syntax.command @{command_spec "export_code"} "generate executable code for constants"
     (Parse.!!! code_exprP >> (fn f => Toplevel.keep (f o Toplevel.theory_of)));
 
--- a/src/Tools/Code_Generator.thy	Wed Jan 01 01:05:46 2014 +0100
+++ b/src/Tools/Code_Generator.thy	Wed Jan 01 01:05:48 2014 +0100
@@ -10,7 +10,7 @@
   "value" "print_codeproc" "code_thms" "code_deps" :: diag and
   "export_code" "code_identifier" "code_printing" "code_class" "code_instance" "code_type"
     "code_const" "code_reserved" "code_include" "code_modulename"
-    "code_abort" "code_monad" "code_reflect" :: thy_decl and
+    "code_monad" "code_reflect" :: thy_decl and
   "datatypes" "functions" "module_name" "file" "checking"
   "constant" "type_constructor" "type_class" "class_relation" "class_instance" "code_module"
 begin