Infinite chains in definitions are now detected, too.
authorobua
Mon, 30 May 2005 16:32:47 +0200
changeset 16113 692fe6595755
parent 16112 27585e65028b
child 16114 8d453f906e43
Infinite chains in definitions are now detected, too.
src/Pure/defs.ML
src/Pure/theory.ML
--- a/src/Pure/defs.ML	Mon May 30 10:25:46 2005 +0200
+++ b/src/Pure/defs.ML	Mon May 30 16:32:47 2005 +0200
@@ -13,14 +13,15 @@
 
     exception DEFS of string
     exception CIRCULAR of (typ * string * string) list
+    exception INFINITE_CHAIN of (typ * string * string) list 
     exception CLASH of string * string * string
     
     val empty : graph
     val declare : graph -> string -> typ -> graph  (* exception DEFS *)
-    val define : graph -> string -> typ -> string -> (string * typ) list -> graph (* exception DEFS, CIRCULAR, CLASH *)
+    val define : graph -> string -> typ -> string -> (string * typ) list -> graph (* exception DEFS, CIRCULAR, INFINITE_CHAIN, CLASH *)
 
     (* the first argument should be the smaller graph *)
-    val merge : graph -> graph -> graph (* exception CIRCULAR, CLASH *)
+    val merge : graph -> graph -> graph (* exception CIRCULAR, INFINITE_CHAIN, CLASH *)
 
 end
 
@@ -70,6 +71,7 @@
 
 exception DEFS of string;
 exception CIRCULAR of (typ * string * string) list;
+exception INFINITE_CHAIN of (typ * string * string) list;
 exception CLASH of string * string * string;
 
 fun def_err s = raise (DEFS s)
@@ -390,7 +392,13 @@
 				    val _ = 
 					if noderef = mainref andalso defname = axname then
 					    (case unify alpha' ty' of
-						 NONE => ()
+						 NONE => 
+						   if (is_instance_r ty' alpha') then
+						       raise (INFINITE_CHAIN (
+							      (alpha', mainref, axname)::
+							      (subst_history s_beta history)@
+							      [(ty', mainref, axname)]))
+						   else ()
 					       | SOME s => raise (CIRCULAR (
 								  (subst s alpha', mainref, axname)::
 								  (subst_history s (subst_history s_beta history))@
--- a/src/Pure/theory.ML	Mon May 30 10:25:46 2005 +0200
+++ b/src/Pure/theory.ML	Mon May 30 16:32:47 2005 +0200
@@ -396,14 +396,18 @@
 
 fun pretty_const sg (c, ty) = [Pretty.str c, Pretty.str " ::", Pretty.quote (Sign.pretty_typ sg (#1 (Type.freeze_thaw_type ty)))];
 
-fun cycle_msg sg namess = Pretty.string_of (Pretty.block (((Pretty.str "cyclic dependency found: ") :: Pretty.fbrk :: (
-  let      
-      fun f last (ty, constname, defname) =  
-	  (pretty_const sg (constname, ty)) @ (if last then [] else [Pretty.str (" depends via "^ quote defname^ " on ")])
+fun cycle_msg sg (infinite, namess) = 
+  let val header = if not (infinite) then "cyclic dependency found: " else "infinite chain found: "
+  in
+      Pretty.string_of (Pretty.block (((Pretty.str header) :: Pretty.fbrk :: (
+        let      
+	    fun f last (ty, constname, defname) =  
+		(pretty_const sg (constname, ty)) @ (if last then [] else [Pretty.str (" depends via "^ quote defname^ " on ")])
           	
-  in
-      foldr (fn (x,r) => (f (r=[]) x)@[Pretty.fbrk]@r) [] namess
-  end))))
+	in
+	    foldr (fn (x,r) => (f (r=[]) x)@[Pretty.fbrk]@r) [] namess
+	end))))
+  end
 
 fun check_defn sg overloaded final_consts ((deps, axms), def as (name, tm)) =
   let
@@ -455,7 +459,8 @@
 	 let 
 	     val deps' = Defs.define deps c ty name body
 		 handle Defs.DEFS s => err_in_defn sg name ("DEFS: "^s) 
-		      | Defs.CIRCULAR s => err_in_defn sg name (cycle_msg sg s)
+		      | Defs.CIRCULAR s => err_in_defn sg name (cycle_msg sg (false, s))
+                      | Defs.INFINITE_CHAIN s => err_in_defn sg name (cycle_msg sg (true, s)) 
                       | Defs.CLASH (_, def1, def2) => err_in_defn sg name (
 			  "clashing definitions "^ quote def1 ^" and "^ quote def2)
 	 in
@@ -565,7 +570,8 @@
 
     val depss = map (#const_deps o rep_theory) thys;
     val deps' = foldl (uncurry Defs.merge) (hd depss) (tl depss)
-      handle Defs.CIRCULAR namess => error (cycle_msg sign' namess);
+      handle Defs.CIRCULAR namess => error (cycle_msg sign' (false, namess))
+	   | Defs.INFINITE_CHAIN namess => error (cycle_msg sign' (true, namess))
 
     val final_constss = map (#final_consts o rep_theory) thys;
     val final_consts' =