src/HOL/Tools/refute.ML
author webertj
Wed Feb 23 14:04:53 2005 +0100 (2005-02-23)
changeset 15547 f08e2d83681e
parent 15531 08c8dad8e399
child 15570 8d8c70b41bab
permissions -rw-r--r--
major code change: refute can now handle recursion and axiomatic type classes; 3-valued logic with two kinds of equality; some bugfixes
     1 (*  Title:      HOL/Tools/refute.ML
     2     ID:         $Id$
     3     Author:     Tjark Weber
     4     Copyright   2003-2005
     5 
     6 Finite model generation for HOL formulas, using a SAT solver.
     7 *)
     8 
     9 (* ------------------------------------------------------------------------- *)
    10 (* Declares the 'REFUTE' signature as well as a structure 'Refute'.          *)
    11 (* Documentation is available in the Isabelle/Isar theory 'HOL/Refute.thy'.  *)
    12 (* ------------------------------------------------------------------------- *)
    13 
    14 signature REFUTE =
    15 sig
    16 
    17 	exception REFUTE of string * string
    18 
    19 (* ------------------------------------------------------------------------- *)
    20 (* Model/interpretation related code (translation HOL -> propositional logic *)
    21 (* ------------------------------------------------------------------------- *)
    22 
    23 	type params
    24 	type interpretation
    25 	type model
    26 	type arguments
    27 
    28 	exception MAXVARS_EXCEEDED
    29 
    30 	val add_interpreter : string -> (theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option) -> theory -> theory
    31 	val add_printer     : string -> (theory -> model -> Term.term -> interpretation -> (int -> bool) -> Term.term option) -> theory -> theory
    32 
    33 	val interpret : theory -> model -> arguments -> Term.term -> (interpretation * model * arguments)
    34 
    35 	val print       : theory -> model -> Term.term -> interpretation -> (int -> bool) -> Term.term
    36 	val print_model : theory -> model -> (int -> bool) -> string
    37 
    38 (* ------------------------------------------------------------------------- *)
    39 (* Interface                                                                 *)
    40 (* ------------------------------------------------------------------------- *)
    41 
    42 	val set_default_param  : (string * string) -> theory -> theory
    43 	val get_default_param  : theory -> string -> string option
    44 	val get_default_params : theory -> (string * string) list
    45 	val actual_params      : theory -> (string * string) list -> params
    46 
    47 	val find_model : theory -> params -> Term.term -> bool -> unit
    48 
    49 	val satisfy_term   : theory -> (string * string) list -> Term.term -> unit  (* tries to find a model for a formula *)
    50 	val refute_term    : theory -> (string * string) list -> Term.term -> unit  (* tries to find a model that refutes a formula *)
    51 	val refute_subgoal : theory -> (string * string) list -> Thm.thm -> int -> unit
    52 
    53 	val setup : (theory -> theory) list
    54 end;
    55 
    56 structure Refute : REFUTE =
    57 struct
    58 
    59 	open PropLogic;
    60 
    61 	(* We use 'REFUTE' only for internal error conditions that should    *)
    62 	(* never occur in the first place (i.e. errors caused by bugs in our *)
    63 	(* code).  Otherwise (e.g. to indicate invalid input data) we use    *)
    64 	(* 'error'.                                                          *)
    65 	exception REFUTE of string * string;  (* ("in function", "cause") *)
    66 
    67 	(* should be raised by an interpreter when more variables would be *)
    68 	(* required than allowed by 'maxvars'                              *)
    69 	exception MAXVARS_EXCEEDED;
    70 
    71 (* ------------------------------------------------------------------------- *)
    72 (* TREES                                                                     *)
    73 (* ------------------------------------------------------------------------- *)
    74 
    75 (* ------------------------------------------------------------------------- *)
    76 (* tree: implements an arbitrarily (but finitely) branching tree as a list   *)
    77 (*       of (lists of ...) elements                                          *)
    78 (* ------------------------------------------------------------------------- *)
    79 
    80 	datatype 'a tree =
    81 		  Leaf of 'a
    82 		| Node of ('a tree) list;
    83 
    84 	(* ('a -> 'b) -> 'a tree -> 'b tree *)
    85 
    86 	fun tree_map f tr =
    87 		case tr of
    88 		  Leaf x  => Leaf (f x)
    89 		| Node xs => Node (map (tree_map f) xs);
    90 
    91 	(* ('a * 'b -> 'a) -> 'a * ('b tree) -> 'a *)
    92 
    93 	fun tree_foldl f =
    94 	let
    95 		fun itl (e, Leaf x)  = f(e,x)
    96 		  | itl (e, Node xs) = foldl (tree_foldl f) (e,xs)
    97 	in
    98 		itl
    99 	end;
   100 
   101 	(* 'a tree * 'b tree -> ('a * 'b) tree *)
   102 
   103 	fun tree_pair (t1,t2) =
   104 		case t1 of
   105 		  Leaf x =>
   106 			(case t2 of
   107 				  Leaf y => Leaf (x,y)
   108 				| Node _ => raise REFUTE ("tree_pair", "trees are of different height (second tree is higher)"))
   109 		| Node xs =>
   110 			(case t2 of
   111 				  (* '~~' will raise an exception if the number of branches in   *)
   112 				  (* both trees is different at the current node                 *)
   113 				  Node ys => Node (map tree_pair (xs ~~ ys))
   114 				| Leaf _  => raise REFUTE ("tree_pair", "trees are of different height (first tree is higher)"));
   115 
   116 (* ------------------------------------------------------------------------- *)
   117 (* params: parameters that control the translation into a propositional      *)
   118 (*         formula/model generation                                          *)
   119 (*                                                                           *)
   120 (* The following parameters are supported (and required (!), except for      *)
   121 (* "sizes"):                                                                 *)
   122 (*                                                                           *)
   123 (* Name          Type    Description                                         *)
   124 (*                                                                           *)
   125 (* "sizes"       (string * int) list                                         *)
   126 (*                       Size of ground types (e.g. 'a=2), or depth of IDTs. *)
   127 (* "minsize"     int     If >0, minimal size of each ground type/IDT depth.  *)
   128 (* "maxsize"     int     If >0, maximal size of each ground type/IDT depth.  *)
   129 (* "maxvars"     int     If >0, use at most 'maxvars' Boolean variables      *)
   130 (*                       when transforming the term into a propositional     *)
   131 (*                       formula.                                            *)
   132 (* "maxtime"     int     If >0, terminate after at most 'maxtime' seconds.   *)
   133 (* "satsolver"   string  SAT solver to be used.                              *)
   134 (* ------------------------------------------------------------------------- *)
   135 
   136 	type params =
   137 		{
   138 			sizes    : (string * int) list,
   139 			minsize  : int,
   140 			maxsize  : int,
   141 			maxvars  : int,
   142 			maxtime  : int,
   143 			satsolver: string
   144 		};
   145 
   146 (* ------------------------------------------------------------------------- *)
   147 (* interpretation: a term's interpretation is given by a variable of type    *)
   148 (*                 'interpretation'                                          *)
   149 (* ------------------------------------------------------------------------- *)
   150 
   151 	type interpretation =
   152 		prop_formula list tree;
   153 
   154 (* ------------------------------------------------------------------------- *)
   155 (* model: a model specifies the size of types and the interpretation of      *)
   156 (*        terms                                                              *)
   157 (* ------------------------------------------------------------------------- *)
   158 
   159 	type model =
   160 		(Term.typ * int) list * (Term.term * interpretation) list;
   161 
   162 (* ------------------------------------------------------------------------- *)
   163 (* arguments: additional arguments required during interpretation of terms   *)
   164 (* ------------------------------------------------------------------------- *)
   165 
   166 	type arguments =
   167 		{
   168 			maxvars   : int,   (* just passed unchanged from 'params' *)
   169 			def_eq    : bool,  (* whether to use 'make_equality' or 'make_def_equality' *)
   170 			(* the following may change during the translation *)
   171 			next_idx  : int,
   172 			bounds    : interpretation list,
   173 			wellformed: prop_formula
   174 		};
   175 
   176 
   177 	structure RefuteDataArgs =
   178 	struct
   179 		val name = "HOL/refute";
   180 		type T =
   181 			{interpreters: (string * (theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option)) list,
   182 			 printers: (string * (theory -> model -> Term.term -> interpretation -> (int -> bool) -> Term.term option)) list,
   183 			 parameters: string Symtab.table};
   184 		val empty = {interpreters = [], printers = [], parameters = Symtab.empty};
   185 		val copy = I;
   186 		val prep_ext = I;
   187 		fun merge
   188 			({interpreters = in1, printers = pr1, parameters = pa1},
   189 			 {interpreters = in2, printers = pr2, parameters = pa2}) =
   190 			{interpreters = rev (merge_alists (rev in1) (rev in2)),
   191 			 printers = rev (merge_alists (rev pr1) (rev pr2)),
   192 			 parameters = Symtab.merge (op=) (pa1, pa2)};
   193 		fun print sg {interpreters, printers, parameters} =
   194 			Pretty.writeln (Pretty.chunks
   195 				[Pretty.strs ("default parameters:" :: flat (map (fn (name,value) => [name, "=", value]) (Symtab.dest parameters))),
   196 				 Pretty.strs ("interpreters:" :: map fst interpreters),
   197 				 Pretty.strs ("printers:" :: map fst printers)]);
   198 	end;
   199 
   200 	structure RefuteData = TheoryDataFun(RefuteDataArgs);
   201 
   202 
   203 (* ------------------------------------------------------------------------- *)
   204 (* interpret: interprets the term 't' using a suitable interpreter; returns  *)
   205 (*            the interpretation and a (possibly extended) model that keeps  *)
   206 (*            track of the interpretation of subterms                        *)
   207 (* ------------------------------------------------------------------------- *)
   208 
   209 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) *)
   210 
   211 	fun interpret thy model args t =
   212 		(case get_first (fn (_, f) => f thy model args t) (#interpreters (RefuteData.get thy)) of
   213 		  NONE   => raise REFUTE ("interpret", "no interpreter for term " ^ quote (Sign.string_of_term (sign_of thy) t))
   214 		| SOME x => x);
   215 
   216 (* ------------------------------------------------------------------------- *)
   217 (* print: converts the constant denoted by the term 't' into a term using a  *)
   218 (*        suitable printer                                                   *)
   219 (* ------------------------------------------------------------------------- *)
   220 
   221 	(* theory -> model -> Term.term -> interpretation -> (int -> bool) -> Term.term *)
   222 
   223 	fun print thy model t intr assignment =
   224 		(case get_first (fn (_, f) => f thy model t intr assignment) (#printers (RefuteData.get thy)) of
   225 		  NONE   => raise REFUTE ("print", "no printer for term " ^ quote (Sign.string_of_term (sign_of thy) t))
   226 		| SOME x => x);
   227 
   228 (* ------------------------------------------------------------------------- *)
   229 (* print_model: turns the model into a string, using a fixed interpretation  *)
   230 (*              (given by an assignment for Boolean variables) and suitable  *)
   231 (*              printers                                                     *)
   232 (* ------------------------------------------------------------------------- *)
   233 
   234 	(* theory -> model -> (int -> bool) -> string *)
   235 
   236 	fun print_model thy model assignment =
   237 	let
   238 		val (typs, terms) = model
   239 		val typs_msg =
   240 			if null typs then
   241 				"empty universe (no type variables in term)\n"
   242 			else
   243 				"Size of types: " ^ commas (map (fn (T,i) => Sign.string_of_typ (sign_of thy) T ^ ": " ^ string_of_int i) typs) ^ "\n"
   244 		val show_consts_msg =
   245 			if not (!show_consts) andalso Library.exists (is_Const o fst) terms then
   246 				"set \"show_consts\" to show the interpretation of constants\n"
   247 			else
   248 				""
   249 		val terms_msg =
   250 			if null terms then
   251 				"empty interpretation (no free variables in term)\n"
   252 			else
   253 				space_implode "\n" (mapfilter (fn (t,intr) =>
   254 					(* print constants only if 'show_consts' is true *)
   255 					if (!show_consts) orelse not (is_Const t) then
   256 						SOME (Sign.string_of_term (sign_of thy) t ^ ": " ^ Sign.string_of_term (sign_of thy) (print thy model t intr assignment))
   257 					else
   258 						NONE) terms) ^ "\n"
   259 	in
   260 		typs_msg ^ show_consts_msg ^ terms_msg
   261 	end;
   262 
   263 
   264 (* ------------------------------------------------------------------------- *)
   265 (* PARAMETER MANAGEMENT                                                      *)
   266 (* ------------------------------------------------------------------------- *)
   267 
   268 	(* string -> (theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option) -> theory -> theory *)
   269 
   270 	fun add_interpreter name f thy =
   271 	let
   272 		val {interpreters, printers, parameters} = RefuteData.get thy
   273 	in
   274 		case assoc (interpreters, name) of
   275 		  NONE   => RefuteData.put {interpreters = (name, f) :: interpreters, printers = printers, parameters = parameters} thy
   276 		| SOME _ => error ("Interpreter " ^ name ^ " already declared")
   277 	end;
   278 
   279 	(* string -> (theory -> model -> Term.term -> interpretation -> (int -> bool) -> Term.term option) -> theory -> theory *)
   280 
   281 	fun add_printer name f thy =
   282 	let
   283 		val {interpreters, printers, parameters} = RefuteData.get thy
   284 	in
   285 		case assoc (printers, name) of
   286 		  NONE   => RefuteData.put {interpreters = interpreters, printers = (name, f) :: printers, parameters = parameters} thy
   287 		| SOME _ => error ("Printer " ^ name ^ " already declared")
   288 	end;
   289 
   290 (* ------------------------------------------------------------------------- *)
   291 (* set_default_param: stores the '(name, value)' pair in RefuteData's        *)
   292 (*                    parameter table                                        *)
   293 (* ------------------------------------------------------------------------- *)
   294 
   295 	(* (string * string) -> theory -> theory *)
   296 
   297 	fun set_default_param (name, value) thy =
   298 	let
   299 		val {interpreters, printers, parameters} = RefuteData.get thy
   300 	in
   301 		case Symtab.lookup (parameters, name) of
   302 		  NONE   => RefuteData.put
   303 			{interpreters = interpreters, printers = printers, parameters = Symtab.extend (parameters, [(name, value)])} thy
   304 		| SOME _ => RefuteData.put
   305 			{interpreters = interpreters, printers = printers, parameters = Symtab.update ((name, value), parameters)} thy
   306 	end;
   307 
   308 (* ------------------------------------------------------------------------- *)
   309 (* get_default_param: retrieves the value associated with 'name' from        *)
   310 (*                    RefuteData's parameter table                           *)
   311 (* ------------------------------------------------------------------------- *)
   312 
   313 	(* theory -> string -> string option *)
   314 
   315 	fun get_default_param thy name = Symtab.lookup ((#parameters o RefuteData.get) thy, name);
   316 
   317 (* ------------------------------------------------------------------------- *)
   318 (* get_default_params: returns a list of all '(name, value)' pairs that are  *)
   319 (*                     stored in RefuteData's parameter table                *)
   320 (* ------------------------------------------------------------------------- *)
   321 
   322 	(* theory -> (string * string) list *)
   323 
   324 	fun get_default_params thy = (Symtab.dest o #parameters o RefuteData.get) thy;
   325 
   326 (* ------------------------------------------------------------------------- *)
   327 (* actual_params: takes a (possibly empty) list 'params' of parameters that  *)
   328 (*      override the default parameters currently specified in 'thy', and    *)
   329 (*      returns a record that can be passed to 'find_model'.                 *)
   330 (* ------------------------------------------------------------------------- *)
   331 
   332 	(* theory -> (string * string) list -> params *)
   333 
   334 	fun actual_params thy override =
   335 	let
   336 		(* (string * string) list * string -> int *)
   337 		fun read_int (parms, name) =
   338 			case assoc_string (parms, name) of
   339 			  SOME s => (case Int.fromString s of
   340 				  SOME i => i
   341 				| NONE   => error ("parameter " ^ quote name ^ " (value is " ^ quote s ^ ") must be an integer value"))
   342 			| NONE   => error ("parameter " ^ quote name ^ " must be assigned a value")
   343 		(* (string * string) list * string -> string *)
   344 		fun read_string (parms, name) =
   345 			case assoc_string (parms, name) of
   346 			  SOME s => s
   347 			| NONE   => error ("parameter " ^ quote name ^ " must be assigned a value")
   348 		(* (string * string) list *)
   349 		val allparams = override @ (get_default_params thy)  (* 'override' first, defaults last *)
   350 		(* int *)
   351 		val minsize   = read_int (allparams, "minsize")
   352 		val maxsize   = read_int (allparams, "maxsize")
   353 		val maxvars   = read_int (allparams, "maxvars")
   354       val maxtime   = read_int (allparams, "maxtime")
   355 		(* string *)
   356 		val satsolver = read_string (allparams, "satsolver")
   357 		(* all remaining parameters of the form "string=int" are collected in  *)
   358 		(* 'sizes'                                                             *)
   359 		(* TODO: it is currently not possible to specify a size for a type     *)
   360 		(*       whose name is one of the other parameters (e.g. 'maxvars')    *)
   361 		(* (string * int) list *)
   362 		val sizes     = mapfilter
   363 			(fn (name,value) => (case Int.fromString value of SOME i => SOME (name, i) | NONE => NONE))
   364 			(filter (fn (name,_) => name<>"minsize" andalso name<>"maxsize" andalso name<>"maxvars" andalso name<>"maxtime" andalso name<>"satsolver")
   365 				allparams)
   366 	in
   367 		{sizes=sizes, minsize=minsize, maxsize=maxsize, maxvars=maxvars, maxtime=maxtime, satsolver=satsolver}
   368 	end;
   369 
   370 
   371 (* ------------------------------------------------------------------------- *)
   372 (* TRANSLATION HOL -> PROPOSITIONAL LOGIC, BOOLEAN ASSIGNMENT -> MODEL       *)
   373 (* ------------------------------------------------------------------------- *)
   374 
   375 (* ------------------------------------------------------------------------- *)
   376 (* typ_of_dtyp: converts a data type ('DatatypeAux.dtyp') into a type        *)
   377 (*              ('Term.typ'), given type parameters for the data type's type *)
   378 (*              arguments                                                    *)
   379 (* ------------------------------------------------------------------------- *)
   380 
   381 	(* DatatypeAux.descr -> (DatatypeAux.dtyp * Term.typ) list -> DatatypeAux.dtyp -> Term.typ *)
   382 
   383 	fun typ_of_dtyp descr typ_assoc (DatatypeAux.DtTFree a) =
   384 		(* replace a 'DtTFree' variable by the associated type *)
   385 		(the o assoc) (typ_assoc, DatatypeAux.DtTFree a)
   386 	  | typ_of_dtyp descr typ_assoc (DatatypeAux.DtType (s, ds)) =
   387 		Type (s, map (typ_of_dtyp descr typ_assoc) ds)
   388 	  | typ_of_dtyp descr typ_assoc (DatatypeAux.DtRec i) =
   389 		let
   390 			val (s, ds, _) = (the o assoc) (descr, i)
   391 		in
   392 			Type (s, map (typ_of_dtyp descr typ_assoc) ds)
   393 		end;
   394 
   395 (* ------------------------------------------------------------------------- *)
   396 (* collect_axioms: collects (monomorphic, universally quantified versions    *)
   397 (*                 of) all HOL axioms that are relevant w.r.t 't'            *)
   398 (* ------------------------------------------------------------------------- *)
   399 
   400 	(* Note: to make the collection of axioms more easily extensible, this    *)
   401 	(*       function could be based on user-supplied "axiom collectors",     *)
   402 	(*       similar to 'interpret'/interpreters or 'print'/printers          *)
   403 
   404 	(* theory -> Term.term -> Term.term list *)
   405 
   406 	(* Which axioms are "relevant" for a particular term/type goes hand in    *)
   407 	(* hand with the interpretation of that term/type by its interpreter (see *)
   408 	(* way below): if the interpretation respects an axiom anyway, the axiom  *)
   409 	(* does not need to be added as a constraint here.                        *)
   410 
   411 	(* When an axiom is added as relevant, further axioms may need to be      *)
   412 	(* added as well (e.g. when a constant is defined in terms of other       *)
   413 	(* constants).  To avoid infinite recursion (which should not happen for  *)
   414 	(* constants anyway, but it could happen for "typedef"-related axioms,    *)
   415 	(* since they contain the type again), we use an accumulator 'axs' and    *)
   416 	(* add a relevant axiom only if it is not in 'axs' yet.                   *)
   417 
   418 	fun collect_axioms thy t =
   419 	let
   420 		val _ = immediate_output "Adding axioms..."
   421 		(* (string * Term.term) list *)
   422 		val axioms = flat (map (Symtab.dest o #axioms o Theory.rep_theory) (thy :: Theory.ancestors_of thy))
   423 		(* string list *)
   424 		val rec_names = Symtab.foldl (fn (acc, (_, info)) =>
   425 			#rec_names info @ acc) ([], DatatypePackage.get_datatypes thy)
   426 		(* string list *)
   427 		val const_of_class_names = map Sign.const_of_class (Sign.classes (sign_of thy))
   428 		(* given a constant 's' of type 'T', which is a subterm of 't', where  *)
   429 		(* 't' has a (possibly) more general type, the schematic type          *)
   430 		(* variables in 't' are instantiated to match the type 'T' (may raise  *)
   431 		(* Type.TYPE_MATCH)                                                    *)
   432 		(* (string * Term.typ) * Term.term -> Term.term *)
   433 		fun specialize_type ((s, T), t) =
   434 		let
   435 			fun find_typeSubs (Const (s', T')) =
   436 				(if s=s' then
   437 					SOME (Type.typ_match (Sign.tsig_of (sign_of thy)) (Vartab.empty, (T', T))) handle Type.TYPE_MATCH => NONE
   438 				else
   439 					NONE)
   440 			  | find_typeSubs (Free _)           = NONE
   441 			  | find_typeSubs (Var _)            = NONE
   442 			  | find_typeSubs (Bound _)          = NONE
   443 			  | find_typeSubs (Abs (_, _, body)) = find_typeSubs body
   444 			  | find_typeSubs (t1 $ t2)          = (case find_typeSubs t1 of SOME x => SOME x | NONE => find_typeSubs t2)
   445 			val typeSubs = (case find_typeSubs t of
   446 				  SOME x => x
   447 				| NONE   => raise Type.TYPE_MATCH (* no match found - perhaps due to sort constraints *))
   448 		in
   449 			map_term_types
   450 				(map_type_tvar
   451 					(fn (v,_) =>
   452 						case Vartab.lookup (typeSubs, v) of
   453 						  NONE =>
   454 							(* schematic type variable not instantiated *)
   455 							raise REFUTE ("collect_axioms", "term " ^ Sign.string_of_term (sign_of thy) t ^ " still has a polymorphic type (after instantiating type of " ^ quote s ^ ")")
   456 						| SOME typ =>
   457 							typ))
   458 					t
   459 		end
   460 		(* applies a type substitution 'typeSubs' for all type variables in a  *)
   461 		(* term 't'                                                            *)
   462 		(* Term.typ Term.Vartab.table -> Term.term -> Term.term *)
   463 		fun monomorphic_term typeSubs t =
   464 			map_term_types (map_type_tvar
   465 				(fn (v, _) =>
   466 					case Vartab.lookup (typeSubs, v) of
   467 					  NONE =>
   468 						(* schematic type variable not instantiated *)
   469 						raise ERROR
   470 					| SOME typ =>
   471 						typ)) t
   472 		(* Term.term list * Term.typ -> Term.term list *)
   473 		fun collect_sort_axioms (axs, T) =
   474 			let
   475 				(* collect the axioms for a single 'class' (but not for its superclasses) *)
   476 				(* Term.term list * string -> Term.term list *)
   477 				fun collect_class_axioms (axs, class) =
   478 					let
   479 						(* obtain the axioms generated by the "axclass" command *)
   480 						(* (string * Term.term) list *)
   481 						val class_axioms             = filter (fn (s, _) => String.isPrefix (class ^ ".axioms_") s) axioms
   482 						(* replace the one schematic type variable in each axiom by the actual type 'T' *)
   483 						(* (string * Term.term) list *)
   484 						val monomorphic_class_axioms = map (fn (axname, ax) =>
   485 							let
   486 								val (idx, _) = (case term_tvars ax of
   487 									  [is] => is
   488 									| _    => raise REFUTE ("collect_axioms", "class axiom " ^ axname ^ " (" ^ Sign.string_of_term (sign_of thy) ax ^ ") does not contain exactly one type variable"))
   489 							in
   490 								(axname, monomorphic_term (Vartab.make [(idx, T)]) ax)
   491 							end) class_axioms
   492 						(* Term.term list * (string * Term.term) list -> Term.term list *)
   493 						fun collect_axiom (axs, (axname, ax)) =
   494 							if mem_term (ax, axs) then
   495 								axs
   496 							else (
   497 								immediate_output (" " ^ axname);
   498 								collect_term_axioms (ax :: axs, ax)
   499 							)
   500 					in
   501 						foldl collect_axiom (axs, monomorphic_class_axioms)
   502 					end
   503 				(* string list *)
   504 				val sort = (case T of
   505 					  TFree (_, sort) => sort
   506 					| TVar (_, sort)  => sort
   507 					| _               => raise REFUTE ("collect_axioms", "type " ^ Sign.string_of_typ (sign_of thy) T ^ " is not a variable"))
   508 				(* obtain all superclasses of classes in 'sort' *)
   509 				(* string list *)
   510 				val superclasses = Graph.all_succs ((#classes o Type.rep_tsig o Sign.tsig_of o sign_of) thy) sort
   511 			in
   512 				foldl collect_class_axioms (axs, superclasses)
   513 			end
   514 		(* Term.term list * Term.typ -> Term.term list *)
   515 		and collect_type_axioms (axs, T) =
   516 			case T of
   517 			(* simple types *)
   518 			  Type ("prop", [])      => axs
   519 			| Type ("fun", [T1, T2]) => collect_type_axioms (collect_type_axioms (axs, T1), T2)
   520 			| Type ("set", [T1])     => collect_type_axioms (axs, T1)
   521 			| Type ("itself", [T1])  => collect_type_axioms (axs, T1)  (* axiomatic type classes *)
   522 			| Type (s, Ts)           =>
   523 				let
   524 					(* look up the definition of a type, as created by "typedef" *)
   525 					(* (string * Term.term) list -> (string * Term.term) option *)
   526 					fun get_typedefn [] =
   527 						NONE
   528 					  | get_typedefn ((axname,ax)::axms) =
   529 						(let
   530 							(* Term.term -> Term.typ option *)
   531 							fun type_of_type_definition (Const (s', T')) =
   532 								if s'="Typedef.type_definition" then
   533 									SOME T'
   534 								else
   535 									NONE
   536 							  | type_of_type_definition (Free _)           = NONE
   537 							  | type_of_type_definition (Var _)            = NONE
   538 							  | type_of_type_definition (Bound _)          = NONE
   539 							  | type_of_type_definition (Abs (_, _, body)) = type_of_type_definition body
   540 							  | type_of_type_definition (t1 $ t2)          = (case type_of_type_definition t1 of SOME x => SOME x | NONE => type_of_type_definition t2)
   541 						in
   542 							case type_of_type_definition ax of
   543 							  SOME T' =>
   544 								let
   545 									val T''      = (domain_type o domain_type) T'
   546 									val typeSubs = Type.typ_match (Sign.tsig_of (sign_of thy)) (Vartab.empty, (T'', T))
   547 								in
   548 									SOME (axname, monomorphic_term typeSubs ax)
   549 								end
   550 							| NONE =>
   551 								get_typedefn axms
   552 						end
   553 						handle ERROR           => get_typedefn axms
   554 						     | MATCH           => get_typedefn axms
   555 						     | Type.TYPE_MATCH => get_typedefn axms)
   556 				in
   557 					case DatatypePackage.datatype_info thy s of
   558 					  SOME info =>  (* inductive datatype *)
   559 							(* only collect relevant type axioms for the argument types *)
   560 							foldl collect_type_axioms (axs, Ts)
   561 					| NONE =>
   562 						(case get_typedefn axioms of
   563 						  SOME (axname, ax) => 
   564 							if mem_term (ax, axs) then
   565 								(* only collect relevant type axioms for the argument types *)
   566 								foldl collect_type_axioms (axs, Ts)
   567 							else
   568 								(immediate_output (" " ^ axname);
   569 								collect_term_axioms (ax :: axs, ax))
   570 						| NONE =>
   571 							(* unspecified type, perhaps introduced with 'typedecl' *)
   572 							(* at least collect relevant type axioms for the argument types *)
   573 							foldl collect_type_axioms (axs, Ts))
   574 				end
   575 			| TFree _                => collect_sort_axioms (axs, T)  (* axiomatic type classes *)
   576 			| TVar _                 => collect_sort_axioms (axs, T)  (* axiomatic type classes *)
   577 		(* Term.term list * Term.term -> Term.term list *)
   578 		and collect_term_axioms (axs, t) =
   579 			case t of
   580 			(* Pure *)
   581 			  Const ("all", _)                => axs
   582 			| Const ("==", _)                 => axs
   583 			| Const ("==>", _)                => axs
   584 			| Const ("TYPE", T)               => collect_type_axioms (axs, T)  (* axiomatic type classes *)
   585 			(* HOL *)
   586 			| Const ("Trueprop", _)           => axs
   587 			| Const ("Not", _)                => axs
   588 			| Const ("True", _)               => axs  (* redundant, since 'True' is also an IDT constructor *)
   589 			| Const ("False", _)              => axs  (* redundant, since 'False' is also an IDT constructor *)
   590 			| Const ("arbitrary", T)          => collect_type_axioms (axs, T)
   591 			| Const ("The", T)                =>
   592 				let
   593 					val ax = specialize_type (("The", T), (the o assoc) (axioms, "HOL.the_eq_trivial"))
   594 				in
   595 					if mem_term (ax, axs) then
   596 						collect_type_axioms (axs, T)
   597 					else
   598 						(immediate_output " HOL.the_eq_trivial";
   599 						collect_term_axioms (ax :: axs, ax))
   600 				end
   601 			| Const ("Hilbert_Choice.Eps", T) =>
   602 				let
   603 					val ax = specialize_type (("Hilbert_Choice.Eps", T), (the o assoc) (axioms, "Hilbert_Choice.someI"))
   604 				in
   605 					if mem_term (ax, axs) then
   606 						collect_type_axioms (axs, T)
   607 					else
   608 						(immediate_output " Hilbert_Choice.someI";
   609 						collect_term_axioms (ax :: axs, ax))
   610 				end
   611 			| Const ("All", _) $ t1           => collect_term_axioms (axs, t1)
   612 			| Const ("Ex", _) $ t1            => collect_term_axioms (axs, t1)
   613 			| Const ("op =", T)               => collect_type_axioms (axs, T)
   614 			| Const ("op &", _)               => axs
   615 			| Const ("op |", _)               => axs
   616 			| Const ("op -->", _)             => axs
   617 			(* sets *)
   618 			| Const ("Collect", T)            => collect_type_axioms (axs, T)
   619 			| Const ("op :", T)               => collect_type_axioms (axs, T)
   620 			(* other optimizations *)
   621 			| Const ("Finite_Set.card", T)    => collect_type_axioms (axs, T)
   622 			| Const ("op <", T as Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("bool", [])])])) => collect_type_axioms (axs, T)
   623 			| Const ("op +", T as Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("nat", [])])])) => collect_type_axioms (axs, T)
   624 			| Const ("op -", T as Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("nat", [])])])) => collect_type_axioms (axs, T)
   625 			| Const ("op *", T as Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("nat", [])])])) => collect_type_axioms (axs, T)
   626 			(* simply-typed lambda calculus *)
   627 			| Const (s, T)                    =>
   628 				let
   629 					(* look up the definition of a constant, as created by "constdefs" *)
   630 					(* string -> Term.typ -> (string * Term.term) list -> (string * Term.term) option *)
   631 					fun get_defn [] =
   632 						NONE
   633 					  | get_defn ((axname, ax)::axms) =
   634 						(let
   635 							val (lhs, _) = Logic.dest_equals ax  (* equations only *)
   636 							val c        = head_of lhs
   637 							val (s', T') = dest_Const c
   638 						in
   639 							if s=s' then
   640 								let
   641 									val typeSubs = Type.typ_match (Sign.tsig_of (sign_of thy)) (Vartab.empty, (T', T))
   642 								in
   643 									SOME (axname, monomorphic_term typeSubs ax)
   644 								end
   645 							else
   646 								get_defn axms
   647 						end
   648 						handle ERROR           => get_defn axms
   649 						     | TERM _          => get_defn axms
   650 						     | Type.TYPE_MATCH => get_defn axms)
   651 					(* axiomatic type classes *)
   652 					(* unit -> bool *)
   653 					fun is_const_of_class () =
   654 						(* I'm not quite sure if checking the name 's' is sufficient, *)
   655 						(* or if we should also check the type 'T'                    *)
   656 						s mem const_of_class_names
   657 					(* inductive data types *)
   658 					(* unit -> bool *)
   659 					fun is_IDT_constructor () =
   660 						(case body_type T of
   661 						  Type (s', _) =>
   662 							(case DatatypePackage.constrs_of thy s' of
   663 							  SOME constrs =>
   664 								Library.exists (fn c =>
   665 									(case c of
   666 									  Const (cname, ctype) =>
   667 										cname = s andalso Type.typ_instance (Sign.tsig_of (sign_of thy)) (T, ctype)
   668 									| _ =>
   669 										raise REFUTE ("collect_axioms", "IDT constructor is not a constant")))
   670 									constrs
   671 							| NONE =>
   672 								false)
   673 						| _  =>
   674 							false)
   675 					(* unit -> bool *)
   676 					fun is_IDT_recursor () =
   677 						(* I'm not quite sure if checking the name 's' is sufficient, *)
   678 						(* or if we should also check the type 'T'                    *)
   679 						s mem rec_names
   680 				in
   681 					if is_const_of_class () then
   682 						(* axiomatic type classes: add "OFCLASS(?'a::c, c_class)" and *)
   683 						(* the introduction rule "class.intro" as axioms              *)
   684 						let
   685 							val class   = Sign.class_of_const s
   686 							val inclass = Logic.mk_inclass (TVar (("'a", 0), [class]), class)
   687 							(* Term.term option *)
   688 							val ofclass_ax = (SOME (specialize_type ((s, T), inclass)) handle Type.TYPE_MATCH => NONE)
   689 							val intro_ax   = (apsome (fn t => specialize_type ((s, T), t)) (assoc (axioms, class ^ ".intro")) handle Type.TYPE_MATCH => NONE)
   690 							val axs'       = (case ofclass_ax of NONE => axs | SOME ax => if mem_term (ax, axs) then
   691 									(* collect relevant type axioms *)
   692 									collect_type_axioms (axs, T)
   693 								else
   694 									(immediate_output (" " ^ Sign.string_of_term (sign_of thy) ax);
   695 									collect_term_axioms (ax :: axs, ax)))
   696 							val axs''      = (case intro_ax of NONE => axs' | SOME ax => if mem_term (ax, axs') then
   697 									(* collect relevant type axioms *)
   698 									collect_type_axioms (axs', T)
   699 								else
   700 									(immediate_output (" " ^ class ^ ".intro");
   701 									collect_term_axioms (ax :: axs', ax)))
   702 						in
   703 							axs''
   704 						end
   705 					else if is_IDT_constructor () then
   706 						(* only collect relevant type axioms *)
   707 						collect_type_axioms (axs, T)
   708 					else if is_IDT_recursor () then
   709 						(* only collect relevant type axioms *)
   710 						collect_type_axioms (axs, T)
   711 					else (
   712 						case get_defn axioms of
   713 						  SOME (axname, ax) => 
   714 							if mem_term (ax, axs) then
   715 								(* collect relevant type axioms *)
   716 								collect_type_axioms (axs, T)
   717 							else
   718 								(immediate_output (" " ^ axname);
   719 								collect_term_axioms (ax :: axs, ax))
   720 						| NONE =>
   721 							(* collect relevant type axioms *)
   722 							collect_type_axioms (axs, T)
   723 					)
   724 				end
   725 			| Free (_, T)                     => collect_type_axioms (axs, T)
   726 			| Var (_, T)                      => collect_type_axioms (axs, T)
   727 			| Bound i                         => axs
   728 			| Abs (_, T, body)                => collect_term_axioms (collect_type_axioms (axs, T), body)
   729 			| t1 $ t2                         => collect_term_axioms (collect_term_axioms (axs, t1), t2)
   730 		(* universal closure over schematic variables *)
   731 		(* Term.term -> Term.term *)
   732 		fun close_form t =
   733 		let
   734 			(* (Term.indexname * Term.typ) list *)
   735 			val vars = sort_wrt (fst o fst) (map dest_Var (term_vars t))
   736 		in
   737 			foldl
   738 				(fn (t', ((x, i), T)) => (Term.all T) $ Abs (x, T, abstract_over (Var((x, i), T), t')))
   739 				(t, vars)
   740 		end
   741 		(* Term.term list *)
   742 		val result = map close_form (collect_term_axioms ([], t))
   743 		val _ = writeln " ...done."
   744 	in
   745 		result
   746 	end;
   747 
   748 (* ------------------------------------------------------------------------- *)
   749 (* ground_types: collects all ground types in a term (including argument     *)
   750 (*               types of other types), suppressing duplicates.  Does not    *)
   751 (*               return function types, set types, non-recursive IDTs, or    *)
   752 (*               'propT'.  For IDTs, also the argument types of constructors *)
   753 (*               are considered.                                             *)
   754 (* ------------------------------------------------------------------------- *)
   755 
   756 	(* theory -> Term.term -> Term.typ list *)
   757 
   758 	fun ground_types thy t =
   759 	let
   760 		(* Term.typ * Term.typ list -> Term.typ list *)
   761 		fun collect_types (T, acc) =
   762 			if T mem acc then
   763 				acc  (* prevent infinite recursion (for IDTs) *)
   764 			else
   765 				(case T of
   766 				  Type ("fun", [T1, T2]) => collect_types (T1, collect_types (T2, acc))
   767 				| Type ("prop", [])      => acc
   768 				| Type ("set", [T1])     => collect_types (T1, acc)
   769 				| Type (s, Ts)           =>
   770 					(case DatatypePackage.datatype_info thy s of
   771 					  SOME info =>  (* inductive datatype *)
   772 						let
   773 							val index               = #index info
   774 							val descr               = #descr info
   775 							val (_, dtyps, constrs) = (the o assoc) (descr, index)
   776 							val typ_assoc           = dtyps ~~ Ts
   777 							(* sanity check: every element in 'dtyps' must be a 'DtTFree' *)
   778 							val _ = (if Library.exists (fn d =>
   779 									case d of DatatypeAux.DtTFree _ => false | _ => true) dtyps
   780 								then
   781 									raise REFUTE ("ground_types", "datatype argument (for type " ^ Sign.string_of_typ (sign_of thy) (Type (s, Ts)) ^ ") is not a variable")
   782 								else
   783 									())
   784 							(* if the current type is a recursive IDT (i.e. a depth is required), add it to 'acc' *)
   785 							val acc' = (if Library.exists (fn (_, ds) => Library.exists DatatypeAux.is_rec_type ds) constrs then
   786 									T ins acc
   787 								else
   788 									acc)
   789 							(* collect argument types *)
   790 							val acc_args = foldr collect_types (Ts, acc')
   791 							(* collect constructor types *)
   792 							val acc_constrs = foldr collect_types (flat (map (fn (_, ds) => map (typ_of_dtyp descr typ_assoc) ds) constrs), acc_args)
   793 						in
   794 							acc_constrs
   795 						end
   796 					| NONE =>  (* not an inductive datatype, e.g. defined via "typedef" or "typedecl" *)
   797 						T ins (foldr collect_types (Ts, acc)))
   798 				| TFree _                => T ins acc
   799 				| TVar _                 => T ins acc)
   800 	in
   801 		it_term_types collect_types (t, [])
   802 	end;
   803 
   804 (* ------------------------------------------------------------------------- *)
   805 (* string_of_typ: (rather naive) conversion from types to strings, used to   *)
   806 (*                look up the size of a type in 'sizes'.  Parameterized      *)
   807 (*                types with different parameters (e.g. "'a list" vs. "bool  *)
   808 (*                list") are identified.                                     *)
   809 (* ------------------------------------------------------------------------- *)
   810 
   811 	(* Term.typ -> string *)
   812 
   813 	fun string_of_typ (Type (s, _))     = s
   814 	  | string_of_typ (TFree (s, _))    = s
   815 	  | string_of_typ (TVar ((s,_), _)) = s;
   816 
   817 (* ------------------------------------------------------------------------- *)
   818 (* first_universe: returns the "first" (i.e. smallest) universe by assigning *)
   819 (*                 'minsize' to every type for which no size is specified in *)
   820 (*                 'sizes'                                                   *)
   821 (* ------------------------------------------------------------------------- *)
   822 
   823 	(* Term.typ list -> (string * int) list -> int -> (Term.typ * int) list *)
   824 
   825 	fun first_universe xs sizes minsize =
   826 	let
   827 		fun size_of_typ T =
   828 			case assoc (sizes, string_of_typ T) of
   829 			  SOME n => n
   830 			| NONE   => minsize
   831 	in
   832 		map (fn T => (T, size_of_typ T)) xs
   833 	end;
   834 
   835 (* ------------------------------------------------------------------------- *)
   836 (* next_universe: enumerates all universes (i.e. assignments of sizes to     *)
   837 (*                types), where the minimal size of a type is given by       *)
   838 (*                'minsize', the maximal size is given by 'maxsize', and a   *)
   839 (*                type may have a fixed size given in 'sizes'                *)
   840 (* ------------------------------------------------------------------------- *)
   841 
   842 	(* (Term.typ * int) list -> (string * int) list -> int -> int -> (Term.typ * int) list option *)
   843 
   844 	fun next_universe xs sizes minsize maxsize =
   845 	let
   846 		(* creates the "first" list of length 'len', where the sum of all list *)
   847 		(* elements is 'sum', and the length of the list is 'len'              *)
   848 		(* int -> int -> int -> int list option *)
   849 		fun make_first _ 0 sum =
   850 			if sum=0 then
   851 				SOME []
   852 			else
   853 				NONE
   854 		  | make_first max len sum =
   855 			if sum<=max orelse max<0 then
   856 				apsome (fn xs' => sum :: xs') (make_first max (len-1) 0)
   857 			else
   858 				apsome (fn xs' => max :: xs') (make_first max (len-1) (sum-max))
   859 		(* enumerates all int lists with a fixed length, where 0<=x<='max' for *)
   860 		(* all list elements x (unless 'max'<0)                                *)
   861 		(* int -> int -> int -> int list -> int list option *)
   862 		fun next max len sum [] =
   863 			NONE
   864 		  | next max len sum [x] =
   865 			(* we've reached the last list element, so there's no shift possible *)
   866 			make_first max (len+1) (sum+x+1)  (* increment 'sum' by 1 *)
   867 		  | next max len sum (x1::x2::xs) =
   868 			if x1>0 andalso (x2<max orelse max<0) then
   869 				(* we can shift *)
   870 				SOME (the (make_first max (len+1) (sum+x1-1)) @ (x2+1) :: xs)
   871 			else
   872 				(* continue search *)
   873 				next max (len+1) (sum+x1) (x2::xs)
   874 		(* only consider those types for which the size is not fixed *)
   875 		val mutables = filter (fn (T, _) => assoc (sizes, string_of_typ T) = NONE) xs
   876 		(* subtract 'minsize' from every size (will be added again at the end) *)
   877 		val diffs = map (fn (_, n) => n-minsize) mutables
   878 	in
   879 		case next (maxsize-minsize) 0 0 diffs of
   880 		  SOME diffs' =>
   881 			(* merge with those types for which the size is fixed *)
   882 			SOME (snd (foldl_map (fn (ds, (T, _)) =>
   883 				case assoc (sizes, string_of_typ T) of
   884 				  SOME n => (ds, (T, n))                    (* return the fixed size *)
   885 				| NONE   => (tl ds, (T, minsize + hd ds)))  (* consume the head of 'ds', add 'minsize' *)
   886 				(diffs', xs)))
   887 		| NONE =>
   888 			NONE
   889 	end;
   890 
   891 (* ------------------------------------------------------------------------- *)
   892 (* toTrue: converts the interpretation of a Boolean value to a propositional *)
   893 (*         formula that is true iff the interpretation denotes "true"        *)
   894 (* ------------------------------------------------------------------------- *)
   895 
   896 	(* interpretation -> prop_formula *)
   897 
   898 	fun toTrue (Leaf [fm,_]) = fm
   899 	  | toTrue _             = raise REFUTE ("toTrue", "interpretation does not denote a Boolean value");
   900 
   901 (* ------------------------------------------------------------------------- *)
   902 (* toFalse: converts the interpretation of a Boolean value to a              *)
   903 (*          propositional formula that is true iff the interpretation        *)
   904 (*          denotes "false"                                                  *)
   905 (* ------------------------------------------------------------------------- *)
   906 
   907 	(* interpretation -> prop_formula *)
   908 
   909 	fun toFalse (Leaf [_,fm]) = fm
   910 	  | toFalse _             = raise REFUTE ("toFalse", "interpretation does not denote a Boolean value");
   911 
   912 (* ------------------------------------------------------------------------- *)
   913 (* find_model: repeatedly calls 'interpret' with appropriate parameters,     *)
   914 (*             applies a SAT solver, and (in case a model is found) displays *)
   915 (*             the model to the user by calling 'print_model'                *)
   916 (* thy       : the current theory                                            *)
   917 (* {...}     : parameters that control the translation/model generation      *)
   918 (* t         : term to be translated into a propositional formula            *)
   919 (* negate    : if true, find a model that makes 't' false (rather than true) *)
   920 (* Note: exception 'TimeOut' is raised if the algorithm does not terminate   *)
   921 (*       within 'maxtime' seconds (if 'maxtime' >0)                          *)
   922 (* ------------------------------------------------------------------------- *)
   923 
   924 	(* theory -> params -> Term.term -> bool -> unit *)
   925 
   926 	fun find_model thy {sizes, minsize, maxsize, maxvars, maxtime, satsolver} t negate =
   927 	let
   928 		(* unit -> unit *)
   929 		fun wrapper () =
   930 		let
   931 			(* Term.term list *)
   932 			val axioms = collect_axioms thy t
   933 			(* Term.typ list *)
   934 			val types  = foldl (fn (acc, t') => acc union (ground_types thy t')) ([], t :: axioms)
   935 			val _      = writeln ("Ground types: "
   936 				^ (if null types then "none."
   937 				   else commas (map (Sign.string_of_typ (sign_of thy)) types)))
   938 			(* we can only consider fragments of recursive IDTs, so we issue a  *)
   939 			(* warning if the formula contains a recursive IDT                  *)
   940 			(* TODO: no warning needed for /positive/ occurrences of IDTs       *)
   941 			val _ = if Library.exists (fn
   942 				  Type (s, _) =>
   943 					(case DatatypePackage.datatype_info thy s of
   944 					  SOME info =>  (* inductive datatype *)
   945 						let
   946 							val index           = #index info
   947 							val descr           = #descr info
   948 							val (_, _, constrs) = (the o assoc) (descr, index)
   949 						in
   950 							(* recursive datatype? *)
   951 							Library.exists (fn (_, ds) => Library.exists DatatypeAux.is_rec_type ds) constrs
   952 						end
   953 					| NONE => false)
   954 				| _ => false) types then
   955 					warning "Term contains a recursive datatype; countermodel(s) may be spurious!"
   956 				else
   957 					()
   958 			(* (Term.typ * int) list -> unit *)
   959 			fun find_model_loop universe =
   960 			let
   961 				val init_model             = (universe, [])
   962 				val init_args              = {maxvars = maxvars, def_eq = false, next_idx = 1, bounds = [], wellformed = True}
   963 				val _                      = immediate_output ("Translating term (sizes: " ^ commas (map (fn (_, n) => string_of_int n) universe) ^ ") ...")
   964 				(* translate 't' and all axioms *)
   965 				val ((model, args), intrs) = foldl_map (fn ((m, a), t') =>
   966 					let
   967 						val (i, m', a') = interpret thy m a t'
   968 					in
   969 						(* set 'def_eq' to 'true' *)
   970 						((m', {maxvars = #maxvars a', def_eq = true, next_idx = #next_idx a', bounds = #bounds a', wellformed = #wellformed a'}), i)
   971 					end) ((init_model, init_args), t :: axioms)
   972 				(* make 't' either true or false, and make all axioms true, and *)
   973 				(* add the well-formedness side condition                       *)
   974 				val fm_t  = (if negate then toFalse else toTrue) (hd intrs)
   975 				val fm_ax = PropLogic.all (map toTrue (tl intrs))
   976 				val fm    = PropLogic.all [#wellformed args, fm_ax, fm_t]
   977 			in
   978 				immediate_output " invoking SAT solver...";
   979 				(case SatSolver.invoke_solver satsolver fm of
   980 				  SatSolver.SATISFIABLE assignment =>
   981 					(writeln " model found!";
   982 					writeln ("*** Model found: ***\n" ^ print_model thy model (fn i => case assignment i of SOME b => b | NONE => true)))
   983 				| SatSolver.UNSATISFIABLE =>
   984 					(immediate_output " no model exists.\n";
   985 					case next_universe universe sizes minsize maxsize of
   986 					  SOME universe' => find_model_loop universe'
   987 					| NONE           => writeln "Search terminated, no larger universe within the given limits.")
   988 				| SatSolver.UNKNOWN =>
   989 					(immediate_output " no model found.\n";
   990 					case next_universe universe sizes minsize maxsize of
   991 					  SOME universe' => find_model_loop universe'
   992 					| NONE           => writeln "Search terminated, no larger universe within the given limits.")
   993 				) handle SatSolver.NOT_CONFIGURED =>
   994 					error ("SAT solver " ^ quote satsolver ^ " is not configured.")
   995 			end handle MAXVARS_EXCEEDED =>
   996 				writeln ("\nSearch terminated, number of Boolean variables (" ^ string_of_int maxvars ^ " allowed) exceeded.")
   997 			in
   998 				find_model_loop (first_universe types sizes minsize)
   999 			end
  1000 		in
  1001 			(* some parameter sanity checks *)
  1002 			assert (minsize>=1) ("\"minsize\" is " ^ string_of_int minsize ^ ", must be at least 1");
  1003 			assert (maxsize>=1) ("\"maxsize\" is " ^ string_of_int maxsize ^ ", must be at least 1");
  1004 			assert (maxsize>=minsize) ("\"maxsize\" (=" ^ string_of_int maxsize ^ ") is less than \"minsize\" (=" ^ string_of_int minsize ^ ").");
  1005 			assert (maxvars>=0) ("\"maxvars\" is " ^ string_of_int maxvars ^ ", must be at least 0");
  1006 			assert (maxtime>=0) ("\"maxtime\" is " ^ string_of_int maxtime ^ ", must be at least 0");
  1007 			(* enter loop with or without time limit *)
  1008 			writeln ("Trying to find a model that " ^ (if negate then "refutes" else "satisfies") ^ ": "
  1009 				^ Sign.string_of_term (sign_of thy) t);
  1010 			if maxtime>0 then (
  1011 				TimeLimit.timeLimit (Time.fromSeconds (Int.toLarge maxtime))
  1012 					wrapper ()
  1013 				handle TimeLimit.TimeOut =>
  1014 					writeln ("\nSearch terminated, time limit ("
  1015 						^ string_of_int maxtime ^ (if maxtime=1 then " second" else " seconds")
  1016 						^ ") exceeded.")
  1017 			) else
  1018 				wrapper ()
  1019 		end;
  1020 
  1021 
  1022 (* ------------------------------------------------------------------------- *)
  1023 (* INTERFACE, PART 2: FINDING A MODEL                                        *)
  1024 (* ------------------------------------------------------------------------- *)
  1025 
  1026 (* ------------------------------------------------------------------------- *)
  1027 (* satisfy_term: calls 'find_model' to find a model that satisfies 't'       *)
  1028 (* params      : list of '(name, value)' pairs used to override default      *)
  1029 (*               parameters                                                  *)
  1030 (* ------------------------------------------------------------------------- *)
  1031 
  1032 	(* theory -> (string * string) list -> Term.term -> unit *)
  1033 
  1034 	fun satisfy_term thy params t =
  1035 		find_model thy (actual_params thy params) t false;
  1036 
  1037 (* ------------------------------------------------------------------------- *)
  1038 (* refute_term: calls 'find_model' to find a model that refutes 't'          *)
  1039 (* params     : list of '(name, value)' pairs used to override default       *)
  1040 (*              parameters                                                   *)
  1041 (* ------------------------------------------------------------------------- *)
  1042 
  1043 	(* theory -> (string * string) list -> Term.term -> unit *)
  1044 
  1045 	fun refute_term thy params t =
  1046 	let
  1047 		(* disallow schematic type variables, since we cannot properly negate  *)
  1048 		(* terms containing them (their logical meaning is that there EXISTS a *)
  1049 		(* type s.t. ...; to refute such a formula, we would have to show that *)
  1050 		(* for ALL types, not ...)                                             *)
  1051 		val _ = assert (null (term_tvars t)) "Term to be refuted contains schematic type variables"
  1052 		(* existential closure over schematic variables *)
  1053 		(* (Term.indexname * Term.typ) list *)
  1054 		val vars = sort_wrt (fst o fst) (map dest_Var (term_vars t))
  1055 		(* Term.term *)
  1056 		val ex_closure = foldl
  1057 			(fn (t', ((x,i),T)) => (HOLogic.exists_const T) $ Abs (x, T, abstract_over (Var((x,i),T), t')))
  1058 			(t, vars)
  1059 		(* If 't' is of type 'propT' (rather than 'boolT'), applying  *)
  1060 		(* 'HOLogic.exists_const' is not type-correct.  However, this *)
  1061 		(* is not really a problem as long as 'find_model' still      *)
  1062 		(* interprets the resulting term correctly, without checking  *)
  1063 		(* its type.                                                  *)
  1064 	in
  1065 		find_model thy (actual_params thy params) ex_closure true
  1066 	end;
  1067 
  1068 (* ------------------------------------------------------------------------- *)
  1069 (* refute_subgoal: calls 'refute_term' on a specific subgoal                 *)
  1070 (* params        : list of '(name, value)' pairs used to override default    *)
  1071 (*                 parameters                                                *)
  1072 (* subgoal       : 0-based index specifying the subgoal number               *)
  1073 (* ------------------------------------------------------------------------- *)
  1074 
  1075 	(* theory -> (string * string) list -> Thm.thm -> int -> unit *)
  1076 
  1077 	fun refute_subgoal thy params thm subgoal =
  1078 		refute_term thy params (nth_elem (subgoal, prems_of thm));
  1079 
  1080 
  1081 (* ------------------------------------------------------------------------- *)
  1082 (* INTERPRETERS: Auxiliary Functions                                         *)
  1083 (* ------------------------------------------------------------------------- *)
  1084 
  1085 (* ------------------------------------------------------------------------- *)
  1086 (* make_constants: returns all interpretations that have the same tree       *)
  1087 (*                 structure as 'intr', but consist of unit vectors with     *)
  1088 (*                 'True'/'False' only (no Boolean variables)                *)
  1089 (* ------------------------------------------------------------------------- *)
  1090 
  1091 	(* interpretation -> interpretation list *)
  1092 
  1093 	fun make_constants intr =
  1094 	let
  1095 		(* returns a list with all unit vectors of length n *)
  1096 		(* int -> interpretation list *)
  1097 		fun unit_vectors n =
  1098 		let
  1099 			(* returns the k-th unit vector of length n *)
  1100 			(* int * int -> interpretation *)
  1101 			fun unit_vector (k,n) =
  1102 				Leaf ((replicate (k-1) False) @ (True :: (replicate (n-k) False)))
  1103 			(* int -> interpretation list -> interpretation list *)
  1104 			fun unit_vectors_acc k vs =
  1105 				if k>n then [] else (unit_vector (k,n))::(unit_vectors_acc (k+1) vs)
  1106 		in
  1107 			unit_vectors_acc 1 []
  1108 		end
  1109 		(* concatenates 'x' with every list in 'xss', returning a new list of lists *)
  1110 		(* 'a -> 'a list list -> 'a list list *)
  1111 		fun cons_list x xss =
  1112 			map (fn xs => x::xs) xss
  1113 		(* returns a list of lists, each one consisting of n (possibly identical) elements from 'xs' *)
  1114 		(* int -> 'a list -> 'a list list *)
  1115 		fun pick_all 1 xs =
  1116 			map (fn x => [x]) xs
  1117 		  | pick_all n xs =
  1118 			let val rec_pick = pick_all (n-1) xs in
  1119 				foldl (fn (acc,x) => (cons_list x rec_pick) @ acc) ([],xs)
  1120 			end
  1121 	in
  1122 		case intr of
  1123 		  Leaf xs => unit_vectors (length xs)
  1124 		| Node xs => map (fn xs' => Node xs') (pick_all (length xs) (make_constants (hd xs)))
  1125 	end;
  1126 
  1127 (* ------------------------------------------------------------------------- *)
  1128 (* size_of_type: returns the number of constants in a type (i.e. 'length     *)
  1129 (*               (make_constants intr)', but implemented more efficiently)   *)
  1130 (* ------------------------------------------------------------------------- *)
  1131 
  1132 	(* interpretation -> int *)
  1133 
  1134 	fun size_of_type intr =
  1135 	let
  1136 		(* power(a,b) computes a^b, for a>=0, b>=0 *)
  1137 		(* int * int -> int *)
  1138 		fun power (a,0) = 1
  1139 		  | power (a,1) = a
  1140 		  | power (a,b) = let val ab = power(a, b div 2) in ab * ab * power(a, b mod 2) end
  1141 	in
  1142 		case intr of
  1143 		  Leaf xs => length xs
  1144 		| Node xs => power (size_of_type (hd xs), length xs)
  1145 	end;
  1146 
  1147 (* ------------------------------------------------------------------------- *)
  1148 (* TT/FF: interpretations that denote "true" or "false", respectively        *)
  1149 (* ------------------------------------------------------------------------- *)
  1150 
  1151 	(* interpretation *)
  1152 
  1153 	val TT = Leaf [True, False];
  1154 
  1155 	val FF = Leaf [False, True];
  1156 
  1157 (* ------------------------------------------------------------------------- *)
  1158 (* make_equality: returns an interpretation that denotes (extensional)       *)
  1159 (*                equality of two interpretations                            *)
  1160 (* - two interpretations are 'equal' iff they are both defined and denote    *)
  1161 (*   the same value                                                          *)
  1162 (* - two interpretations are 'not_equal' iff they are both defined at least  *)
  1163 (*   partially, and a defined part denotes different values                  *)
  1164 (* - a completely undefined interpretation is neither 'equal' nor            *)
  1165 (*   'not_equal' to another interpretation                                   *)
  1166 (* ------------------------------------------------------------------------- *)
  1167 
  1168 	(* We could in principle represent '=' on a type T by a particular        *)
  1169 	(* interpretation.  However, the size of that interpretation is quadratic *)
  1170 	(* in the size of T.  Therefore comparing the interpretations 'i1' and    *)
  1171 	(* 'i2' directly is more efficient than constructing the interpretation   *)
  1172 	(* for equality on T first, and "applying" this interpretation to 'i1'    *)
  1173 	(* and 'i2' in the usual way (cf. 'interpretation_apply') then.           *)
  1174 
  1175 	(* interpretation * interpretation -> interpretation *)
  1176 
  1177 	fun make_equality (i1, i2) =
  1178 	let
  1179 		(* interpretation * interpretation -> prop_formula *)
  1180 		fun equal (i1, i2) =
  1181 			(case i1 of
  1182 			  Leaf xs =>
  1183 				(case i2 of
  1184 				  Leaf ys => PropLogic.dot_product (xs, ys)  (* defined and equal *)
  1185 				| Node _  => raise REFUTE ("make_equality", "second interpretation is higher"))
  1186 			| Node xs =>
  1187 				(case i2 of
  1188 				  Leaf _  => raise REFUTE ("make_equality", "first interpretation is higher")
  1189 				| Node ys => PropLogic.all (map equal (xs ~~ ys))))
  1190 		(* interpretation * interpretation -> prop_formula *)
  1191 		fun not_equal (i1, i2) =
  1192 			(case i1 of
  1193 			  Leaf xs =>
  1194 				(case i2 of
  1195 				  Leaf ys => PropLogic.all ((PropLogic.exists xs) :: (PropLogic.exists ys) ::
  1196 					(map (fn (x,y) => SOr (SNot x, SNot y)) (xs ~~ ys)))  (* defined and not equal *)
  1197 				| Node _  => raise REFUTE ("make_equality", "second interpretation is higher"))
  1198 			| Node xs =>
  1199 				(case i2 of
  1200 				  Leaf _  => raise REFUTE ("make_equality", "first interpretation is higher")
  1201 				| Node ys => PropLogic.exists (map not_equal (xs ~~ ys))))
  1202 	in
  1203 		(* a value may be undefined; therefore 'not_equal' is not just the     *)
  1204 		(* negation of 'equal'                                                 *)
  1205 		Leaf [equal (i1, i2), not_equal (i1, i2)]
  1206 	end;
  1207 
  1208 (* ------------------------------------------------------------------------- *)
  1209 (* make_def_equality: returns an interpretation that denotes (extensional)   *)
  1210 (*                    equality of two interpretations                        *)
  1211 (* This function treats undefined/partially defined interpretations          *)
  1212 (* different from 'make_equality': two undefined interpretations are         *)
  1213 (* considered equal, while a defined interpretation is considered not equal  *)
  1214 (* to an undefined interpretation.                                           *)
  1215 (* ------------------------------------------------------------------------- *)
  1216 
  1217 	(* interpretation * interpretation -> interpretation *)
  1218 
  1219 	fun make_def_equality (i1, i2) =
  1220 	let
  1221 		(* interpretation * interpretation -> prop_formula *)
  1222 		fun equal (i1, i2) =
  1223 			(case i1 of
  1224 			  Leaf xs =>
  1225 				(case i2 of
  1226 				  Leaf ys => SOr (PropLogic.dot_product (xs, ys),  (* defined and equal, or both undefined *)
  1227 					SAnd (PropLogic.all (map SNot xs), PropLogic.all (map SNot ys)))
  1228 				| Node _  => raise REFUTE ("make_def_equality", "second interpretation is higher"))
  1229 			| Node xs =>
  1230 				(case i2 of
  1231 				  Leaf _  => raise REFUTE ("make_def_equality", "first interpretation is higher")
  1232 				| Node ys => PropLogic.all (map equal (xs ~~ ys))))
  1233 		(* interpretation *)
  1234 		val eq = equal (i1, i2)
  1235 	in
  1236 		Leaf [eq, SNot eq]
  1237 	end;
  1238 
  1239 (* ------------------------------------------------------------------------- *)
  1240 (* interpretation_apply: returns an interpretation that denotes the result   *)
  1241 (*                       of applying the function denoted by 'i2' to the     *)
  1242 (*                       argument denoted by 'i2'                            *)
  1243 (* ------------------------------------------------------------------------- *)
  1244 
  1245 	(* interpretation * interpretation -> interpretation *)
  1246 
  1247 	fun interpretation_apply (i1, i2) =
  1248 	let
  1249 		(* interpretation * interpretation -> interpretation *)
  1250 		fun interpretation_disjunction (tr1,tr2) =
  1251 			tree_map (fn (xs,ys) => map (fn (x,y) => SOr(x,y)) (xs ~~ ys)) (tree_pair (tr1,tr2))
  1252 		(* prop_formula * interpretation -> interpretation *)
  1253 		fun prop_formula_times_interpretation (fm,tr) =
  1254 			tree_map (map (fn x => SAnd (fm,x))) tr
  1255 		(* prop_formula list * interpretation list -> interpretation *)
  1256 		fun prop_formula_list_dot_product_interpretation_list ([fm],[tr]) =
  1257 			prop_formula_times_interpretation (fm,tr)
  1258 		  | prop_formula_list_dot_product_interpretation_list (fm::fms,tr::trees) =
  1259 			interpretation_disjunction (prop_formula_times_interpretation (fm,tr), prop_formula_list_dot_product_interpretation_list (fms,trees))
  1260 		  | prop_formula_list_dot_product_interpretation_list (_,_) =
  1261 			raise REFUTE ("interpretation_apply", "empty list (in dot product)")
  1262 		(* concatenates 'x' with every list in 'xss', returning a new list of lists *)
  1263 		(* 'a -> 'a list list -> 'a list list *)
  1264 		fun cons_list x xss =
  1265 			map (fn xs => x::xs) xss
  1266 		(* returns a list of lists, each one consisting of one element from each element of 'xss' *)
  1267 		(* 'a list list -> 'a list list *)
  1268 		fun pick_all [xs] =
  1269 			map (fn x => [x]) xs
  1270 		  | pick_all (xs::xss) =
  1271 			let val rec_pick = pick_all xss in
  1272 				foldl (fn (acc,x) => (cons_list x rec_pick) @ acc) ([],xs)
  1273 			end
  1274 		  | pick_all _ =
  1275 			raise REFUTE ("interpretation_apply", "empty list (in pick_all)")
  1276 		(* interpretation -> prop_formula list *)
  1277 		fun interpretation_to_prop_formula_list (Leaf xs) =
  1278 			xs
  1279 		  | interpretation_to_prop_formula_list (Node trees) =
  1280 			map PropLogic.all (pick_all (map interpretation_to_prop_formula_list trees))
  1281 	in
  1282 		case i1 of
  1283 		  Leaf _ =>
  1284 			raise REFUTE ("interpretation_apply", "first interpretation is a leaf")
  1285 		| Node xs =>
  1286 			prop_formula_list_dot_product_interpretation_list (interpretation_to_prop_formula_list i2, xs)
  1287 	end;
  1288 
  1289 (* ------------------------------------------------------------------------- *)
  1290 (* eta_expand: eta-expands a term 't' by adding 'i' lambda abstractions      *)
  1291 (* ------------------------------------------------------------------------- *)
  1292 
  1293 	(* Term.term -> int -> Term.term *)
  1294 
  1295 	fun eta_expand t i =
  1296 	let
  1297 		val Ts = binder_types (fastype_of t)
  1298 	in
  1299 		foldr (fn (T, t) => Abs ("<eta_expand>", T, t))
  1300 			(take (i, Ts), list_comb (t, map Bound (i-1 downto 0)))
  1301 	end;
  1302 
  1303 (* ------------------------------------------------------------------------- *)
  1304 (* sum: returns the sum of a list 'xs' of integers                           *)
  1305 (* ------------------------------------------------------------------------- *)
  1306 
  1307 	(* int list -> int *)
  1308 
  1309 	fun sum xs = foldl op+ (0, xs);
  1310 
  1311 (* ------------------------------------------------------------------------- *)
  1312 (* product: returns the product of a list 'xs' of integers                   *)
  1313 (* ------------------------------------------------------------------------- *)
  1314 
  1315 	(* int list -> int *)
  1316 
  1317 	fun product xs = foldl op* (1, xs);
  1318 
  1319 (* ------------------------------------------------------------------------- *)
  1320 (* size_of_dtyp: the size of (an initial fragment of) an inductive data type *)
  1321 (*               is the sum (over its constructors) of the product (over     *)
  1322 (*               their arguments) of the size of the argument types          *)
  1323 (* ------------------------------------------------------------------------- *)
  1324 
  1325 	(* theory -> (Term.typ * int) list -> DatatypeAux.descr -> (DatatypeAux.dtyp * Term.typ) list -> (string * DatatypeAux.dtyp list) list -> int *)
  1326 
  1327 	fun size_of_dtyp thy typ_sizes descr typ_assoc constructors =
  1328 		sum (map (fn (_, dtyps) =>
  1329 			product (map (fn dtyp =>
  1330 				let
  1331 					val T         = typ_of_dtyp descr typ_assoc dtyp
  1332 					val (i, _, _) = interpret thy (typ_sizes, []) {maxvars=0, def_eq = false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  1333 				in
  1334 					size_of_type i
  1335 				end) dtyps)) constructors);
  1336 
  1337 
  1338 (* ------------------------------------------------------------------------- *)
  1339 (* INTERPRETERS: Actual Interpreters                                         *)
  1340 (* ------------------------------------------------------------------------- *)
  1341 
  1342 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1343 
  1344 	(* simply typed lambda calculus: Isabelle's basic term syntax, with type  *)
  1345 	(* variables, function types, and propT                                   *)
  1346 
  1347 	fun stlc_interpreter thy model args t =
  1348 	let
  1349 		val (typs, terms)                                   = model
  1350 		val {maxvars, def_eq, next_idx, bounds, wellformed} = args
  1351 		(* Term.typ -> (interpretation * model * arguments) option *)
  1352 		fun interpret_groundterm T =
  1353 		let
  1354 			(* unit -> (interpretation * model * arguments) option *)
  1355 			fun interpret_groundtype () =
  1356 			let
  1357 				val size = (if T = Term.propT then 2 else (the o assoc) (typs, T))                    (* the model MUST specify a size for ground types *)
  1358 				val next = next_idx+size
  1359 				val _    = (if next-1>maxvars andalso maxvars>0 then raise MAXVARS_EXCEEDED else ())  (* check if 'maxvars' is large enough *)
  1360 				(* prop_formula list *)
  1361 				val fms  = map BoolVar (next_idx upto (next_idx+size-1))
  1362 				(* interpretation *)
  1363 				val intr = Leaf fms
  1364 				(* prop_formula list -> prop_formula *)
  1365 				fun one_of_two_false []      = True
  1366 				  | one_of_two_false (x::xs) = SAnd (PropLogic.all (map (fn x' => SOr (SNot x, SNot x')) xs), one_of_two_false xs)
  1367 				(* prop_formula *)
  1368 				val wf   = one_of_two_false fms
  1369 			in
  1370 				(* extend the model, increase 'next_idx', add well-formedness condition *)
  1371 				SOME (intr, (typs, (t, intr)::terms), {maxvars = maxvars, def_eq = def_eq, next_idx = next, bounds = bounds, wellformed = SAnd (wellformed, wf)})
  1372 			end
  1373 		in
  1374 			case T of
  1375 			  Type ("fun", [T1, T2]) =>
  1376 				let
  1377 					(* we create 'size_of_type (interpret (... T1))' different copies *)
  1378 					(* of the interpretation for 'T2', which are then combined into a *)
  1379 					(* single new interpretation                                      *)
  1380 					val (i1, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T1))
  1381 					(* make fresh copies, with different variable indices *)
  1382 					(* 'idx': next variable index                         *)
  1383 					(* 'n'  : number of copies                            *)
  1384 					(* int -> int -> (int * interpretation list * prop_formula *)
  1385 					fun make_copies idx 0 =
  1386 						(idx, [], True)
  1387 					  | make_copies idx n =
  1388 						let
  1389 							val (copy, _, new_args) = interpret thy (typs, []) {maxvars = maxvars, def_eq = false, next_idx = idx, bounds = [], wellformed = True} (Free ("dummy", T2))
  1390 							val (idx', copies, wf') = make_copies (#next_idx new_args) (n-1)
  1391 						in
  1392 							(idx', copy :: copies, SAnd (#wellformed new_args, wf'))
  1393 						end
  1394 					val (next, copies, wf) = make_copies next_idx (size_of_type i1)
  1395 					(* combine copies into a single interpretation *)
  1396 					val intr = Node copies
  1397 				in
  1398 					(* extend the model, increase 'next_idx', add well-formedness condition *)
  1399 					SOME (intr, (typs, (t, intr)::terms), {maxvars = maxvars, def_eq = def_eq, next_idx = next, bounds = bounds, wellformed = SAnd (wellformed, wf)})
  1400 				end
  1401 			| Type _  => interpret_groundtype ()
  1402 			| TFree _ => interpret_groundtype ()
  1403 			| TVar  _ => interpret_groundtype ()
  1404 		end
  1405 	in
  1406 		case assoc (terms, t) of
  1407 		  SOME intr =>
  1408 			(* return an existing interpretation *)
  1409 			SOME (intr, model, args)
  1410 		| NONE =>
  1411 			(case t of
  1412 			  Const (_, T)     =>
  1413 				interpret_groundterm T
  1414 			| Free (_, T)      =>
  1415 				interpret_groundterm T
  1416 			| Var (_, T)       =>
  1417 				interpret_groundterm T
  1418 			| Bound i          =>
  1419 				SOME (nth_elem (i, #bounds args), model, args)
  1420 			| Abs (x, T, body) =>
  1421 				let
  1422 					(* create all constants of type 'T' *)
  1423 					val (i, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  1424 					val constants = make_constants i
  1425 					(* interpret the 'body' separately for each constant *)
  1426 					val ((model', args'), bodies) = foldl_map
  1427 						(fn ((m, a), c) =>
  1428 							let
  1429 								(* add 'c' to 'bounds' *)
  1430 								val (i', m', a') = interpret thy m {maxvars = #maxvars a, def_eq = #def_eq a, next_idx = #next_idx a, bounds = (c :: #bounds a), wellformed = #wellformed a} body
  1431 							in
  1432 								(* keep the new model m' and 'next_idx' and 'wellformed', but use old 'bounds' *)
  1433 								((m', {maxvars = maxvars, def_eq = def_eq, next_idx = #next_idx a', bounds = bounds, wellformed = #wellformed a'}), i')
  1434 							end)
  1435 						((model, args), constants)
  1436 				in
  1437 					SOME (Node bodies, model', args')
  1438 				end
  1439 			| t1 $ t2          =>
  1440 				let
  1441 					(* interpret 't1' and 't2' separately *)
  1442 					val (intr1, model1, args1) = interpret thy model args t1
  1443 					val (intr2, model2, args2) = interpret thy model1 args1 t2
  1444 				in
  1445 					SOME (interpretation_apply (intr1, intr2), model2, args2)
  1446 				end)
  1447 	end;
  1448 
  1449 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1450 
  1451 	fun Pure_interpreter thy model args t =
  1452 		case t of
  1453 		  Const ("all", _) $ t1 =>  (* in the meta-logic, 'all' MUST be followed by an argument term *)
  1454 			let
  1455 				val (i, m, a) = interpret thy model args t1
  1456 			in
  1457 				case i of
  1458 				  Node xs =>
  1459 					let
  1460 						val fmTrue  = PropLogic.all (map toTrue xs)
  1461 						val fmFalse = PropLogic.exists (map toFalse xs)
  1462 					in
  1463 						SOME (Leaf [fmTrue, fmFalse], m, a)
  1464 					end
  1465 				| _ =>
  1466 					raise REFUTE ("Pure_interpreter", "\"all\" is not followed by a function")
  1467 			end
  1468 		| Const ("==", _) $ t1 $ t2 =>
  1469 			let
  1470 				val (i1, m1, a1) = interpret thy model args t1
  1471 				val (i2, m2, a2) = interpret thy m1 a1 t2
  1472 			in
  1473 				(* we use either 'make_def_equality' or 'make_equality' *)
  1474 				SOME ((if #def_eq args then make_def_equality else make_equality) (i1, i2), m2, a2)
  1475 			end
  1476 		| Const ("==>", _) =>  (* simpler than translating 'Const ("==>", _) $ t1 $ t2' *)
  1477 			SOME (Node [Node [TT, FF], Node [TT, TT]], model, args)
  1478 		| _ => NONE;
  1479 
  1480 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1481 
  1482 	fun HOLogic_interpreter thy model args t =
  1483 	(* ------------------------------------------------------------------------- *)
  1484 	(* Providing interpretations directly is more efficient than unfolding the   *)
  1485 	(* logical constants.  In HOL however, logical constants can themselves be   *)
  1486 	(* arguments.  "All" and "Ex" are then translated just like any other        *)
  1487 	(* constant, with the relevant axiom being added by 'collect_axioms'.        *)
  1488 	(* ------------------------------------------------------------------------- *)
  1489 		case t of
  1490 		  Const ("Trueprop", _) =>
  1491 			SOME (Node [TT, FF], model, args)
  1492 		| Const ("Not", _) =>
  1493 			SOME (Node [FF, TT], model, args)
  1494 		| Const ("True", _) =>  (* redundant, since 'True' is also an IDT constructor *)
  1495 			SOME (TT, model, args)
  1496 		| Const ("False", _) =>  (* redundant, since 'False' is also an IDT constructor *)
  1497 			SOME (FF, model, args)
  1498 		| Const ("All", _) $ t1 =>
  1499 		(* if "All" occurs without an argument (i.e. as argument to a higher-order *)
  1500 		(* function or predicate), it is handled by the 'stlc_interpreter' (i.e.   *)
  1501 		(* by unfolding its definition)                                            *)
  1502 			let
  1503 				val (i, m, a) = interpret thy model args t1
  1504 			in
  1505 				case i of
  1506 				  Node xs =>
  1507 					let
  1508 						val fmTrue  = PropLogic.all (map toTrue xs)
  1509 						val fmFalse = PropLogic.exists (map toFalse xs)
  1510 					in
  1511 						SOME (Leaf [fmTrue, fmFalse], m, a)
  1512 					end
  1513 				| _ =>
  1514 					raise REFUTE ("HOLogic_interpreter", "\"All\" is followed by a non-function")
  1515 			end
  1516 		| Const ("Ex", _) $ t1 =>
  1517 		(* if "Ex" occurs without an argument (i.e. as argument to a higher-order  *)
  1518 		(* function or predicate), it is handled by the 'stlc_interpreter' (i.e.   *)
  1519 		(* by unfolding its definition)                                            *)
  1520 			let
  1521 				val (i, m, a) = interpret thy model args t1
  1522 			in
  1523 				case i of
  1524 				  Node xs =>
  1525 					let
  1526 						val fmTrue  = PropLogic.exists (map toTrue xs)
  1527 						val fmFalse = PropLogic.all (map toFalse xs)
  1528 					in
  1529 						SOME (Leaf [fmTrue, fmFalse], m, a)
  1530 					end
  1531 				| _ =>
  1532 					raise REFUTE ("HOLogic_interpreter", "\"Ex\" is followed by a non-function")
  1533 			end
  1534 		| Const ("op =", _) $ t1 $ t2 =>
  1535 			let
  1536 				val (i1, m1, a1) = interpret thy model args t1
  1537 				val (i2, m2, a2) = interpret thy m1 a1 t2
  1538 			in
  1539 				SOME (make_equality (i1, i2), m2, a2)
  1540 			end
  1541 		| Const ("op =", _) $ t1 =>
  1542 			SOME (interpret thy model args (eta_expand t 1))
  1543 		| Const ("op =", _) =>
  1544 			SOME (interpret thy model args (eta_expand t 2))
  1545 		| Const ("op &", _) $ t1 $ t2 =>
  1546 			(* 3-valued logic *)
  1547 			let
  1548 				val (i1, m1, a1) = interpret thy model args t1
  1549 				val (i2, m2, a2) = interpret thy m1 a1 t2
  1550 				val fmTrue       = PropLogic.SAnd (toTrue i1, toTrue i2)
  1551 				val fmFalse      = PropLogic.SOr (toFalse i1, toFalse i2)
  1552 			in
  1553 				SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1554 			end
  1555 		| Const ("op &", _) $ t1 =>
  1556 			SOME (interpret thy model args (eta_expand t 1))
  1557 		| Const ("op &", _) =>
  1558 			SOME (interpret thy model args (eta_expand t 2))
  1559 			(* SOME (Node [Node [TT, FF], Node [FF, FF]], model, args) *)
  1560 		| Const ("op |", _) $ t1 $ t2 =>
  1561 			(* 3-valued logic *)
  1562 			let
  1563 				val (i1, m1, a1) = interpret thy model args t1
  1564 				val (i2, m2, a2) = interpret thy m1 a1 t2
  1565 				val fmTrue       = PropLogic.SOr (toTrue i1, toTrue i2)
  1566 				val fmFalse      = PropLogic.SAnd (toFalse i1, toFalse i2)
  1567 			in
  1568 				SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1569 			end
  1570 		| Const ("op |", _) $ t1 =>
  1571 			SOME (interpret thy model args (eta_expand t 1))
  1572 		| Const ("op |", _) =>
  1573 			SOME (interpret thy model args (eta_expand t 2))
  1574 			(* SOME (Node [Node [TT, TT], Node [TT, FF]], model, args) *)
  1575 		| Const ("op -->", _) $ t1 $ t2 =>
  1576 			(* 3-valued logic *)
  1577 			let
  1578 				val (i1, m1, a1) = interpret thy model args t1
  1579 				val (i2, m2, a2) = interpret thy m1 a1 t2
  1580 				val fmTrue       = PropLogic.SOr (toFalse i1, toTrue i2)
  1581 				val fmFalse      = PropLogic.SAnd (toTrue i1, toFalse i2)
  1582 			in
  1583 				SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1584 			end
  1585 		| Const ("op -->", _) =>
  1586 			(* SOME (Node [Node [TT, FF], Node [TT, TT]], model, args) *)
  1587 			SOME (interpret thy model args (eta_expand t 2))
  1588 		| _ => NONE;
  1589 
  1590 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1591 
  1592 	fun set_interpreter thy model args t =
  1593 	(* "T set" is isomorphic to "T --> bool" *)
  1594 	let
  1595 		val (typs, terms) = model
  1596 	in
  1597 		case assoc (terms, t) of
  1598 		  SOME intr =>
  1599 			(* return an existing interpretation *)
  1600 			SOME (intr, model, args)
  1601 		| NONE =>
  1602 			(case t of
  1603 			  Free (x, Type ("set", [T])) =>
  1604 				let
  1605 					val (intr, _, args') = interpret thy (typs, []) args (Free (x, T --> HOLogic.boolT))
  1606 				in
  1607 					SOME (intr, (typs, (t, intr)::terms), args')
  1608 				end
  1609 			| Var ((x,i), Type ("set", [T])) =>
  1610 				let
  1611 					val (intr, _, args') = interpret thy (typs, []) args (Var ((x,i), T --> HOLogic.boolT))
  1612 				in
  1613 					SOME (intr, (typs, (t, intr)::terms), args')
  1614 				end
  1615 			| Const (s, Type ("set", [T])) =>
  1616 				let
  1617 					val (intr, _, args') = interpret thy (typs, []) args (Const (s, T --> HOLogic.boolT))
  1618 				in
  1619 					SOME (intr, (typs, (t, intr)::terms), args')
  1620 				end
  1621 			(* 'Collect' == identity *)
  1622 			| Const ("Collect", _) $ t1 =>
  1623 				SOME (interpret thy model args t1)
  1624 			| Const ("Collect", _) =>
  1625 				SOME (interpret thy model args (eta_expand t 1))
  1626 			(* 'op :' == application *)
  1627 			| Const ("op :", _) $ t1 $ t2 =>
  1628 				SOME (interpret thy model args (t2 $ t1))
  1629 			| Const ("op :", _) $ t1 =>
  1630 				SOME (interpret thy model args (eta_expand t 1))
  1631 			| Const ("op :", _) =>
  1632 				SOME (interpret thy model args (eta_expand t 2))
  1633 			| _ => NONE)
  1634 	end;
  1635 
  1636 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1637 
  1638 	(* interprets variables and constants whose type is an IDT; constructors of  *)
  1639 	(* IDTs are properly interpreted by 'IDT_constructor_interpreter' however    *)
  1640 
  1641 	fun IDT_interpreter thy model args t =
  1642 	let
  1643 		val (typs, terms) = model
  1644 		(* Term.typ -> (interpretation * model * arguments) option *)
  1645 		fun interpret_term (Type (s, Ts)) =
  1646 			(case DatatypePackage.datatype_info thy s of
  1647 			  SOME info =>  (* inductive datatype *)
  1648 				let
  1649 					(* int option -- only recursive IDTs have an associated depth *)
  1650 					val depth = assoc (typs, Type (s, Ts))
  1651 				in
  1652 					if depth = (SOME 0) then  (* termination condition to avoid infinite recursion *)
  1653 						(* return a leaf of size 0 *)
  1654 						SOME (Leaf [], model, args)
  1655 					else
  1656 						let
  1657 							val index               = #index info
  1658 							val descr               = #descr info
  1659 							val (_, dtyps, constrs) = (the o assoc) (descr, index)
  1660 							val typ_assoc           = dtyps ~~ Ts
  1661 							(* sanity check: every element in 'dtyps' must be a 'DtTFree' *)
  1662 							val _ = (if Library.exists (fn d =>
  1663 									case d of DatatypeAux.DtTFree _ => false | _ => true) dtyps
  1664 								then
  1665 									raise REFUTE ("IDT_interpreter", "datatype argument (for type " ^ Sign.string_of_typ (sign_of thy) (Type (s, Ts)) ^ ") is not a variable")
  1666 								else
  1667 									())
  1668 							(* if the model specifies a depth for the current type, decrement it to avoid infinite recursion *)
  1669 							val typs'    = (case depth of NONE => typs | SOME n => overwrite (typs, (Type (s, Ts), n-1)))
  1670 							(* recursively compute the size of the datatype *)
  1671 							val size     = size_of_dtyp thy typs' descr typ_assoc constrs
  1672 							val next_idx = #next_idx args
  1673 							val next     = next_idx+size
  1674 							val _        = (if next-1>(#maxvars args) andalso (#maxvars args)>0 then raise MAXVARS_EXCEEDED else ())  (* check if 'maxvars' is large enough *)
  1675 							(* prop_formula list *)
  1676 							val fms      = map BoolVar (next_idx upto (next_idx+size-1))
  1677 							(* interpretation *)
  1678 							val intr     = Leaf fms
  1679 							(* prop_formula list -> prop_formula *)
  1680 							fun one_of_two_false []      = True
  1681 							  | one_of_two_false (x::xs) = SAnd (PropLogic.all (map (fn x' => SOr (SNot x, SNot x')) xs), one_of_two_false xs)
  1682 							(* prop_formula *)
  1683 							val wf       = one_of_two_false fms
  1684 						in
  1685 							(* extend the model, increase 'next_idx', add well-formedness condition *)
  1686 							SOME (intr, (typs, (t, intr)::terms), {maxvars = #maxvars args, def_eq = #def_eq args, next_idx = next, bounds = #bounds args, wellformed = SAnd (#wellformed args, wf)})
  1687 						end
  1688 				end
  1689 			| NONE =>  (* not an inductive datatype *)
  1690 				NONE)
  1691 		  | interpret_term _ =  (* a (free or schematic) type variable *)
  1692 			NONE
  1693 	in
  1694 		case assoc (terms, t) of
  1695 		  SOME intr =>
  1696 			(* return an existing interpretation *)
  1697 			SOME (intr, model, args)
  1698 		| NONE =>
  1699 			(case t of
  1700 			  Free (_, T)  => interpret_term T
  1701 			| Var (_, T)   => interpret_term T
  1702 			| Const (_, T) => interpret_term T
  1703 			| _            => NONE)
  1704 	end;
  1705 
  1706 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1707 
  1708 	fun IDT_constructor_interpreter thy model args t =
  1709 	let
  1710 		val (typs, terms) = model
  1711 	in
  1712 		case assoc (terms, t) of
  1713 		  SOME intr =>
  1714 			(* return an existing interpretation *)
  1715 			SOME (intr, model, args)
  1716 		| NONE =>
  1717 			(case t of
  1718 			  Const (s, T) =>
  1719 				(case body_type T of
  1720 				  Type (s', Ts') =>
  1721 					(case DatatypePackage.datatype_info thy s' of
  1722 					  SOME info =>  (* body type is an inductive datatype *)
  1723 						let
  1724 							val index               = #index info
  1725 							val descr               = #descr info
  1726 							val (_, dtyps, constrs) = (the o assoc) (descr, index)
  1727 							val typ_assoc           = dtyps ~~ Ts'
  1728 							(* sanity check: every element in 'dtyps' must be a 'DtTFree' *)
  1729 							val _ = (if Library.exists (fn d =>
  1730 									case d of DatatypeAux.DtTFree _ => false | _ => true) dtyps
  1731 								then
  1732 									raise REFUTE ("IDT_constructor_interpreter", "datatype argument (for type " ^ Sign.string_of_typ (sign_of thy) (Type (s', Ts')) ^ ") is not a variable")
  1733 								else
  1734 									())
  1735 							(* split the constructors into those occuring before/after 'Const (s, T)' *)
  1736 							val (constrs1, constrs2) = take_prefix (fn (cname, ctypes) =>
  1737 								not (cname = s andalso Type.typ_instance (Sign.tsig_of (sign_of thy)) (T,
  1738 									map (typ_of_dtyp descr typ_assoc) ctypes ---> Type (s', Ts')))) constrs
  1739 						in
  1740 							case constrs2 of
  1741 							  [] =>
  1742 								(* 'Const (s, T)' is not a constructor of this datatype *)
  1743 								NONE
  1744 							| (_, ctypes)::cs =>
  1745 								let
  1746 									(* compute the total size of the datatype (with the current depth) *)
  1747 									val (i, _, _) = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type (s', Ts')))
  1748 									val total     = size_of_type i
  1749 									(* int option -- only recursive IDTs have an associated depth *)
  1750 									val depth = assoc (typs, Type (s', Ts'))
  1751 									val typs' = (case depth of NONE => typs | SOME n => overwrite (typs, (Type (s', Ts'), n-1)))
  1752 									(* DatatypeAux.dtyp list -> interpretation *)
  1753 									fun make_undef [] =
  1754 										Leaf (replicate total False)
  1755 									  | make_undef (d::ds) =
  1756 										let
  1757 											(* compute the current size of the type 'd' *)
  1758 											val T           = typ_of_dtyp descr typ_assoc d
  1759 											val (i, _, _)   = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  1760 											val size        = size_of_type i
  1761 										in
  1762 											Node (replicate size (make_undef ds))
  1763 										end
  1764 									(* returns the interpretation for a constructor at depth 1 *)
  1765 									(* int * DatatypeAux.dtyp list -> int * interpretation *)
  1766 									fun make_constr (offset, []) =
  1767 										if offset<total then
  1768 											(offset+1, Leaf ((replicate offset False) @ True :: (replicate (total-offset-1) False)))
  1769 										else
  1770 											raise REFUTE ("IDT_constructor_interpreter", "offset >= total")
  1771 									  | make_constr (offset, d::ds) =
  1772 										let
  1773 											(* compute the current and the old size of the type 'd' *)
  1774 											val T           = typ_of_dtyp descr typ_assoc d
  1775 											val (i, _, _)   = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  1776 											val size        = size_of_type i
  1777 											val (i', _, _)  = interpret thy (typs', []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  1778 											val size'       = size_of_type i'
  1779 											(* sanity check *)
  1780 											val _           = if size < size' then
  1781 													raise REFUTE ("IDT_constructor_interpreter", "current size is less than old size")
  1782 												else
  1783 													()
  1784 											(* elements that exist at the previous depth are mapped to a defined *)
  1785 											(* value, while new elements are mapped to "undefined" by the        *)
  1786 											(* recursive constructor                                             *)
  1787 											(* int * interpretation list *)
  1788 											val (new_offset, intrs) = foldl_map make_constr (offset, replicate size' ds)
  1789 											(* interpretation list *)
  1790 											val undefs              = replicate (size - size') (make_undef ds)
  1791 										in
  1792 											(new_offset, Node (intrs @ undefs))
  1793 										end
  1794 									(* extends the interpretation for a constructor (both recursive *)
  1795 									(* and non-recursive) obtained at depth n (n>=1) to depth n+1   *)
  1796 									(* int * DatatypeAux.dtyp list * interpretation -> int * interpretation *)
  1797 									fun extend_constr (offset, [], Leaf xs) =
  1798 										let
  1799 											(* returns the k-th unit vector of length n *)
  1800 											(* int * int -> interpretation *)
  1801 											fun unit_vector (k,n) =
  1802 												Leaf ((replicate (k-1) False) @ (True :: (replicate (n-k) False)))
  1803 											(* int *)
  1804 											val k = find_index_eq True xs
  1805 										in
  1806 											if k=(~1) then
  1807 												(* if the element was mapped to "undefined" before, map it to   *)
  1808 												(* the value given by 'offset' now (and extend the length of    *)
  1809 												(* the leaf)                                                    *)
  1810 												(offset+1, unit_vector (offset+1, total))
  1811 											else
  1812 												(* if the element was already mapped to a defined value, map it *)
  1813 												(* to the same value again, just extend the length of the leaf, *)
  1814 												(* do not increment offset                                      *)
  1815 												(offset, unit_vector (k+1, total))
  1816 										end
  1817 									  | extend_constr (_, [], Node _) =
  1818 										raise REFUTE ("IDT_constructor_interpreter", "interpretation for constructor (with no arguments left) is a node")
  1819 									  | extend_constr (offset, d::ds, Node xs) =
  1820 										let
  1821 											(* compute the size of the type 'd' *)
  1822 											val T          = typ_of_dtyp descr typ_assoc d
  1823 											val (i, _, _)  = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  1824 											val size       = size_of_type i
  1825 											(* sanity check *)
  1826 											val _          = if size < length xs then
  1827 													raise REFUTE ("IDT_constructor_interpreter", "new size of type is less than old size")
  1828 												else
  1829 													()
  1830 											(* extend the existing interpretations *)
  1831 											(* int * interpretation list *)
  1832 											val (new_offset, intrs) = foldl_map (fn (off, i) => extend_constr (off, ds, i)) (offset, xs)
  1833 											(* new elements of the type 'd' are mapped to "undefined" *)
  1834 											val undefs = replicate (size - length xs) (make_undef ds)
  1835 										in
  1836 											(new_offset, Node (intrs @ undefs))
  1837 										end
  1838 									  | extend_constr (_, d::ds, Leaf _) =
  1839 										raise REFUTE ("IDT_constructor_interpreter", "interpretation for constructor (with arguments left) is a leaf")
  1840 									(* returns 'true' iff the constructor has a recursive argument *)
  1841 									(* DatatypeAux.dtyp list -> bool *)
  1842 									fun is_rec_constr ds =
  1843 										Library.exists DatatypeAux.is_rec_type ds
  1844 									(* constructors before 'Const (s, T)' generate elements of the datatype, *)
  1845 									(* and if the constructor is recursive, then non-recursive constructors  *)
  1846 									(* after it generate further elements                                    *)
  1847 									val offset = size_of_dtyp thy typs' descr typ_assoc constrs1 +
  1848 										(if is_rec_constr ctypes then
  1849 											size_of_dtyp thy typs' descr typ_assoc (filter (not o is_rec_constr o snd) cs)
  1850 										else
  1851 											0)
  1852 								in
  1853 									case depth of
  1854 									  NONE =>  (* equivalent to a depth of 1 *)
  1855 										SOME (snd (make_constr (offset, ctypes)), model, args)
  1856 									| SOME 0 =>
  1857 										raise REFUTE ("IDT_constructor_interpreter", "depth is 0")
  1858 									| SOME 1 =>
  1859 										SOME (snd (make_constr (offset, ctypes)), model, args)
  1860 									| SOME n =>  (* n > 1 *)
  1861 										let
  1862 											(* interpret the constructor at depth-1 *)
  1863 											val (iC, _, _) = interpret thy (typs', []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Const (s, T))
  1864 											(* elements generated by the constructor at depth-1 must be added to 'offset' *)
  1865 											(* interpretation -> int *)
  1866 											fun number_of_defined_elements (Leaf xs) =
  1867 												if find_index_eq True xs = (~1) then 0 else 1
  1868 											  | number_of_defined_elements (Node xs) =
  1869 												sum (map number_of_defined_elements xs)
  1870 											(* int *)
  1871 											val offset' = offset + number_of_defined_elements iC
  1872 										in
  1873 											SOME (snd (extend_constr (offset', ctypes, iC)), model, args)
  1874 										end
  1875 								end
  1876 						end
  1877 					| NONE =>  (* body type is not an inductive datatype *)
  1878 						NONE)
  1879 				| _ =>  (* body type is a (free or schematic) type variable *)
  1880 					NONE)
  1881 			| _ =>  (* term is not a constant *)
  1882 				NONE)
  1883 	end;
  1884 
  1885 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1886 
  1887 	(* Difficult code ahead.  Make sure you understand the 'IDT_constructor_interpreter' *)
  1888 	(* and the order in which it enumerates elements of an IDT before you try to         *)
  1889 	(* understand this function.                                                         *)
  1890 
  1891 	fun IDT_recursion_interpreter thy model args t =
  1892 		case strip_comb t of  (* careful: here we descend arbitrarily deep into 't', *)
  1893 		                      (* possibly before any other interpreter for atomic    *)
  1894 		                      (* terms has had a chance to look at 't'               *)
  1895 		  (Const (s, T), params) =>
  1896 			(* iterate over all datatypes in 'thy' *)
  1897 			Symtab.foldl (fn (result, (_, info)) =>
  1898 				case result of
  1899 				  SOME _ =>
  1900 					result  (* just keep 'result' *)
  1901 				| NONE =>
  1902 					if s mem (#rec_names info) then
  1903 						(* okay, we do have a recursion operator of the datatype given by 'info' *)
  1904 						let
  1905 							val index               = #index info
  1906 							val descr               = #descr info
  1907 							val (_, dtyps, constrs) = (the o assoc) (descr, index)
  1908 							(* the total number of constructors, including those of different    *)
  1909 							(* (mutually recursive) datatypes within the same descriptor 'descr' *)
  1910 							val constrs_count = sum (map (fn (_, (_, _, cs)) => length cs) descr)
  1911 							val params_count  = length params
  1912 						in
  1913 							if constrs_count < params_count then
  1914 								(* too many actual parameters; for now we'll use the *)
  1915 								(* 'stlc_interpreter' to strip off one application   *)
  1916 								NONE
  1917 							else if constrs_count > params_count then
  1918 								(* too few actual parameters; we use eta expansion            *)
  1919 								(* Note that the resulting expansion of lambda abstractions   *)
  1920 								(* by the 'stlc_interpreter' may be rather slow (depending on *)
  1921 								(* the argument types and the size of the IDT, of course).    *)
  1922 								SOME (interpret thy model args (eta_expand t (constrs_count - params_count)))
  1923 							else  (* constrs_count = params_count *)
  1924 								let
  1925 									(* interpret each parameter separately *)
  1926 									val ((model', args'), p_intrs) = foldl_map (fn ((m, a), p) =>
  1927 										let
  1928 											val (i, m', a') = interpret thy m a p
  1929 										in
  1930 											((m', a'), i)
  1931 										end) ((model, args), params)
  1932 									val (typs, terms) = model'
  1933 									(* the type of a recursion operator: [T1, ..., Tn, IDT] ---> Tresult *)
  1934 									val IDT       = nth_elem (constrs_count, binder_types T)
  1935 									val typ_assoc = dtyps ~~ (snd o dest_Type) IDT
  1936 									(* interpret each constructor of the datatype *)
  1937 									(* TODO: we probably need to interpret every constructor in the descriptor, *)
  1938 									(*       possibly for typs' instead of typs                                 *)
  1939 									val c_intrs = map (#1 o interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True})
  1940 										(map (fn (cname, cargs) => Const (cname, map (typ_of_dtyp descr typ_assoc) cargs ---> IDT)) constrs)
  1941 									(* the recursion operator is a function that maps every element of *)
  1942 									(* the inductive datatype to an element of the result type         *)
  1943 									val (i, _, _) = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", IDT))
  1944 									val size      = size_of_type i
  1945 									val INTRS     = Array.array (size, Leaf [])  (* the initial value 'Leaf []' does not matter; it will be overwritten *)
  1946 									(* takes an interpretation, and if some leaf of this interpretation *)
  1947 									(* is the 'elem'-th element of the datatype, the indices of the     *)
  1948 									(* arguments leading to this leaf are returned                      *)
  1949 									(* interpretation -> int -> int list option *)
  1950 									fun get_args (Leaf xs) elem =
  1951 										if find_index_eq True xs = elem then
  1952 											SOME []
  1953 										else
  1954 											NONE
  1955 									  | get_args (Node xs) elem =
  1956 										let
  1957 											(* interpretation * int -> int list option *)
  1958 											fun search ([], _) =
  1959 												NONE
  1960 											  | search (x::xs, n) =
  1961 												(case get_args x elem of
  1962 												  SOME result => SOME (n::result)
  1963 												| NONE        => search (xs, n+1))
  1964 										in
  1965 											search (xs, 0)
  1966 										end
  1967 									(* returns the index of the constructor and indices for its      *)
  1968 									(* arguments that generate the 'elem'-th element of the datatype *)
  1969 									(* int -> int * int list *)
  1970 									fun get_cargs elem =
  1971 										let
  1972 											(* int * interpretation list -> int * int list *)
  1973 											fun get_cargs_rec (_, []) =
  1974 												raise REFUTE ("IDT_recursion_interpreter", "no matching constructor found for element " ^ string_of_int elem)
  1975 											  | get_cargs_rec (n, x::xs) =
  1976 												(case get_args x elem of
  1977 												  SOME args => (n, args)
  1978 												| NONE      => get_cargs_rec (n+1, xs))
  1979 										in
  1980 											get_cargs_rec (0, c_intrs)
  1981 										end
  1982 									(* int -> unit *)
  1983 									fun compute_loop elem =
  1984 										if elem=size then
  1985 											()
  1986 										else  (* elem < size *)
  1987 											let
  1988 												(* int * int list *)
  1989 												val (c, args) = get_cargs elem
  1990 												(* interpretation * int list -> interpretation *)
  1991 												fun select_subtree (tr, []) =
  1992 													tr  (* return the whole tree *)
  1993 												  | select_subtree (Leaf _, _) =
  1994 													raise REFUTE ("IDT_recursion_interpreter", "interpretation for parameter is a leaf; cannot select a subtree")
  1995 												  | select_subtree (Node tr, x::xs) =
  1996 													select_subtree (nth_elem (x, tr), xs)
  1997 												(* select the correct subtree of the parameter corresponding to constructor 'c' *)
  1998 												val p_intr = select_subtree (nth_elem (c, p_intrs), args)
  1999 												(* find the indices of recursive arguments *)
  2000 												val rec_args = map snd (filter (DatatypeAux.is_rec_type o fst) ((snd (nth_elem (c, constrs))) ~~ args))
  2001 												(* apply 'p_intr' to recursively computed results *)
  2002 												val rec_p_intr = foldl (fn (i, n) => interpretation_apply (i, Array.sub (INTRS, n))) (p_intr, rec_args)
  2003 												(* update 'INTRS' *)
  2004 												val _ = Array.update (INTRS, elem, rec_p_intr)
  2005 											in
  2006 												compute_loop (elem+1)
  2007 											end
  2008 									val _ = compute_loop 0
  2009 									(* 'a Array.array -> 'a list *)
  2010 									fun toList arr =
  2011 										Array.foldr op:: [] arr
  2012 								in
  2013 									(* TODO writeln ("REC-OP: " ^ makestring (Node (toList INTRS))); *)
  2014 									SOME (Node (toList INTRS), model', args')
  2015 								end
  2016 						end
  2017 					else
  2018 						NONE  (* not a recursion operator of this datatype *)
  2019 				) (NONE, DatatypePackage.get_datatypes thy)
  2020 		| _ =>  (* head of term is not a constant *)
  2021 			NONE;
  2022 
  2023 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  2024 
  2025 	(* only an optimization: 'card' could in principle be interpreted with    *)
  2026 	(* interpreters available already (using its definition), but the code    *)
  2027 	(* below is more efficient                                                *)
  2028 
  2029 	fun Finite_Set_card_interpreter thy model args t =
  2030 		case t of
  2031 		  Const ("Finite_Set.card", Type ("fun", [Type ("set", [T]), Type ("nat", [])])) =>
  2032 			let
  2033 				val (i_nat, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("nat", [])))
  2034 				val size_nat      = size_of_type i_nat
  2035 				val (i_set, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("set", [T])))
  2036 				val constants     = make_constants i_set
  2037 				(* interpretation -> int *)
  2038 				fun number_of_elements (Node xs) =
  2039 					foldl (fn (n, x) =>
  2040 						if x=TT then
  2041 							n+1
  2042 						else if x=FF then
  2043 							n
  2044 						else
  2045 							raise REFUTE ("Finite_Set_card_interpreter", "interpretation for set type does not yield a Boolean")) (0, xs)
  2046 				  | number_of_elements (Leaf _) =
  2047 					raise REFUTE ("Finite_Set_card_interpreter", "interpretation for set type is a leaf")
  2048 				(* takes an interpretation for a set and returns an interpretation for a 'nat' *)
  2049 				(* interpretation -> interpretation *)
  2050 				fun card i =
  2051 					let
  2052 						val n = number_of_elements i
  2053 					in
  2054 						if n<size_nat then
  2055 							Leaf ((replicate n False) @ True :: (replicate (size_nat-n-1) False))
  2056 						else
  2057 							Leaf (replicate size_nat False)
  2058 					end
  2059 			in
  2060 				SOME (Node (map card constants), model, args)
  2061 			end
  2062 		| _ =>
  2063 			NONE;
  2064 
  2065 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  2066 
  2067 	(* only an optimization: 'op <' could in principle be interpreted with    *)
  2068 	(* interpreters available already (using its definition), but the code    *)
  2069 	(* below is more efficient                                                *)
  2070 
  2071 	fun Nat_less_interpreter thy model args t =
  2072 		case t of
  2073 		  Const ("op <", Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("bool", [])])])) =>
  2074 			let
  2075 				val (i_nat, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("nat", [])))
  2076 				val size_nat      = size_of_type i_nat
  2077 				(* int -> interpretation *)
  2078 				(* the 'n'-th nat is not less than the first 'n' nats, while it *)
  2079 				(* is less than the remaining 'size_nat - n' nats               *)
  2080 				fun less n = Node ((replicate n FF) @ (replicate (size_nat - n) TT))
  2081 			in
  2082 				SOME (Node (map less (1 upto size_nat)), model, args)
  2083 			end
  2084 		| _ =>
  2085 			NONE;
  2086 
  2087 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  2088 
  2089 	(* only an optimization: 'op +' could in principle be interpreted with    *)
  2090 	(* interpreters available already (using its definition), but the code    *)
  2091 	(* below is more efficient                                                *)
  2092 
  2093 	fun Nat_plus_interpreter thy model args t =
  2094 		case t of
  2095 		  Const ("op +", Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("nat", [])])])) =>
  2096 			let
  2097 				val (i_nat, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("nat", [])))
  2098 				val size_nat      = size_of_type i_nat
  2099 				(* int -> int -> interpretation *)
  2100 				fun plus m n = let
  2101 						val element = (m+n)+1
  2102 					in
  2103 						if element > size_nat then
  2104 							Leaf (replicate size_nat False)
  2105 						else
  2106 							Leaf ((replicate (element-1) False) @ True :: (replicate (size_nat - element) False))
  2107 					end
  2108 			in
  2109 				SOME (Node (map (fn m => Node (map (plus m) (0 upto size_nat-1))) (0 upto size_nat-1)), model, args)
  2110 			end
  2111 		| _ =>
  2112 			NONE;
  2113 
  2114 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  2115 
  2116 	(* only an optimization: 'op -' could in principle be interpreted with    *)
  2117 	(* interpreters available already (using its definition), but the code    *)
  2118 	(* below is more efficient                                                *)
  2119 
  2120 	fun Nat_minus_interpreter thy model args t =
  2121 		case t of
  2122 		  Const ("op -", Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("nat", [])])])) =>
  2123 			let
  2124 				val (i_nat, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("nat", [])))
  2125 				val size_nat      = size_of_type i_nat
  2126 				(* int -> int -> interpretation *)
  2127 				fun minus m n = let
  2128 						val element = Int.max (m-n, 0) + 1
  2129 					in
  2130 						Leaf ((replicate (element-1) False) @ True :: (replicate (size_nat - element) False))
  2131 					end
  2132 			in
  2133 				SOME (Node (map (fn m => Node (map (minus m) (0 upto size_nat-1))) (0 upto size_nat-1)), model, args)
  2134 			end
  2135 		| _ =>
  2136 			NONE;
  2137 
  2138 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  2139 
  2140 	(* only an optimization: 'op *' could in principle be interpreted with    *)
  2141 	(* interpreters available already (using its definition), but the code    *)
  2142 	(* below is more efficient                                                *)
  2143 
  2144 	fun Nat_mult_interpreter thy model args t =
  2145 		case t of
  2146 		  Const ("op *", Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("nat", [])])])) =>
  2147 			let
  2148 				val (i_nat, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("nat", [])))
  2149 				val size_nat      = size_of_type i_nat
  2150 				(* nat -> nat -> interpretation *)
  2151 				fun mult m n = let
  2152 						val element = (m*n)+1
  2153 					in
  2154 						if element > size_nat then
  2155 							Leaf (replicate size_nat False)
  2156 						else
  2157 							Leaf ((replicate (element-1) False) @ True :: (replicate (size_nat - element) False))
  2158 					end
  2159 			in
  2160 				SOME (Node (map (fn m => Node (map (mult m) (0 upto size_nat-1))) (0 upto size_nat-1)), model, args)
  2161 			end
  2162 		| _ =>
  2163 			NONE;
  2164 
  2165 
  2166 (* ------------------------------------------------------------------------- *)
  2167 (* PRINTERS                                                                  *)
  2168 (* ------------------------------------------------------------------------- *)
  2169 
  2170 	(* theory -> model -> Term.term -> interpretation -> (int -> bool) -> Term.term option *)
  2171 
  2172 	fun stlc_printer thy model t intr assignment =
  2173 	let
  2174 		(* Term.term -> Term.typ option *)
  2175 		fun typeof (Free (_, T))  = SOME T
  2176 		  | typeof (Var (_, T))   = SOME T
  2177 		  | typeof (Const (_, T)) = SOME T
  2178 		  | typeof _              = NONE
  2179 		(* string -> string *)
  2180 		fun strip_leading_quote s =
  2181 			(implode o (fn ss => case ss of [] => [] | x::xs => if x="'" then xs else ss) o explode) s
  2182 		(* Term.typ -> string *)
  2183 		fun string_of_typ (Type (s, _))     = s
  2184 		  | string_of_typ (TFree (x, _))    = strip_leading_quote x
  2185 		  | string_of_typ (TVar ((x,i), _)) = strip_leading_quote x ^ string_of_int i
  2186 		(* interpretation -> int *)
  2187 		fun index_from_interpretation (Leaf xs) =
  2188 			find_index (PropLogic.eval assignment) xs
  2189 		  | index_from_interpretation _ =
  2190 			raise REFUTE ("stlc_printer", "interpretation for ground type is not a leaf")
  2191 	in
  2192 		case typeof t of
  2193 		  SOME T =>
  2194 			(case T of
  2195 			  Type ("fun", [T1, T2]) =>
  2196 				let
  2197 					(* create all constants of type 'T1' *)
  2198 					val (i, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T1))
  2199 					val constants = make_constants i
  2200 					(* interpretation list *)
  2201 					val results = (case intr of
  2202 						  Node xs => xs
  2203 						| _       => raise REFUTE ("stlc_printer", "interpretation for function type is a leaf"))
  2204 					(* Term.term list *)
  2205 					val pairs = map (fn (arg, result) =>
  2206 						HOLogic.mk_prod
  2207 							(print thy model (Free ("dummy", T1)) arg assignment,
  2208 							 print thy model (Free ("dummy", T2)) result assignment))
  2209 						(constants ~~ results)
  2210 					(* Term.typ *)
  2211 					val HOLogic_prodT = HOLogic.mk_prodT (T1, T2)
  2212 					val HOLogic_setT  = HOLogic.mk_setT HOLogic_prodT
  2213 					(* Term.term *)
  2214 					val HOLogic_empty_set = Const ("{}", HOLogic_setT)
  2215 					val HOLogic_insert    = Const ("insert", HOLogic_prodT --> HOLogic_setT --> HOLogic_setT)
  2216 				in
  2217 					SOME (foldr (fn (pair, acc) => HOLogic_insert $ pair $ acc) (pairs, HOLogic_empty_set))
  2218 				end
  2219 			| Type ("prop", [])      =>
  2220 				(case index_from_interpretation intr of
  2221 				  (~1) => SOME (HOLogic.mk_Trueprop (Const ("arbitrary", HOLogic.boolT)))
  2222 				| 0    => SOME (HOLogic.mk_Trueprop HOLogic.true_const)
  2223 				| 1    => SOME (HOLogic.mk_Trueprop HOLogic.false_const)
  2224 				| _    => raise REFUTE ("stlc_interpreter", "illegal interpretation for a propositional value"))
  2225 			| Type _  => if index_from_interpretation intr = (~1) then
  2226 					SOME (Const ("arbitrary", T))
  2227 				else
  2228 					SOME (Const (string_of_typ T ^ string_of_int (index_from_interpretation intr), T))
  2229 			| TFree _ => if index_from_interpretation intr = (~1) then
  2230 					SOME (Const ("arbitrary", T))
  2231 				else
  2232 					SOME (Const (string_of_typ T ^ string_of_int (index_from_interpretation intr), T))
  2233 			| TVar _  => if index_from_interpretation intr = (~1) then
  2234 					SOME (Const ("arbitrary", T))
  2235 				else
  2236 					SOME (Const (string_of_typ T ^ string_of_int (index_from_interpretation intr), T)))
  2237 		| NONE =>
  2238 			NONE
  2239 	end;
  2240 
  2241 	(* theory -> model -> Term.term -> interpretation -> (int -> bool) -> string option *)
  2242 
  2243 	fun set_printer thy model t intr assignment =
  2244 	let
  2245 		(* Term.term -> Term.typ option *)
  2246 		fun typeof (Free (_, T))  = SOME T
  2247 		  | typeof (Var (_, T))   = SOME T
  2248 		  | typeof (Const (_, T)) = SOME T
  2249 		  | typeof _              = NONE
  2250 	in
  2251 		case typeof t of
  2252 		  SOME (Type ("set", [T])) =>
  2253 			let
  2254 				(* create all constants of type 'T' *)
  2255 				val (i, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  2256 				val constants = make_constants i
  2257 				(* interpretation list *)
  2258 				val results = (case intr of
  2259 					  Node xs => xs
  2260 					| _       => raise REFUTE ("set_printer", "interpretation for set type is a leaf"))
  2261 				(* Term.term list *)
  2262 				val elements = mapfilter (fn (arg, result) =>
  2263 					case result of
  2264 					  Leaf [fmTrue, fmFalse] =>
  2265 						if PropLogic.eval assignment fmTrue then
  2266 							SOME (print thy model (Free ("dummy", T)) arg assignment)
  2267 						else (*if PropLogic.eval assignment fmFalse then*)
  2268 							NONE
  2269 					| _ =>
  2270 						raise REFUTE ("set_printer", "illegal interpretation for a Boolean value"))
  2271 					(constants ~~ results)
  2272 				(* Term.typ *)
  2273 				val HOLogic_setT  = HOLogic.mk_setT T
  2274 				(* Term.term *)
  2275 				val HOLogic_empty_set = Const ("{}", HOLogic_setT)
  2276 				val HOLogic_insert    = Const ("insert", T --> HOLogic_setT --> HOLogic_setT)
  2277 			in
  2278 				SOME (foldl (fn (acc, elem) => HOLogic_insert $ elem $ acc) (HOLogic_empty_set, elements))
  2279 			end
  2280 		| _ =>
  2281 			NONE
  2282 	end;
  2283 
  2284 	(* theory -> model -> Term.term -> interpretation -> (int -> bool) -> Term.term option *)
  2285 
  2286 	fun IDT_printer thy model t intr assignment =
  2287 	let
  2288 		(* Term.term -> Term.typ option *)
  2289 		fun typeof (Free (_, T))  = SOME T
  2290 		  | typeof (Var (_, T))   = SOME T
  2291 		  | typeof (Const (_, T)) = SOME T
  2292 		  | typeof _              = NONE
  2293 	in
  2294 		case typeof t of
  2295 		  SOME (Type (s, Ts)) =>
  2296 			(case DatatypePackage.datatype_info thy s of
  2297 			  SOME info =>  (* inductive datatype *)
  2298 				let
  2299 					val (typs, _)           = model
  2300 					val index               = #index info
  2301 					val descr               = #descr info
  2302 					val (_, dtyps, constrs) = (the o assoc) (descr, index)
  2303 					val typ_assoc           = dtyps ~~ Ts
  2304 					(* sanity check: every element in 'dtyps' must be a 'DtTFree' *)
  2305 					val _ = (if Library.exists (fn d =>
  2306 							case d of DatatypeAux.DtTFree _ => false | _ => true) dtyps
  2307 						then
  2308 							raise REFUTE ("IDT_printer", "datatype argument (for type " ^ Sign.string_of_typ (sign_of thy) (Type (s, Ts)) ^ ") is not a variable")
  2309 						else
  2310 							())
  2311 					(* the index of the element in the datatype *)
  2312 					val element = (case intr of
  2313 						  Leaf xs => find_index (PropLogic.eval assignment) xs
  2314 						| Node _  => raise REFUTE ("IDT_printer", "interpretation is not a leaf"))
  2315 				in
  2316 					if element < 0 then
  2317 						SOME (Const ("arbitrary", Type (s, Ts)))
  2318 					else let
  2319 						(* takes a datatype constructor, and if for some arguments this constructor *)
  2320 						(* generates the datatype's element that is given by 'element', returns the *)
  2321 						(* constructor (as a term) as well as the indices of the arguments          *)
  2322 						(* string * DatatypeAux.dtyp list -> (Term.term * int list) option *)
  2323 						fun get_constr_args (cname, cargs) =
  2324 							let
  2325 								val cTerm      = Const (cname, (map (typ_of_dtyp descr typ_assoc) cargs) ---> Type (s, Ts))
  2326 								(*TODO val _          = writeln ("cTerm: " ^ makestring cTerm) *)
  2327 								val (iC, _, _) = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} cTerm
  2328 								(*TODO val _          = writeln ("iC: " ^ makestring iC) *)
  2329 								(* interpretation -> int list option *)
  2330 								fun get_args (Leaf xs) =
  2331 									if find_index_eq True xs = element then
  2332 										SOME []
  2333 									else
  2334 										NONE
  2335 								  | get_args (Node xs) =
  2336 									let
  2337 										(* interpretation * int -> int list option *)
  2338 										fun search ([], _) =
  2339 											NONE
  2340 										  | search (x::xs, n) =
  2341 											(case get_args x of
  2342 											  SOME result => SOME (n::result)
  2343 											| NONE        => search (xs, n+1))
  2344 									in
  2345 										search (xs, 0)
  2346 									end
  2347 							in
  2348 								apsome (fn args => (cTerm, cargs, args)) (get_args iC)
  2349 							end
  2350 						(* Term.term * DatatypeAux.dtyp list * int list *)
  2351 						val (cTerm, cargs, args) = (case get_first get_constr_args constrs of
  2352 							  SOME x => x
  2353 							| NONE   => raise REFUTE ("IDT_printer", "no matching constructor found for element " ^ string_of_int element))
  2354 						val argsTerms = map (fn (d, n) =>
  2355 							let
  2356 								val dT        = typ_of_dtyp descr typ_assoc d
  2357 								val (i, _, _) = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", dT))
  2358 								val consts    = make_constants i  (* we only need the n-th element of this *)
  2359 									(* list, so there might be a more efficient implementation that does    *)
  2360 									(* not generate all constants                                           *)
  2361 							in
  2362 								print thy (typs, []) (Free ("dummy", dT)) (nth_elem (n, consts)) assignment
  2363 							end) (cargs ~~ args)
  2364 					in
  2365 						SOME (foldl op$ (cTerm, argsTerms))
  2366 					end
  2367 				end
  2368 			| NONE =>  (* not an inductive datatype *)
  2369 				NONE)
  2370 		| _ =>  (* a (free or schematic) type variable *)
  2371 			NONE
  2372 	end;
  2373 
  2374 
  2375 (* ------------------------------------------------------------------------- *)
  2376 (* use 'setup Refute.setup' in an Isabelle theory to initialize the 'Refute' *)
  2377 (* structure                                                                 *)
  2378 (* ------------------------------------------------------------------------- *)
  2379 
  2380 (* ------------------------------------------------------------------------- *)
  2381 (* Note: the interpreters and printers are used in reverse order; however,   *)
  2382 (*       an interpreter that can handle non-atomic terms ends up being       *)
  2383 (*       applied before the 'stlc_interpreter' breaks the term apart into    *)
  2384 (*       subterms that are then passed to other interpreters!                *)
  2385 (* ------------------------------------------------------------------------- *)
  2386 
  2387 	(* (theory -> theory) list *)
  2388 
  2389 	val setup =
  2390 		[RefuteData.init,
  2391 		 add_interpreter "stlc"            stlc_interpreter,
  2392 		 add_interpreter "Pure"            Pure_interpreter,
  2393 		 add_interpreter "HOLogic"         HOLogic_interpreter,
  2394 		 add_interpreter "set"             set_interpreter,
  2395 		 add_interpreter "IDT"             IDT_interpreter,
  2396 		 add_interpreter "IDT_constructor" IDT_constructor_interpreter,
  2397 		 add_interpreter "IDT_recursion"   IDT_recursion_interpreter,
  2398 		 add_interpreter "Finite_Set.card" Finite_Set_card_interpreter,
  2399 		 add_interpreter "Nat.op <"        Nat_less_interpreter,
  2400 		 add_interpreter "Nat.op +"        Nat_plus_interpreter,
  2401 		 add_interpreter "Nat.op -"        Nat_minus_interpreter,
  2402 		 add_interpreter "Nat.op *"        Nat_mult_interpreter,
  2403 		 add_printer "stlc" stlc_printer,
  2404 		 add_printer "set"  set_printer,
  2405 		 add_printer "IDT"  IDT_printer];
  2406 
  2407 end