Nominal/nominal_function.ML
changeset 2752 9f44608ea28d
parent 2745 34df2cffe259
child 2789 32979078bfe9
--- a/Nominal/nominal_function.ML	Thu Mar 31 15:25:35 2011 +0200
+++ b/Nominal/nominal_function.ML	Wed Apr 06 13:47:08 2011 +0100
@@ -40,6 +40,68 @@
 open Function_Lib
 open Function_Common
 
+
+
+(* Check for all sorts of errors in the input - nominal needs a different checking function *)
+fun nominal_check_defs ctxt fixes eqs =
+  let
+    val fnames = map (fst o fst) fixes
+
+    fun check geq =
+      let
+        fun input_error msg = error (cat_lines [msg, Syntax.string_of_term ctxt geq])
+
+        fun check_head fname =
+          member (op =) fnames fname orelse
+          input_error ("Illegal equation head. Expected " ^ commas_quote fnames)
+
+        val (fname, qs, gs, args, rhs) = split_def ctxt check_head geq
+
+        val _ = length args > 0 orelse input_error "Function has no arguments:"
+
+        fun add_bvs t is = add_loose_bnos (t, 0, is)
+        val rvs = (subtract (op =) (fold add_bvs args []) (add_bvs rhs []))
+                    |> map (fst o nth (rev qs))
+
+        val _ = forall (not o Term.exists_subterm
+          (fn Free (n, _) => member (op =) fnames n | _ => false)) (gs @ args)
+          orelse input_error "Defined function may not occur in premises or arguments"
+
+        val freeargs = map (fn t => subst_bounds (rev (map Free qs), t)) args
+        val funvars = filter (fn q => exists (exists_subterm (fn (Free q') $ _ => q = q' | _ => false)) freeargs) qs
+        val _ = null funvars orelse (warning (cat_lines
+          ["Bound variable" ^ plural " " "s " funvars ^
+          commas_quote (map fst funvars) ^ " occur" ^ plural "s" "" funvars ^
+          " in function position.", "Misspelled constructor???"]); true)
+      in
+        (fname, length args)
+      end
+
+    val grouped_args = AList.group (op =) (map check eqs)
+    val _ = grouped_args
+      |> map (fn (fname, ars) =>
+        length (distinct (op =) ars) = 1
+        orelse error ("Function " ^ quote fname ^
+          " has different numbers of arguments in different equations"))
+
+    val not_defined = subtract (op =) (map fst grouped_args) fnames
+    val _ = null not_defined
+      orelse error ("No defining equations for function" ^
+        plural " " "s " not_defined ^ commas_quote not_defined)
+
+    fun check_sorts ((fname, fT), _) =
+      Sorts.of_sort (Sign.classes_of (ProofContext.theory_of ctxt)) (fT, HOLogic.typeS)
+      orelse error (cat_lines
+      ["Type of " ^ quote fname ^ " is not of sort " ^ quote "type" ^ ":",
+       Syntax.string_of_typ (Config.put show_sorts true ctxt) fT])
+
+    val _ = map check_sorts fixes
+  in
+    ()
+  end
+
+
+
 val simp_attribs = map (Attrib.internal o K)
   [Simplifier.simp_add,
    Code.add_default_eqn_attribute,
@@ -78,7 +140,7 @@
     val ((fixes0, spec0), ctxt') = prep (constrn_fxs fixspec) eqns lthy
     val fixes = map (apfst (apfst Binding.name_of)) fixes0;
     val spec = map (fn (bnd, prop) => (bnd, [prop])) spec0;
-    val (eqs, post, sort_cont, cnames) = get_preproc lthy config ctxt' fixes spec
+    val (eqs, post, sort_cont, cnames) =  empty_preproc nominal_check_defs config ctxt' fixes spec (* nominal *)
 
     val defname = mk_defname fixes
     val FunctionConfig {partials, default, ...} = config
@@ -175,6 +237,7 @@
 val setup_case_cong = Datatype.interpretation (K (fold add_case_cong))
 
 
+
 (* setup *)
 
 val setup =