src/HOL/Tools/refute.ML
author webertj
Thu Mar 17 01:40:18 2005 +0100 (2005-03-17)
changeset 15611 c01f11cd08f9
parent 15574 b1d1b5bfc464
child 15767 8ed9fcc004fe
permissions -rw-r--r--
Bugfix related to the interpretation of IDT constructors
     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) = Library.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:" :: List.concat (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" (List.mapPartial (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     = List.mapPartial
   363 			(fn (name,value) => (case Int.fromString value of SOME i => SOME (name, i) | NONE => NONE))
   364 			(List.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 		(valOf 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, _) = (valOf 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 = List.concat (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             = List.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 						Library.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 				Library.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 							Library.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 								Library.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 							Library.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), (valOf 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), (valOf 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 ("Finite_Set.Finites", T) => collect_type_axioms (axs, T)
   623 			| Const ("op <", T as Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("bool", [])])])) => 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 			| Const ("op *", T as Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("nat", [])])])) => collect_type_axioms (axs, T)
   627 			(* simply-typed lambda calculus *)
   628 			| Const (s, T)                    =>
   629 				let
   630 					(* look up the definition of a constant, as created by "constdefs" *)
   631 					(* string -> Term.typ -> (string * Term.term) list -> (string * Term.term) option *)
   632 					fun get_defn [] =
   633 						NONE
   634 					  | get_defn ((axname, ax)::axms) =
   635 						(let
   636 							val (lhs, _) = Logic.dest_equals ax  (* equations only *)
   637 							val c        = head_of lhs
   638 							val (s', T') = dest_Const c
   639 						in
   640 							if s=s' then
   641 								let
   642 									val typeSubs = Type.typ_match (Sign.tsig_of (sign_of thy)) (Vartab.empty, (T', T))
   643 								in
   644 									SOME (axname, monomorphic_term typeSubs ax)
   645 								end
   646 							else
   647 								get_defn axms
   648 						end
   649 						handle ERROR           => get_defn axms
   650 						     | TERM _          => get_defn axms
   651 						     | Type.TYPE_MATCH => get_defn axms)
   652 					(* axiomatic type classes *)
   653 					(* unit -> bool *)
   654 					fun is_const_of_class () =
   655 						(* I'm not quite sure if checking the name 's' is sufficient, *)
   656 						(* or if we should also check the type 'T'                    *)
   657 						s mem const_of_class_names
   658 					(* inductive data types *)
   659 					(* unit -> bool *)
   660 					fun is_IDT_constructor () =
   661 						(case body_type T of
   662 						  Type (s', _) =>
   663 							(case DatatypePackage.constrs_of thy s' of
   664 							  SOME constrs =>
   665 								Library.exists (fn c =>
   666 									(case c of
   667 									  Const (cname, ctype) =>
   668 										cname = s andalso Type.typ_instance (Sign.tsig_of (sign_of thy)) (T, ctype)
   669 									| _ =>
   670 										raise REFUTE ("collect_axioms", "IDT constructor is not a constant")))
   671 									constrs
   672 							| NONE =>
   673 								false)
   674 						| _  =>
   675 							false)
   676 					(* unit -> bool *)
   677 					fun is_IDT_recursor () =
   678 						(* I'm not quite sure if checking the name 's' is sufficient, *)
   679 						(* or if we should also check the type 'T'                    *)
   680 						s mem rec_names
   681 				in
   682 					if is_const_of_class () then
   683 						(* axiomatic type classes: add "OFCLASS(?'a::c, c_class)" and *)
   684 						(* the introduction rule "class.intro" as axioms              *)
   685 						let
   686 							val class   = Sign.class_of_const s
   687 							val inclass = Logic.mk_inclass (TVar (("'a", 0), [class]), class)
   688 							(* Term.term option *)
   689 							val ofclass_ax = (SOME (specialize_type ((s, T), inclass)) handle Type.TYPE_MATCH => NONE)
   690 							val intro_ax   = (Option.map (fn t => specialize_type ((s, T), t)) (assoc (axioms, class ^ ".intro")) handle Type.TYPE_MATCH => NONE)
   691 							val axs'       = (case ofclass_ax of NONE => axs | SOME ax => if mem_term (ax, axs) then
   692 									(* collect relevant type axioms *)
   693 									collect_type_axioms (axs, T)
   694 								else
   695 									(immediate_output (" " ^ Sign.string_of_term (sign_of thy) ax);
   696 									collect_term_axioms (ax :: axs, ax)))
   697 							val axs''      = (case intro_ax of NONE => axs' | SOME ax => if mem_term (ax, axs') then
   698 									(* collect relevant type axioms *)
   699 									collect_type_axioms (axs', T)
   700 								else
   701 									(immediate_output (" " ^ class ^ ".intro");
   702 									collect_term_axioms (ax :: axs', ax)))
   703 						in
   704 							axs''
   705 						end
   706 					else if is_IDT_constructor () then
   707 						(* only collect relevant type axioms *)
   708 						collect_type_axioms (axs, T)
   709 					else if is_IDT_recursor () then
   710 						(* only collect relevant type axioms *)
   711 						collect_type_axioms (axs, T)
   712 					else (
   713 						case get_defn axioms of
   714 						  SOME (axname, ax) => 
   715 							if mem_term (ax, axs) then
   716 								(* collect relevant type axioms *)
   717 								collect_type_axioms (axs, T)
   718 							else
   719 								(immediate_output (" " ^ axname);
   720 								collect_term_axioms (ax :: axs, ax))
   721 						| NONE =>
   722 							(* collect relevant type axioms *)
   723 							collect_type_axioms (axs, T)
   724 					)
   725 				end
   726 			| Free (_, T)                     => collect_type_axioms (axs, T)
   727 			| Var (_, T)                      => collect_type_axioms (axs, T)
   728 			| Bound i                         => axs
   729 			| Abs (_, T, body)                => collect_term_axioms (collect_type_axioms (axs, T), body)
   730 			| t1 $ t2                         => collect_term_axioms (collect_term_axioms (axs, t1), t2)
   731 		(* universal closure over schematic variables *)
   732 		(* Term.term -> Term.term *)
   733 		fun close_form t =
   734 		let
   735 			(* (Term.indexname * Term.typ) list *)
   736 			val vars = sort_wrt (fst o fst) (map dest_Var (term_vars t))
   737 		in
   738 			Library.foldl
   739 				(fn (t', ((x, i), T)) => (Term.all T) $ Abs (x, T, abstract_over (Var((x, i), T), t')))
   740 				(t, vars)
   741 		end
   742 		(* Term.term list *)
   743 		val result = map close_form (collect_term_axioms ([], t))
   744 		val _ = writeln " ...done."
   745 	in
   746 		result
   747 	end;
   748 
   749 (* ------------------------------------------------------------------------- *)
   750 (* ground_types: collects all ground types in a term (including argument     *)
   751 (*               types of other types), suppressing duplicates.  Does not    *)
   752 (*               return function types, set types, non-recursive IDTs, or    *)
   753 (*               'propT'.  For IDTs, also the argument types of constructors *)
   754 (*               are considered.                                             *)
   755 (* ------------------------------------------------------------------------- *)
   756 
   757 	(* theory -> Term.term -> Term.typ list *)
   758 
   759 	fun ground_types thy t =
   760 	let
   761 		(* Term.typ * Term.typ list -> Term.typ list *)
   762 		fun collect_types (T, acc) =
   763 			if T mem acc then
   764 				acc  (* prevent infinite recursion (for IDTs) *)
   765 			else
   766 				(case T of
   767 				  Type ("fun", [T1, T2]) => collect_types (T1, collect_types (T2, acc))
   768 				| Type ("prop", [])      => acc
   769 				| Type ("set", [T1])     => collect_types (T1, acc)
   770 				| Type (s, Ts)           =>
   771 					(case DatatypePackage.datatype_info thy s of
   772 					  SOME info =>  (* inductive datatype *)
   773 						let
   774 							val index               = #index info
   775 							val descr               = #descr info
   776 							val (_, dtyps, constrs) = (valOf o assoc) (descr, index)
   777 							val typ_assoc           = dtyps ~~ Ts
   778 							(* sanity check: every element in 'dtyps' must be a 'DtTFree' *)
   779 							val _ = (if Library.exists (fn d =>
   780 									case d of DatatypeAux.DtTFree _ => false | _ => true) dtyps
   781 								then
   782 									raise REFUTE ("ground_types", "datatype argument (for type " ^ Sign.string_of_typ (sign_of thy) (Type (s, Ts)) ^ ") is not a variable")
   783 								else
   784 									())
   785 							(* if the current type is a recursive IDT (i.e. a depth is required), add it to 'acc' *)
   786 							val acc' = (if Library.exists (fn (_, ds) => Library.exists DatatypeAux.is_rec_type ds) constrs then
   787 									T ins acc
   788 								else
   789 									acc)
   790 							(* collect argument types *)
   791 							val acc_args = foldr collect_types acc' Ts
   792 							(* collect constructor types *)
   793 							val acc_constrs = foldr collect_types acc_args (List.concat (map (fn (_, ds) => map (typ_of_dtyp descr typ_assoc) ds) constrs))
   794 						in
   795 							acc_constrs
   796 						end
   797 					| NONE =>  (* not an inductive datatype, e.g. defined via "typedef" or "typedecl" *)
   798 						T ins (foldr collect_types acc Ts))
   799 				| TFree _                => T ins acc
   800 				| TVar _                 => T ins acc)
   801 	in
   802 		it_term_types collect_types (t, [])
   803 	end;
   804 
   805 (* ------------------------------------------------------------------------- *)
   806 (* string_of_typ: (rather naive) conversion from types to strings, used to   *)
   807 (*                look up the size of a type in 'sizes'.  Parameterized      *)
   808 (*                types with different parameters (e.g. "'a list" vs. "bool  *)
   809 (*                list") are identified.                                     *)
   810 (* ------------------------------------------------------------------------- *)
   811 
   812 	(* Term.typ -> string *)
   813 
   814 	fun string_of_typ (Type (s, _))     = s
   815 	  | string_of_typ (TFree (s, _))    = s
   816 	  | string_of_typ (TVar ((s,_), _)) = s;
   817 
   818 (* ------------------------------------------------------------------------- *)
   819 (* first_universe: returns the "first" (i.e. smallest) universe by assigning *)
   820 (*                 'minsize' to every type for which no size is specified in *)
   821 (*                 'sizes'                                                   *)
   822 (* ------------------------------------------------------------------------- *)
   823 
   824 	(* Term.typ list -> (string * int) list -> int -> (Term.typ * int) list *)
   825 
   826 	fun first_universe xs sizes minsize =
   827 	let
   828 		fun size_of_typ T =
   829 			case assoc (sizes, string_of_typ T) of
   830 			  SOME n => n
   831 			| NONE   => minsize
   832 	in
   833 		map (fn T => (T, size_of_typ T)) xs
   834 	end;
   835 
   836 (* ------------------------------------------------------------------------- *)
   837 (* next_universe: enumerates all universes (i.e. assignments of sizes to     *)
   838 (*                types), where the minimal size of a type is given by       *)
   839 (*                'minsize', the maximal size is given by 'maxsize', and a   *)
   840 (*                type may have a fixed size given in 'sizes'                *)
   841 (* ------------------------------------------------------------------------- *)
   842 
   843 	(* (Term.typ * int) list -> (string * int) list -> int -> int -> (Term.typ * int) list option *)
   844 
   845 	fun next_universe xs sizes minsize maxsize =
   846 	let
   847 		(* creates the "first" list of length 'len', where the sum of all list *)
   848 		(* elements is 'sum', and the length of the list is 'len'              *)
   849 		(* int -> int -> int -> int list option *)
   850 		fun make_first _ 0 sum =
   851 			if sum=0 then
   852 				SOME []
   853 			else
   854 				NONE
   855 		  | make_first max len sum =
   856 			if sum<=max orelse max<0 then
   857 				Option.map (fn xs' => sum :: xs') (make_first max (len-1) 0)
   858 			else
   859 				Option.map (fn xs' => max :: xs') (make_first max (len-1) (sum-max))
   860 		(* enumerates all int lists with a fixed length, where 0<=x<='max' for *)
   861 		(* all list elements x (unless 'max'<0)                                *)
   862 		(* int -> int -> int -> int list -> int list option *)
   863 		fun next max len sum [] =
   864 			NONE
   865 		  | next max len sum [x] =
   866 			(* we've reached the last list element, so there's no shift possible *)
   867 			make_first max (len+1) (sum+x+1)  (* increment 'sum' by 1 *)
   868 		  | next max len sum (x1::x2::xs) =
   869 			if x1>0 andalso (x2<max orelse max<0) then
   870 				(* we can shift *)
   871 				SOME (valOf (make_first max (len+1) (sum+x1-1)) @ (x2+1) :: xs)
   872 			else
   873 				(* continue search *)
   874 				next max (len+1) (sum+x1) (x2::xs)
   875 		(* only consider those types for which the size is not fixed *)
   876 		val mutables = List.filter (fn (T, _) => assoc (sizes, string_of_typ T) = NONE) xs
   877 		(* subtract 'minsize' from every size (will be added again at the end) *)
   878 		val diffs = map (fn (_, n) => n-minsize) mutables
   879 	in
   880 		case next (maxsize-minsize) 0 0 diffs of
   881 		  SOME diffs' =>
   882 			(* merge with those types for which the size is fixed *)
   883 			SOME (snd (foldl_map (fn (ds, (T, _)) =>
   884 				case assoc (sizes, string_of_typ T) of
   885 				  SOME n => (ds, (T, n))                    (* return the fixed size *)
   886 				| NONE   => (tl ds, (T, minsize + hd ds)))  (* consume the head of 'ds', add 'minsize' *)
   887 				(diffs', xs)))
   888 		| NONE =>
   889 			NONE
   890 	end;
   891 
   892 (* ------------------------------------------------------------------------- *)
   893 (* toTrue: converts the interpretation of a Boolean value to a propositional *)
   894 (*         formula that is true iff the interpretation denotes "true"        *)
   895 (* ------------------------------------------------------------------------- *)
   896 
   897 	(* interpretation -> prop_formula *)
   898 
   899 	fun toTrue (Leaf [fm,_]) = fm
   900 	  | toTrue _             = raise REFUTE ("toTrue", "interpretation does not denote a Boolean value");
   901 
   902 (* ------------------------------------------------------------------------- *)
   903 (* toFalse: converts the interpretation of a Boolean value to a              *)
   904 (*          propositional formula that is true iff the interpretation        *)
   905 (*          denotes "false"                                                  *)
   906 (* ------------------------------------------------------------------------- *)
   907 
   908 	(* interpretation -> prop_formula *)
   909 
   910 	fun toFalse (Leaf [_,fm]) = fm
   911 	  | toFalse _             = raise REFUTE ("toFalse", "interpretation does not denote a Boolean value");
   912 
   913 (* ------------------------------------------------------------------------- *)
   914 (* find_model: repeatedly calls 'interpret' with appropriate parameters,     *)
   915 (*             applies a SAT solver, and (in case a model is found) displays *)
   916 (*             the model to the user by calling 'print_model'                *)
   917 (* thy       : the current theory                                            *)
   918 (* {...}     : parameters that control the translation/model generation      *)
   919 (* t         : term to be translated into a propositional formula            *)
   920 (* negate    : if true, find a model that makes 't' false (rather than true) *)
   921 (* Note: exception 'TimeOut' is raised if the algorithm does not terminate   *)
   922 (*       within 'maxtime' seconds (if 'maxtime' >0)                          *)
   923 (* ------------------------------------------------------------------------- *)
   924 
   925 	(* theory -> params -> Term.term -> bool -> unit *)
   926 
   927 	fun find_model thy {sizes, minsize, maxsize, maxvars, maxtime, satsolver} t negate =
   928 	let
   929 		(* unit -> unit *)
   930 		fun wrapper () =
   931 		let
   932 			(* Term.term list *)
   933 			val axioms = collect_axioms thy t
   934 			(* Term.typ list *)
   935 			val types  = Library.foldl (fn (acc, t') => acc union (ground_types thy t')) ([], t :: axioms)
   936 			val _      = writeln ("Ground types: "
   937 				^ (if null types then "none."
   938 				   else commas (map (Sign.string_of_typ (sign_of thy)) types)))
   939 			(* we can only consider fragments of recursive IDTs, so we issue a  *)
   940 			(* warning if the formula contains a recursive IDT                  *)
   941 			(* TODO: no warning needed for /positive/ occurrences of IDTs       *)
   942 			val _ = if Library.exists (fn
   943 				  Type (s, _) =>
   944 					(case DatatypePackage.datatype_info thy s of
   945 					  SOME info =>  (* inductive datatype *)
   946 						let
   947 							val index           = #index info
   948 							val descr           = #descr info
   949 							val (_, _, constrs) = (valOf o assoc) (descr, index)
   950 						in
   951 							(* recursive datatype? *)
   952 							Library.exists (fn (_, ds) => Library.exists DatatypeAux.is_rec_type ds) constrs
   953 						end
   954 					| NONE => false)
   955 				| _ => false) types then
   956 					warning "Term contains a recursive datatype; countermodel(s) may be spurious!"
   957 				else
   958 					()
   959 			(* (Term.typ * int) list -> unit *)
   960 			fun find_model_loop universe =
   961 			let
   962 				val init_model             = (universe, [])
   963 				val init_args              = {maxvars = maxvars, def_eq = false, next_idx = 1, bounds = [], wellformed = True}
   964 				val _                      = immediate_output ("Translating term (sizes: " ^ commas (map (fn (_, n) => string_of_int n) universe) ^ ") ...")
   965 				(* translate 't' and all axioms *)
   966 				val ((model, args), intrs) = foldl_map (fn ((m, a), t') =>
   967 					let
   968 						val (i, m', a') = interpret thy m a t'
   969 					in
   970 						(* set 'def_eq' to 'true' *)
   971 						((m', {maxvars = #maxvars a', def_eq = true, next_idx = #next_idx a', bounds = #bounds a', wellformed = #wellformed a'}), i)
   972 					end) ((init_model, init_args), t :: axioms)
   973 				(* make 't' either true or false, and make all axioms true, and *)
   974 				(* add the well-formedness side condition                       *)
   975 				val fm_t  = (if negate then toFalse else toTrue) (hd intrs)
   976 				val fm_ax = PropLogic.all (map toTrue (tl intrs))
   977 				val fm    = PropLogic.all [#wellformed args, fm_ax, fm_t]
   978 			in
   979 				immediate_output " invoking SAT solver...";
   980 				(case SatSolver.invoke_solver satsolver fm of
   981 				  SatSolver.SATISFIABLE assignment =>
   982 					(writeln " model found!";
   983 					writeln ("*** Model found: ***\n" ^ print_model thy model (fn i => case assignment i of SOME b => b | NONE => true)))
   984 				| SatSolver.UNSATISFIABLE =>
   985 					(immediate_output " no model exists.\n";
   986 					case next_universe universe sizes minsize maxsize of
   987 					  SOME universe' => find_model_loop universe'
   988 					| NONE           => writeln "Search terminated, no larger universe within the given limits.")
   989 				| SatSolver.UNKNOWN =>
   990 					(immediate_output " no model found.\n";
   991 					case next_universe universe sizes minsize maxsize of
   992 					  SOME universe' => find_model_loop universe'
   993 					| NONE           => writeln "Search terminated, no larger universe within the given limits.")
   994 				) handle SatSolver.NOT_CONFIGURED =>
   995 					error ("SAT solver " ^ quote satsolver ^ " is not configured.")
   996 			end handle MAXVARS_EXCEEDED =>
   997 				writeln ("\nSearch terminated, number of Boolean variables (" ^ string_of_int maxvars ^ " allowed) exceeded.")
   998 			in
   999 				find_model_loop (first_universe types sizes minsize)
  1000 			end
  1001 		in
  1002 			(* some parameter sanity checks *)
  1003 			assert (minsize>=1) ("\"minsize\" is " ^ string_of_int minsize ^ ", must be at least 1");
  1004 			assert (maxsize>=1) ("\"maxsize\" is " ^ string_of_int maxsize ^ ", must be at least 1");
  1005 			assert (maxsize>=minsize) ("\"maxsize\" (=" ^ string_of_int maxsize ^ ") is less than \"minsize\" (=" ^ string_of_int minsize ^ ").");
  1006 			assert (maxvars>=0) ("\"maxvars\" is " ^ string_of_int maxvars ^ ", must be at least 0");
  1007 			assert (maxtime>=0) ("\"maxtime\" is " ^ string_of_int maxtime ^ ", must be at least 0");
  1008 			(* enter loop with or without time limit *)
  1009 			writeln ("Trying to find a model that " ^ (if negate then "refutes" else "satisfies") ^ ": "
  1010 				^ Sign.string_of_term (sign_of thy) t);
  1011 			if maxtime>0 then (
  1012 				TimeLimit.timeLimit (Time.fromSeconds (Int.toLarge maxtime))
  1013 					wrapper ()
  1014 				handle TimeLimit.TimeOut =>
  1015 					writeln ("\nSearch terminated, time limit ("
  1016 						^ string_of_int maxtime ^ (if maxtime=1 then " second" else " seconds")
  1017 						^ ") exceeded.")
  1018 			) else
  1019 				wrapper ()
  1020 		end;
  1021 
  1022 
  1023 (* ------------------------------------------------------------------------- *)
  1024 (* INTERFACE, PART 2: FINDING A MODEL                                        *)
  1025 (* ------------------------------------------------------------------------- *)
  1026 
  1027 (* ------------------------------------------------------------------------- *)
  1028 (* satisfy_term: calls 'find_model' to find a model that satisfies 't'       *)
  1029 (* params      : list of '(name, value)' pairs used to override default      *)
  1030 (*               parameters                                                  *)
  1031 (* ------------------------------------------------------------------------- *)
  1032 
  1033 	(* theory -> (string * string) list -> Term.term -> unit *)
  1034 
  1035 	fun satisfy_term thy params t =
  1036 		find_model thy (actual_params thy params) t false;
  1037 
  1038 (* ------------------------------------------------------------------------- *)
  1039 (* refute_term: calls 'find_model' to find a model that refutes 't'          *)
  1040 (* params     : list of '(name, value)' pairs used to override default       *)
  1041 (*              parameters                                                   *)
  1042 (* ------------------------------------------------------------------------- *)
  1043 
  1044 	(* theory -> (string * string) list -> Term.term -> unit *)
  1045 
  1046 	fun refute_term thy params t =
  1047 	let
  1048 		(* disallow schematic type variables, since we cannot properly negate  *)
  1049 		(* terms containing them (their logical meaning is that there EXISTS a *)
  1050 		(* type s.t. ...; to refute such a formula, we would have to show that *)
  1051 		(* for ALL types, not ...)                                             *)
  1052 		val _ = assert (null (term_tvars t)) "Term to be refuted contains schematic type variables"
  1053 		(* existential closure over schematic variables *)
  1054 		(* (Term.indexname * Term.typ) list *)
  1055 		val vars = sort_wrt (fst o fst) (map dest_Var (term_vars t))
  1056 		(* Term.term *)
  1057 		val ex_closure = Library.foldl
  1058 			(fn (t', ((x, i), T)) => (HOLogic.exists_const T) $ Abs (x, T, abstract_over (Var ((x, i), T), t')))
  1059 			(t, vars)
  1060 		(* If 't' is of type 'propT' (rather than 'boolT'), applying  *)
  1061 		(* 'HOLogic.exists_const' is not type-correct.  However, this *)
  1062 		(* is not really a problem as long as 'find_model' still      *)
  1063 		(* interprets the resulting term correctly, without checking  *)
  1064 		(* its type.                                                  *)
  1065 	in
  1066 		find_model thy (actual_params thy params) ex_closure true
  1067 	end;
  1068 
  1069 (* ------------------------------------------------------------------------- *)
  1070 (* refute_subgoal: calls 'refute_term' on a specific subgoal                 *)
  1071 (* params        : list of '(name, value)' pairs used to override default    *)
  1072 (*                 parameters                                                *)
  1073 (* subgoal       : 0-based index specifying the subgoal number               *)
  1074 (* ------------------------------------------------------------------------- *)
  1075 
  1076 	(* theory -> (string * string) list -> Thm.thm -> int -> unit *)
  1077 
  1078 	fun refute_subgoal thy params thm subgoal =
  1079 		refute_term thy params (List.nth (prems_of thm, subgoal));
  1080 
  1081 
  1082 (* ------------------------------------------------------------------------- *)
  1083 (* INTERPRETERS: Auxiliary Functions                                         *)
  1084 (* ------------------------------------------------------------------------- *)
  1085 
  1086 (* ------------------------------------------------------------------------- *)
  1087 (* make_constants: returns all interpretations that have the same tree       *)
  1088 (*                 structure as 'intr', but consist of unit vectors with     *)
  1089 (*                 'True'/'False' only (no Boolean variables)                *)
  1090 (* ------------------------------------------------------------------------- *)
  1091 
  1092 	(* interpretation -> interpretation list *)
  1093 
  1094 	fun make_constants intr =
  1095 	let
  1096 		(* returns a list with all unit vectors of length n *)
  1097 		(* int -> interpretation list *)
  1098 		fun unit_vectors n =
  1099 		let
  1100 			(* returns the k-th unit vector of length n *)
  1101 			(* int * int -> interpretation *)
  1102 			fun unit_vector (k,n) =
  1103 				Leaf ((replicate (k-1) False) @ (True :: (replicate (n-k) False)))
  1104 			(* int -> interpretation list -> interpretation list *)
  1105 			fun unit_vectors_acc k vs =
  1106 				if k>n then [] else (unit_vector (k,n))::(unit_vectors_acc (k+1) vs)
  1107 		in
  1108 			unit_vectors_acc 1 []
  1109 		end
  1110 		(* concatenates 'x' with every list in 'xss', returning a new list of lists *)
  1111 		(* 'a -> 'a list list -> 'a list list *)
  1112 		fun cons_list x xss =
  1113 			map (fn xs => x::xs) xss
  1114 		(* returns a list of lists, each one consisting of n (possibly identical) elements from 'xs' *)
  1115 		(* int -> 'a list -> 'a list list *)
  1116 		fun pick_all 1 xs =
  1117 			map (fn x => [x]) xs
  1118 		  | pick_all n xs =
  1119 			let val rec_pick = pick_all (n-1) xs in
  1120 				Library.foldl (fn (acc, x) => (cons_list x rec_pick) @ acc) ([], xs)
  1121 			end
  1122 	in
  1123 		case intr of
  1124 		  Leaf xs => unit_vectors (length xs)
  1125 		| Node xs => map (fn xs' => Node xs') (pick_all (length xs) (make_constants (hd xs)))
  1126 	end;
  1127 
  1128 (* ------------------------------------------------------------------------- *)
  1129 (* size_of_type: returns the number of constants in a type (i.e. 'length     *)
  1130 (*               (make_constants intr)', but implemented more efficiently)   *)
  1131 (* ------------------------------------------------------------------------- *)
  1132 
  1133 	(* interpretation -> int *)
  1134 
  1135 	fun size_of_type intr =
  1136 	let
  1137 		(* power (a, b) computes a^b, for a>=0, b>=0 *)
  1138 		(* int * int -> int *)
  1139 		fun power (a, 0) = 1
  1140 		  | power (a, 1) = a
  1141 		  | power (a, b) = let val ab = power(a, b div 2) in ab * ab * power(a, b mod 2) end
  1142 	in
  1143 		case intr of
  1144 		  Leaf xs => length xs
  1145 		| Node xs => power (size_of_type (hd xs), length xs)
  1146 	end;
  1147 
  1148 (* ------------------------------------------------------------------------- *)
  1149 (* TT/FF: interpretations that denote "true" or "false", respectively        *)
  1150 (* ------------------------------------------------------------------------- *)
  1151 
  1152 	(* interpretation *)
  1153 
  1154 	val TT = Leaf [True, False];
  1155 
  1156 	val FF = Leaf [False, True];
  1157 
  1158 (* ------------------------------------------------------------------------- *)
  1159 (* make_equality: returns an interpretation that denotes (extensional)       *)
  1160 (*                equality of two interpretations                            *)
  1161 (* - two interpretations are 'equal' iff they are both defined and denote    *)
  1162 (*   the same value                                                          *)
  1163 (* - two interpretations are 'not_equal' iff they are both defined at least  *)
  1164 (*   partially, and a defined part denotes different values                  *)
  1165 (* - a completely undefined interpretation is neither 'equal' nor            *)
  1166 (*   'not_equal' to another interpretation                                   *)
  1167 (* ------------------------------------------------------------------------- *)
  1168 
  1169 	(* We could in principle represent '=' on a type T by a particular        *)
  1170 	(* interpretation.  However, the size of that interpretation is quadratic *)
  1171 	(* in the size of T.  Therefore comparing the interpretations 'i1' and    *)
  1172 	(* 'i2' directly is more efficient than constructing the interpretation   *)
  1173 	(* for equality on T first, and "applying" this interpretation to 'i1'    *)
  1174 	(* and 'i2' in the usual way (cf. 'interpretation_apply') then.           *)
  1175 
  1176 	(* interpretation * interpretation -> interpretation *)
  1177 
  1178 	fun make_equality (i1, i2) =
  1179 	let
  1180 		(* interpretation * interpretation -> prop_formula *)
  1181 		fun equal (i1, i2) =
  1182 			(case i1 of
  1183 			  Leaf xs =>
  1184 				(case i2 of
  1185 				  Leaf ys => PropLogic.dot_product (xs, ys)  (* defined and equal *)
  1186 				| Node _  => raise REFUTE ("make_equality", "second interpretation is higher"))
  1187 			| Node xs =>
  1188 				(case i2 of
  1189 				  Leaf _  => raise REFUTE ("make_equality", "first interpretation is higher")
  1190 				| Node ys => PropLogic.all (map equal (xs ~~ ys))))
  1191 		(* interpretation * interpretation -> prop_formula *)
  1192 		fun not_equal (i1, i2) =
  1193 			(case i1 of
  1194 			  Leaf xs =>
  1195 				(case i2 of
  1196 				  Leaf ys => PropLogic.all ((PropLogic.exists xs) :: (PropLogic.exists ys) ::
  1197 					(map (fn (x,y) => SOr (SNot x, SNot y)) (xs ~~ ys)))  (* defined and not equal *)
  1198 				| Node _  => raise REFUTE ("make_equality", "second interpretation is higher"))
  1199 			| Node xs =>
  1200 				(case i2 of
  1201 				  Leaf _  => raise REFUTE ("make_equality", "first interpretation is higher")
  1202 				| Node ys => PropLogic.exists (map not_equal (xs ~~ ys))))
  1203 	in
  1204 		(* a value may be undefined; therefore 'not_equal' is not just the     *)
  1205 		(* negation of 'equal'                                                 *)
  1206 		Leaf [equal (i1, i2), not_equal (i1, i2)]
  1207 	end;
  1208 
  1209 (* ------------------------------------------------------------------------- *)
  1210 (* make_def_equality: returns an interpretation that denotes (extensional)   *)
  1211 (*                    equality of two interpretations                        *)
  1212 (* This function treats undefined/partially defined interpretations          *)
  1213 (* different from 'make_equality': two undefined interpretations are         *)
  1214 (* considered equal, while a defined interpretation is considered not equal  *)
  1215 (* to an undefined interpretation.                                           *)
  1216 (* ------------------------------------------------------------------------- *)
  1217 
  1218 	(* interpretation * interpretation -> interpretation *)
  1219 
  1220 	fun make_def_equality (i1, i2) =
  1221 	let
  1222 		(* interpretation * interpretation -> prop_formula *)
  1223 		fun equal (i1, i2) =
  1224 			(case i1 of
  1225 			  Leaf xs =>
  1226 				(case i2 of
  1227 				  Leaf ys => SOr (PropLogic.dot_product (xs, ys),  (* defined and equal, or both undefined *)
  1228 					SAnd (PropLogic.all (map SNot xs), PropLogic.all (map SNot ys)))
  1229 				| Node _  => raise REFUTE ("make_def_equality", "second interpretation is higher"))
  1230 			| Node xs =>
  1231 				(case i2 of
  1232 				  Leaf _  => raise REFUTE ("make_def_equality", "first interpretation is higher")
  1233 				| Node ys => PropLogic.all (map equal (xs ~~ ys))))
  1234 		(* interpretation *)
  1235 		val eq = equal (i1, i2)
  1236 	in
  1237 		Leaf [eq, SNot eq]
  1238 	end;
  1239 
  1240 (* ------------------------------------------------------------------------- *)
  1241 (* interpretation_apply: returns an interpretation that denotes the result   *)
  1242 (*                       of applying the function denoted by 'i2' to the     *)
  1243 (*                       argument denoted by 'i2'                            *)
  1244 (* ------------------------------------------------------------------------- *)
  1245 
  1246 	(* interpretation * interpretation -> interpretation *)
  1247 
  1248 	fun interpretation_apply (i1, i2) =
  1249 	let
  1250 		(* interpretation * interpretation -> interpretation *)
  1251 		fun interpretation_disjunction (tr1,tr2) =
  1252 			tree_map (fn (xs,ys) => map (fn (x,y) => SOr(x,y)) (xs ~~ ys)) (tree_pair (tr1,tr2))
  1253 		(* prop_formula * interpretation -> interpretation *)
  1254 		fun prop_formula_times_interpretation (fm,tr) =
  1255 			tree_map (map (fn x => SAnd (fm,x))) tr
  1256 		(* prop_formula list * interpretation list -> interpretation *)
  1257 		fun prop_formula_list_dot_product_interpretation_list ([fm],[tr]) =
  1258 			prop_formula_times_interpretation (fm,tr)
  1259 		  | prop_formula_list_dot_product_interpretation_list (fm::fms,tr::trees) =
  1260 			interpretation_disjunction (prop_formula_times_interpretation (fm,tr), prop_formula_list_dot_product_interpretation_list (fms,trees))
  1261 		  | prop_formula_list_dot_product_interpretation_list (_,_) =
  1262 			raise REFUTE ("interpretation_apply", "empty list (in dot product)")
  1263 		(* concatenates 'x' with every list in 'xss', returning a new list of lists *)
  1264 		(* 'a -> 'a list list -> 'a list list *)
  1265 		fun cons_list x xss =
  1266 			map (fn xs => x::xs) xss
  1267 		(* returns a list of lists, each one consisting of one element from each element of 'xss' *)
  1268 		(* 'a list list -> 'a list list *)
  1269 		fun pick_all [xs] =
  1270 			map (fn x => [x]) xs
  1271 		  | pick_all (xs::xss) =
  1272 			let val rec_pick = pick_all xss in
  1273 				Library.foldl (fn (acc, x) => (cons_list x rec_pick) @ acc) ([], xs)
  1274 			end
  1275 		  | pick_all _ =
  1276 			raise REFUTE ("interpretation_apply", "empty list (in pick_all)")
  1277 		(* interpretation -> prop_formula list *)
  1278 		fun interpretation_to_prop_formula_list (Leaf xs) =
  1279 			xs
  1280 		  | interpretation_to_prop_formula_list (Node trees) =
  1281 			map PropLogic.all (pick_all (map interpretation_to_prop_formula_list trees))
  1282 	in
  1283 		case i1 of
  1284 		  Leaf _ =>
  1285 			raise REFUTE ("interpretation_apply", "first interpretation is a leaf")
  1286 		| Node xs =>
  1287 			prop_formula_list_dot_product_interpretation_list (interpretation_to_prop_formula_list i2, xs)
  1288 	end;
  1289 
  1290 (* ------------------------------------------------------------------------- *)
  1291 (* eta_expand: eta-expands a term 't' by adding 'i' lambda abstractions      *)
  1292 (* ------------------------------------------------------------------------- *)
  1293 
  1294 	(* Term.term -> int -> Term.term *)
  1295 
  1296 	fun eta_expand t i =
  1297 	let
  1298 		val Ts = binder_types (fastype_of t)
  1299 	in
  1300 		foldr (fn (T, t) => Abs ("<eta_expand>", T, t))
  1301 			(list_comb (t, map Bound (i-1 downto 0))) (Library.take (i, Ts))
  1302 	end;
  1303 
  1304 (* ------------------------------------------------------------------------- *)
  1305 (* sum: returns the sum of a list 'xs' of integers                           *)
  1306 (* ------------------------------------------------------------------------- *)
  1307 
  1308 	(* int list -> int *)
  1309 
  1310 	fun sum xs = foldl op+ 0 xs;
  1311 
  1312 (* ------------------------------------------------------------------------- *)
  1313 (* product: returns the product of a list 'xs' of integers                   *)
  1314 (* ------------------------------------------------------------------------- *)
  1315 
  1316 	(* int list -> int *)
  1317 
  1318 	fun product xs = foldl op* 1 xs;
  1319 
  1320 (* ------------------------------------------------------------------------- *)
  1321 (* size_of_dtyp: the size of (an initial fragment of) an inductive data type *)
  1322 (*               is the sum (over its constructors) of the product (over     *)
  1323 (*               their arguments) of the size of the argument types          *)
  1324 (* ------------------------------------------------------------------------- *)
  1325 
  1326 	(* theory -> (Term.typ * int) list -> DatatypeAux.descr -> (DatatypeAux.dtyp * Term.typ) list -> (string * DatatypeAux.dtyp list) list -> int *)
  1327 
  1328 	fun size_of_dtyp thy typ_sizes descr typ_assoc constructors =
  1329 		sum (map (fn (_, dtyps) =>
  1330 			product (map (fn dtyp =>
  1331 				let
  1332 					val T         = typ_of_dtyp descr typ_assoc dtyp
  1333 					val (i, _, _) = interpret thy (typ_sizes, []) {maxvars=0, def_eq = false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  1334 				in
  1335 					size_of_type i
  1336 				end) dtyps)) constructors);
  1337 
  1338 
  1339 (* ------------------------------------------------------------------------- *)
  1340 (* INTERPRETERS: Actual Interpreters                                         *)
  1341 (* ------------------------------------------------------------------------- *)
  1342 
  1343 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1344 
  1345 	(* simply typed lambda calculus: Isabelle's basic term syntax, with type  *)
  1346 	(* variables, function types, and propT                                   *)
  1347 
  1348 	fun stlc_interpreter thy model args t =
  1349 	let
  1350 		val (typs, terms)                                   = model
  1351 		val {maxvars, def_eq, next_idx, bounds, wellformed} = args
  1352 		(* Term.typ -> (interpretation * model * arguments) option *)
  1353 		fun interpret_groundterm T =
  1354 		let
  1355 			(* unit -> (interpretation * model * arguments) option *)
  1356 			fun interpret_groundtype () =
  1357 			let
  1358 				val size = (if T = Term.propT then 2 else (valOf o assoc) (typs, T))                    (* the model MUST specify a size for ground types *)
  1359 				val next = next_idx+size
  1360 				val _    = (if next-1>maxvars andalso maxvars>0 then raise MAXVARS_EXCEEDED else ())  (* check if 'maxvars' is large enough *)
  1361 				(* prop_formula list *)
  1362 				val fms  = map BoolVar (next_idx upto (next_idx+size-1))
  1363 				(* interpretation *)
  1364 				val intr = Leaf fms
  1365 				(* prop_formula list -> prop_formula *)
  1366 				fun one_of_two_false []      = True
  1367 				  | one_of_two_false (x::xs) = SAnd (PropLogic.all (map (fn x' => SOr (SNot x, SNot x')) xs), one_of_two_false xs)
  1368 				(* prop_formula *)
  1369 				val wf   = one_of_two_false fms
  1370 			in
  1371 				(* extend the model, increase 'next_idx', add well-formedness condition *)
  1372 				SOME (intr, (typs, (t, intr)::terms), {maxvars = maxvars, def_eq = def_eq, next_idx = next, bounds = bounds, wellformed = SAnd (wellformed, wf)})
  1373 			end
  1374 		in
  1375 			case T of
  1376 			  Type ("fun", [T1, T2]) =>
  1377 				let
  1378 					(* we create 'size_of_type (interpret (... T1))' different copies *)
  1379 					(* of the interpretation for 'T2', which are then combined into a *)
  1380 					(* single new interpretation                                      *)
  1381 					val (i1, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T1))
  1382 					(* make fresh copies, with different variable indices *)
  1383 					(* 'idx': next variable index                         *)
  1384 					(* 'n'  : number of copies                            *)
  1385 					(* int -> int -> (int * interpretation list * prop_formula *)
  1386 					fun make_copies idx 0 =
  1387 						(idx, [], True)
  1388 					  | make_copies idx n =
  1389 						let
  1390 							val (copy, _, new_args) = interpret thy (typs, []) {maxvars = maxvars, def_eq = false, next_idx = idx, bounds = [], wellformed = True} (Free ("dummy", T2))
  1391 							val (idx', copies, wf') = make_copies (#next_idx new_args) (n-1)
  1392 						in
  1393 							(idx', copy :: copies, SAnd (#wellformed new_args, wf'))
  1394 						end
  1395 					val (next, copies, wf) = make_copies next_idx (size_of_type i1)
  1396 					(* combine copies into a single interpretation *)
  1397 					val intr = Node copies
  1398 				in
  1399 					(* extend the model, increase 'next_idx', add well-formedness condition *)
  1400 					SOME (intr, (typs, (t, intr)::terms), {maxvars = maxvars, def_eq = def_eq, next_idx = next, bounds = bounds, wellformed = SAnd (wellformed, wf)})
  1401 				end
  1402 			| Type _  => interpret_groundtype ()
  1403 			| TFree _ => interpret_groundtype ()
  1404 			| TVar  _ => interpret_groundtype ()
  1405 		end
  1406 	in
  1407 		case assoc (terms, t) of
  1408 		  SOME intr =>
  1409 			(* return an existing interpretation *)
  1410 			SOME (intr, model, args)
  1411 		| NONE =>
  1412 			(case t of
  1413 			  Const (_, T)     =>
  1414 				interpret_groundterm T
  1415 			| Free (_, T)      =>
  1416 				interpret_groundterm T
  1417 			| Var (_, T)       =>
  1418 				interpret_groundterm T
  1419 			| Bound i          =>
  1420 				SOME (List.nth (#bounds args, i), model, args)
  1421 			| Abs (x, T, body) =>
  1422 				let
  1423 					(* create all constants of type 'T' *)
  1424 					val (i, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  1425 					val constants = make_constants i
  1426 					(* interpret the 'body' separately for each constant *)
  1427 					val ((model', args'), bodies) = foldl_map
  1428 						(fn ((m, a), c) =>
  1429 							let
  1430 								(* add 'c' to 'bounds' *)
  1431 								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
  1432 							in
  1433 								(* keep the new model m' and 'next_idx' and 'wellformed', but use old 'bounds' *)
  1434 								((m', {maxvars = maxvars, def_eq = def_eq, next_idx = #next_idx a', bounds = bounds, wellformed = #wellformed a'}), i')
  1435 							end)
  1436 						((model, args), constants)
  1437 				in
  1438 					SOME (Node bodies, model', args')
  1439 				end
  1440 			| t1 $ t2          =>
  1441 				let
  1442 					(* interpret 't1' and 't2' separately *)
  1443 					val (intr1, model1, args1) = interpret thy model args t1
  1444 					val (intr2, model2, args2) = interpret thy model1 args1 t2
  1445 				in
  1446 					SOME (interpretation_apply (intr1, intr2), model2, args2)
  1447 				end)
  1448 	end;
  1449 
  1450 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1451 
  1452 	fun Pure_interpreter thy model args t =
  1453 		case t of
  1454 		  Const ("all", _) $ t1 =>  (* in the meta-logic, 'all' MUST be followed by an argument term *)
  1455 			let
  1456 				val (i, m, a) = interpret thy model args t1
  1457 			in
  1458 				case i of
  1459 				  Node xs =>
  1460 					let
  1461 						val fmTrue  = PropLogic.all (map toTrue xs)
  1462 						val fmFalse = PropLogic.exists (map toFalse xs)
  1463 					in
  1464 						SOME (Leaf [fmTrue, fmFalse], m, a)
  1465 					end
  1466 				| _ =>
  1467 					raise REFUTE ("Pure_interpreter", "\"all\" is not followed by a function")
  1468 			end
  1469 		| Const ("==", _) $ t1 $ t2 =>
  1470 			let
  1471 				val (i1, m1, a1) = interpret thy model args t1
  1472 				val (i2, m2, a2) = interpret thy m1 a1 t2
  1473 			in
  1474 				(* we use either 'make_def_equality' or 'make_equality' *)
  1475 				SOME ((if #def_eq args then make_def_equality else make_equality) (i1, i2), m2, a2)
  1476 			end
  1477 		| Const ("==>", _) =>  (* simpler than translating 'Const ("==>", _) $ t1 $ t2' *)
  1478 			SOME (Node [Node [TT, FF], Node [TT, TT]], model, args)
  1479 		| _ => NONE;
  1480 
  1481 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1482 
  1483 	fun HOLogic_interpreter thy model args t =
  1484 	(* ------------------------------------------------------------------------- *)
  1485 	(* Providing interpretations directly is more efficient than unfolding the   *)
  1486 	(* logical constants.  In HOL however, logical constants can themselves be   *)
  1487 	(* arguments.  "All" and "Ex" are then translated just like any other        *)
  1488 	(* constant, with the relevant axiom being added by 'collect_axioms'.        *)
  1489 	(* ------------------------------------------------------------------------- *)
  1490 		case t of
  1491 		  Const ("Trueprop", _) =>
  1492 			SOME (Node [TT, FF], model, args)
  1493 		| Const ("Not", _) =>
  1494 			SOME (Node [FF, TT], model, args)
  1495 		| Const ("True", _) =>  (* redundant, since 'True' is also an IDT constructor *)
  1496 			SOME (TT, model, args)
  1497 		| Const ("False", _) =>  (* redundant, since 'False' is also an IDT constructor *)
  1498 			SOME (FF, model, args)
  1499 		| Const ("All", _) $ t1 =>
  1500 		(* if "All" occurs without an argument (i.e. as argument to a higher-order *)
  1501 		(* function or predicate), it is handled by the 'stlc_interpreter' (i.e.   *)
  1502 		(* by unfolding its definition)                                            *)
  1503 			let
  1504 				val (i, m, a) = interpret thy model args t1
  1505 			in
  1506 				case i of
  1507 				  Node xs =>
  1508 					let
  1509 						val fmTrue  = PropLogic.all (map toTrue xs)
  1510 						val fmFalse = PropLogic.exists (map toFalse xs)
  1511 					in
  1512 						SOME (Leaf [fmTrue, fmFalse], m, a)
  1513 					end
  1514 				| _ =>
  1515 					raise REFUTE ("HOLogic_interpreter", "\"All\" is followed by a non-function")
  1516 			end
  1517 		| Const ("Ex", _) $ t1 =>
  1518 		(* if "Ex" occurs without an argument (i.e. as argument to a higher-order  *)
  1519 		(* function or predicate), it is handled by the 'stlc_interpreter' (i.e.   *)
  1520 		(* by unfolding its definition)                                            *)
  1521 			let
  1522 				val (i, m, a) = interpret thy model args t1
  1523 			in
  1524 				case i of
  1525 				  Node xs =>
  1526 					let
  1527 						val fmTrue  = PropLogic.exists (map toTrue xs)
  1528 						val fmFalse = PropLogic.all (map toFalse xs)
  1529 					in
  1530 						SOME (Leaf [fmTrue, fmFalse], m, a)
  1531 					end
  1532 				| _ =>
  1533 					raise REFUTE ("HOLogic_interpreter", "\"Ex\" is followed by a non-function")
  1534 			end
  1535 		| Const ("op =", _) $ t1 $ t2 =>
  1536 			let
  1537 				val (i1, m1, a1) = interpret thy model args t1
  1538 				val (i2, m2, a2) = interpret thy m1 a1 t2
  1539 			in
  1540 				SOME (make_equality (i1, i2), m2, a2)
  1541 			end
  1542 		| Const ("op =", _) $ t1 =>
  1543 			SOME (interpret thy model args (eta_expand t 1))
  1544 		| Const ("op =", _) =>
  1545 			SOME (interpret thy model args (eta_expand t 2))
  1546 		| Const ("op &", _) $ t1 $ t2 =>
  1547 			(* 3-valued logic *)
  1548 			let
  1549 				val (i1, m1, a1) = interpret thy model args t1
  1550 				val (i2, m2, a2) = interpret thy m1 a1 t2
  1551 				val fmTrue       = PropLogic.SAnd (toTrue i1, toTrue i2)
  1552 				val fmFalse      = PropLogic.SOr (toFalse i1, toFalse i2)
  1553 			in
  1554 				SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1555 			end
  1556 		| Const ("op &", _) $ t1 =>
  1557 			SOME (interpret thy model args (eta_expand t 1))
  1558 		| Const ("op &", _) =>
  1559 			SOME (interpret thy model args (eta_expand t 2))
  1560 			(* SOME (Node [Node [TT, FF], Node [FF, FF]], model, args) *)
  1561 		| Const ("op |", _) $ t1 $ t2 =>
  1562 			(* 3-valued logic *)
  1563 			let
  1564 				val (i1, m1, a1) = interpret thy model args t1
  1565 				val (i2, m2, a2) = interpret thy m1 a1 t2
  1566 				val fmTrue       = PropLogic.SOr (toTrue i1, toTrue i2)
  1567 				val fmFalse      = PropLogic.SAnd (toFalse i1, toFalse i2)
  1568 			in
  1569 				SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1570 			end
  1571 		| Const ("op |", _) $ t1 =>
  1572 			SOME (interpret thy model args (eta_expand t 1))
  1573 		| Const ("op |", _) =>
  1574 			SOME (interpret thy model args (eta_expand t 2))
  1575 			(* SOME (Node [Node [TT, TT], Node [TT, FF]], model, args) *)
  1576 		| Const ("op -->", _) $ t1 $ t2 =>
  1577 			(* 3-valued logic *)
  1578 			let
  1579 				val (i1, m1, a1) = interpret thy model args t1
  1580 				val (i2, m2, a2) = interpret thy m1 a1 t2
  1581 				val fmTrue       = PropLogic.SOr (toFalse i1, toTrue i2)
  1582 				val fmFalse      = PropLogic.SAnd (toTrue i1, toFalse i2)
  1583 			in
  1584 				SOME (Leaf [fmTrue, fmFalse], m2, a2)
  1585 			end
  1586 		| Const ("op -->", _) =>
  1587 			(* SOME (Node [Node [TT, FF], Node [TT, TT]], model, args) *)
  1588 			SOME (interpret thy model args (eta_expand t 2))
  1589 		| _ => NONE;
  1590 
  1591 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1592 
  1593 	fun set_interpreter thy model args t =
  1594 	(* "T set" is isomorphic to "T --> bool" *)
  1595 	let
  1596 		val (typs, terms) = model
  1597 	in
  1598 		case assoc (terms, t) of
  1599 		  SOME intr =>
  1600 			(* return an existing interpretation *)
  1601 			SOME (intr, model, args)
  1602 		| NONE =>
  1603 			(case t of
  1604 			  Free (x, Type ("set", [T])) =>
  1605 				let
  1606 					val (intr, _, args') = interpret thy (typs, []) args (Free (x, T --> HOLogic.boolT))
  1607 				in
  1608 					SOME (intr, (typs, (t, intr)::terms), args')
  1609 				end
  1610 			| Var ((x,i), Type ("set", [T])) =>
  1611 				let
  1612 					val (intr, _, args') = interpret thy (typs, []) args (Var ((x,i), T --> HOLogic.boolT))
  1613 				in
  1614 					SOME (intr, (typs, (t, intr)::terms), args')
  1615 				end
  1616 			| Const (s, Type ("set", [T])) =>
  1617 				let
  1618 					val (intr, _, args') = interpret thy (typs, []) args (Const (s, T --> HOLogic.boolT))
  1619 				in
  1620 					SOME (intr, (typs, (t, intr)::terms), args')
  1621 				end
  1622 			(* 'Collect' == identity *)
  1623 			| Const ("Collect", _) $ t1 =>
  1624 				SOME (interpret thy model args t1)
  1625 			| Const ("Collect", _) =>
  1626 				SOME (interpret thy model args (eta_expand t 1))
  1627 			(* 'op :' == application *)
  1628 			| Const ("op :", _) $ t1 $ t2 =>
  1629 				SOME (interpret thy model args (t2 $ t1))
  1630 			| Const ("op :", _) $ t1 =>
  1631 				SOME (interpret thy model args (eta_expand t 1))
  1632 			| Const ("op :", _) =>
  1633 				SOME (interpret thy model args (eta_expand t 2))
  1634 			| _ => NONE)
  1635 	end;
  1636 
  1637 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1638 
  1639 	(* interprets variables and constants whose type is an IDT; constructors of  *)
  1640 	(* IDTs are properly interpreted by 'IDT_constructor_interpreter' however    *)
  1641 
  1642 	fun IDT_interpreter thy model args t =
  1643 	let
  1644 		val (typs, terms) = model
  1645 		(* Term.typ -> (interpretation * model * arguments) option *)
  1646 		fun interpret_term (Type (s, Ts)) =
  1647 			(case DatatypePackage.datatype_info thy s of
  1648 			  SOME info =>  (* inductive datatype *)
  1649 				let
  1650 					(* int option -- only recursive IDTs have an associated depth *)
  1651 					val depth = assoc (typs, Type (s, Ts))
  1652 				in
  1653 					if depth = (SOME 0) then  (* termination condition to avoid infinite recursion *)
  1654 						(* return a leaf of size 0 *)
  1655 						SOME (Leaf [], model, args)
  1656 					else
  1657 						let
  1658 							val index               = #index info
  1659 							val descr               = #descr info
  1660 							val (_, dtyps, constrs) = (valOf o assoc) (descr, index)
  1661 							val typ_assoc           = dtyps ~~ Ts
  1662 							(* sanity check: every element in 'dtyps' must be a 'DtTFree' *)
  1663 							val _ = (if Library.exists (fn d =>
  1664 									case d of DatatypeAux.DtTFree _ => false | _ => true) dtyps
  1665 								then
  1666 									raise REFUTE ("IDT_interpreter", "datatype argument (for type " ^ Sign.string_of_typ (sign_of thy) (Type (s, Ts)) ^ ") is not a variable")
  1667 								else
  1668 									())
  1669 							(* if the model specifies a depth for the current type, decrement it to avoid infinite recursion *)
  1670 							val typs'    = (case depth of NONE => typs | SOME n => overwrite (typs, (Type (s, Ts), n-1)))
  1671 							(* recursively compute the size of the datatype *)
  1672 							val size     = size_of_dtyp thy typs' descr typ_assoc constrs
  1673 							val next_idx = #next_idx args
  1674 							val next     = next_idx+size
  1675 							val _        = (if next-1>(#maxvars args) andalso (#maxvars args)>0 then raise MAXVARS_EXCEEDED else ())  (* check if 'maxvars' is large enough *)
  1676 							(* prop_formula list *)
  1677 							val fms      = map BoolVar (next_idx upto (next_idx+size-1))
  1678 							(* interpretation *)
  1679 							val intr     = Leaf fms
  1680 							(* prop_formula list -> prop_formula *)
  1681 							fun one_of_two_false []      = True
  1682 							  | one_of_two_false (x::xs) = SAnd (PropLogic.all (map (fn x' => SOr (SNot x, SNot x')) xs), one_of_two_false xs)
  1683 							(* prop_formula *)
  1684 							val wf       = one_of_two_false fms
  1685 						in
  1686 							(* extend the model, increase 'next_idx', add well-formedness condition *)
  1687 							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)})
  1688 						end
  1689 				end
  1690 			| NONE =>  (* not an inductive datatype *)
  1691 				NONE)
  1692 		  | interpret_term _ =  (* a (free or schematic) type variable *)
  1693 			NONE
  1694 	in
  1695 		case assoc (terms, t) of
  1696 		  SOME intr =>
  1697 			(* return an existing interpretation *)
  1698 			SOME (intr, model, args)
  1699 		| NONE =>
  1700 			(case t of
  1701 			  Free (_, T)  => interpret_term T
  1702 			| Var (_, T)   => interpret_term T
  1703 			| Const (_, T) => interpret_term T
  1704 			| _            => NONE)
  1705 	end;
  1706 
  1707 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1708 
  1709 	fun IDT_constructor_interpreter thy model args t =
  1710 	let
  1711 		val (typs, terms) = model
  1712 	in
  1713 		case assoc (terms, t) of
  1714 		  SOME intr =>
  1715 			(* return an existing interpretation *)
  1716 			SOME (intr, model, args)
  1717 		| NONE =>
  1718 			(case t of
  1719 			  Const (s, T) =>
  1720 				(case body_type T of
  1721 				  Type (s', Ts') =>
  1722 					(case DatatypePackage.datatype_info thy s' of
  1723 					  SOME info =>  (* body type is an inductive datatype *)
  1724 						let
  1725 							val index               = #index info
  1726 							val descr               = #descr info
  1727 							val (_, dtyps, constrs) = (valOf o assoc) (descr, index)
  1728 							val typ_assoc           = dtyps ~~ Ts'
  1729 							(* sanity check: every element in 'dtyps' must be a 'DtTFree' *)
  1730 							val _ = (if Library.exists (fn d =>
  1731 									case d of DatatypeAux.DtTFree _ => false | _ => true) dtyps
  1732 								then
  1733 									raise REFUTE ("IDT_constructor_interpreter", "datatype argument (for type " ^ Sign.string_of_typ (sign_of thy) (Type (s', Ts')) ^ ") is not a variable")
  1734 								else
  1735 									())
  1736 							(* split the constructors into those occuring before/after 'Const (s, T)' *)
  1737 							val (constrs1, constrs2) = take_prefix (fn (cname, ctypes) =>
  1738 								not (cname = s andalso Type.typ_instance (Sign.tsig_of (sign_of thy)) (T,
  1739 									map (typ_of_dtyp descr typ_assoc) ctypes ---> Type (s', Ts')))) constrs
  1740 						in
  1741 							case constrs2 of
  1742 							  [] =>
  1743 								(* 'Const (s, T)' is not a constructor of this datatype *)
  1744 								NONE
  1745 							| (_, ctypes)::cs =>
  1746 								let
  1747 									(* compute the total size of the datatype (with the current depth) *)
  1748 									val (i, _, _) = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type (s', Ts')))
  1749 									val total     = size_of_type i
  1750 									(* int option -- only recursive IDTs have an associated depth *)
  1751 									val depth = assoc (typs, Type (s', Ts'))
  1752 									val typs' = (case depth of NONE => typs | SOME n => overwrite (typs, (Type (s', Ts'), n-1)))
  1753 									(* returns an interpretation where everything is mapped to "undefined" *)
  1754 									(* DatatypeAux.dtyp list -> interpretation *)
  1755 									fun make_undef [] =
  1756 										Leaf (replicate total False)
  1757 									  | make_undef (d::ds) =
  1758 										let
  1759 											(* compute the current size of the type 'd' *)
  1760 											val T           = typ_of_dtyp descr typ_assoc d
  1761 											val (i, _, _)   = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  1762 											val size        = size_of_type i
  1763 										in
  1764 											Node (replicate size (make_undef ds))
  1765 										end
  1766 									(* returns the interpretation for a constructor at depth 1 *)
  1767 									(* int * DatatypeAux.dtyp list -> int * interpretation *)
  1768 									fun make_constr (offset, []) =
  1769 										if offset<total then
  1770 											(offset+1, Leaf ((replicate offset False) @ True :: (replicate (total-offset-1) False)))
  1771 										else
  1772 											raise REFUTE ("IDT_constructor_interpreter", "offset >= total")
  1773 									  | make_constr (offset, d::ds) =
  1774 										let
  1775 											(* compute the current and the old size of the type 'd' *)
  1776 											val T           = typ_of_dtyp descr typ_assoc d
  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 											val (i', _, _)  = interpret thy (typs', []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  1780 											val size'       = size_of_type i'
  1781 											(* sanity check *)
  1782 											val _           = if size < size' then
  1783 													raise REFUTE ("IDT_constructor_interpreter", "current size is less than old size")
  1784 												else
  1785 													()
  1786 											(* int * interpretation list *)
  1787 											val (new_offset, intrs) = foldl_map make_constr (offset, replicate size' ds)
  1788 											(* interpretation list *)
  1789 											val undefs              = replicate (size - size') (make_undef ds)
  1790 										in
  1791 											(* elements that exist at the previous depth are mapped to a defined *)
  1792 											(* value, while new elements are mapped to "undefined" by the        *)
  1793 											(* recursive constructor                                             *)
  1794 											(new_offset, Node (intrs @ undefs))
  1795 										end
  1796 									(* extends the interpretation for a constructor (both recursive *)
  1797 									(* and non-recursive) obtained at depth n (n>=1) to depth n+1   *)
  1798 									(* int * DatatypeAux.dtyp list * interpretation -> int * interpretation *)
  1799 									fun extend_constr (offset, [], Leaf xs) =
  1800 										let
  1801 											(* returns the k-th unit vector of length n *)
  1802 											(* int * int -> interpretation *)
  1803 											fun unit_vector (k, n) =
  1804 												Leaf ((replicate (k-1) False) @ (True :: (replicate (n-k) False)))
  1805 											(* int *)
  1806 											val k = find_index_eq True xs
  1807 										in
  1808 											if k=(~1) then
  1809 												(* if the element was mapped to "undefined" before, map it to   *)
  1810 												(* the value given by 'offset' now (and extend the length of    *)
  1811 												(* the leaf)                                                    *)
  1812 												(offset+1, unit_vector (offset+1, total))
  1813 											else
  1814 												(* if the element was already mapped to a defined value, map it *)
  1815 												(* to the same value again, just extend the length of the leaf, *)
  1816 												(* do not increment the 'offset'                                *)
  1817 												(offset, unit_vector (k+1, total))
  1818 										end
  1819 									  | extend_constr (_, [], Node _) =
  1820 										raise REFUTE ("IDT_constructor_interpreter", "interpretation for constructor (with no arguments left) is a node")
  1821 									  | extend_constr (offset, d::ds, Node xs) =
  1822 										let
  1823 											(* compute the size of the type 'd' *)
  1824 											val T          = typ_of_dtyp descr typ_assoc d
  1825 											val (i, _, _)  = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  1826 											val size       = size_of_type i
  1827 											(* sanity check *)
  1828 											val _          = if size < length xs then
  1829 													raise REFUTE ("IDT_constructor_interpreter", "new size of type is less than old size")
  1830 												else
  1831 													()
  1832 											(* extend the existing interpretations *)
  1833 											(* int * interpretation list *)
  1834 											val (new_offset, intrs) = foldl_map (fn (off, i) => extend_constr (off, ds, i)) (offset, xs)
  1835 											(* new elements of the type 'd' are mapped to "undefined" *)
  1836 											val undefs = replicate (size - length xs) (make_undef ds)
  1837 										in
  1838 											(new_offset, Node (intrs @ undefs))
  1839 										end
  1840 									  | extend_constr (_, d::ds, Leaf _) =
  1841 										raise REFUTE ("IDT_constructor_interpreter", "interpretation for constructor (with arguments left) is a leaf")
  1842 									(* returns 'true' iff the constructor has a recursive argument *)
  1843 									(* DatatypeAux.dtyp list -> bool *)
  1844 									fun is_rec_constr ds =
  1845 										Library.exists DatatypeAux.is_rec_type ds
  1846 									(* constructors before 'Const (s, T)' generate elements of the datatype *)
  1847 									val offset = size_of_dtyp thy typs' descr typ_assoc constrs1
  1848 								in
  1849 									case depth of
  1850 									  NONE =>  (* equivalent to a depth of 1 *)
  1851 										SOME (snd (make_constr (offset, ctypes)), model, args)
  1852 									| SOME 0 =>
  1853 										raise REFUTE ("IDT_constructor_interpreter", "depth is 0")
  1854 									| SOME 1 =>
  1855 										SOME (snd (make_constr (offset, ctypes)), model, args)
  1856 									| SOME n =>  (* n > 1 *)
  1857 										let
  1858 											(* interpret the constructor at depth-1 *)
  1859 											val (iC, _, _) = interpret thy (typs', []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Const (s, T))
  1860 											(* elements generated by the constructor at depth-1 must be added to 'offset' *)
  1861 											(* interpretation -> int *)
  1862 											fun number_of_defined_elements (Leaf xs) =
  1863 												if find_index_eq True xs = (~1) then 0 else 1
  1864 											  | number_of_defined_elements (Node xs) =
  1865 												sum (map number_of_defined_elements xs)
  1866 											(* int *)
  1867 											val offset' = offset + number_of_defined_elements iC
  1868 										in
  1869 											SOME (snd (extend_constr (offset', ctypes, iC)), model, args)
  1870 										end
  1871 								end
  1872 						end
  1873 					| NONE =>  (* body type is not an inductive datatype *)
  1874 						NONE)
  1875 				| _ =>  (* body type is a (free or schematic) type variable *)
  1876 					NONE)
  1877 			| _ =>  (* term is not a constant *)
  1878 				NONE)
  1879 	end;
  1880 
  1881 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  1882 
  1883 	(* Difficult code ahead.  Make sure you understand the 'IDT_constructor_interpreter' *)
  1884 	(* and the order in which it enumerates elements of an IDT before you try to         *)
  1885 	(* understand this function.                                                         *)
  1886 
  1887 	fun IDT_recursion_interpreter thy model args t =
  1888 		case strip_comb t of  (* careful: here we descend arbitrarily deep into 't', *)
  1889 		                      (* possibly before any other interpreter for atomic    *)
  1890 		                      (* terms has had a chance to look at 't'               *)
  1891 		  (Const (s, T), params) =>
  1892 			(* iterate over all datatypes in 'thy' *)
  1893 			Symtab.foldl (fn (result, (_, info)) =>
  1894 				case result of
  1895 				  SOME _ =>
  1896 					result  (* just keep 'result' *)
  1897 				| NONE =>
  1898 					if s mem (#rec_names info) then
  1899 						(* okay, we do have a recursion operator of the datatype given by 'info' *)
  1900 						let
  1901 							val index               = #index info
  1902 							val descr               = #descr info
  1903 							val (_, dtyps, constrs) = (valOf o assoc) (descr, index)
  1904 							(* the total number of constructors, including those of different    *)
  1905 							(* (mutually recursive) datatypes within the same descriptor 'descr' *)
  1906 							val constrs_count = sum (map (fn (_, (_, _, cs)) => length cs) descr)
  1907 							val params_count  = length params
  1908 						in
  1909 							if constrs_count < params_count then
  1910 								(* too many actual parameters; for now we'll use the *)
  1911 								(* 'stlc_interpreter' to strip off one application   *)
  1912 								NONE
  1913 							else if constrs_count > params_count then
  1914 								(* too few actual parameters; we use eta expansion            *)
  1915 								(* Note that the resulting expansion of lambda abstractions   *)
  1916 								(* by the 'stlc_interpreter' may be rather slow (depending on *)
  1917 								(* the argument types and the size of the IDT, of course).    *)
  1918 								SOME (interpret thy model args (eta_expand t (constrs_count - params_count)))
  1919 							else  (* constrs_count = params_count *)
  1920 								let
  1921 									(* interpret each parameter separately *)
  1922 									val ((model', args'), p_intrs) = foldl_map (fn ((m, a), p) =>
  1923 										let
  1924 											val (i, m', a') = interpret thy m a p
  1925 										in
  1926 											((m', a'), i)
  1927 										end) ((model, args), params)
  1928 									val (typs, terms) = model'
  1929 									(* the type of a recursion operator: [T1, ..., Tn, IDT] ---> Tresult *)
  1930 									val IDT       = List.nth (binder_types T, constrs_count)
  1931 									val typ_assoc = dtyps ~~ (snd o dest_Type) IDT
  1932 									(* interpret each constructor of the datatype *)
  1933 									(* TODO: we probably need to interpret every constructor in the descriptor, *)
  1934 									(*       possibly for typs' instead of typs                                 *)
  1935 									val c_intrs = map (#1 o interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True})
  1936 										(map (fn (cname, cargs) => Const (cname, map (typ_of_dtyp descr typ_assoc) cargs ---> IDT)) constrs)
  1937 									(* the recursion operator is a function that maps every element of *)
  1938 									(* the inductive datatype to an element of the result type         *)
  1939 									val (i, _, _) = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", IDT))
  1940 									val size      = size_of_type i
  1941 									val INTRS     = Array.array (size, Leaf [])  (* the initial value 'Leaf []' does not matter; it will be overwritten *)
  1942 									(* takes an interpretation, and if some leaf of this interpretation *)
  1943 									(* is the 'elem'-th element of the datatype, the indices of the     *)
  1944 									(* arguments leading to this leaf are returned                      *)
  1945 									(* interpretation -> int -> int list option *)
  1946 									fun get_args (Leaf xs) elem =
  1947 										if find_index_eq True xs = elem then
  1948 											SOME []
  1949 										else
  1950 											NONE
  1951 									  | get_args (Node xs) elem =
  1952 										let
  1953 											(* interpretation * int -> int list option *)
  1954 											fun search ([], _) =
  1955 												NONE
  1956 											  | search (x::xs, n) =
  1957 												(case get_args x elem of
  1958 												  SOME result => SOME (n::result)
  1959 												| NONE        => search (xs, n+1))
  1960 										in
  1961 											search (xs, 0)
  1962 										end
  1963 									(* returns the index of the constructor and indices for its      *)
  1964 									(* arguments that generate the 'elem'-th element of the datatype *)
  1965 									(* int -> int * int list *)
  1966 									fun get_cargs elem =
  1967 										let
  1968 											(* int * interpretation list -> int * int list *)
  1969 											fun get_cargs_rec (_, []) =
  1970 												raise REFUTE ("IDT_recursion_interpreter", "no matching constructor found for element " ^ string_of_int elem)
  1971 											  | get_cargs_rec (n, x::xs) =
  1972 												(case get_args x elem of
  1973 												  SOME args => (n, args)
  1974 												| NONE      => get_cargs_rec (n+1, xs))
  1975 										in
  1976 											get_cargs_rec (0, c_intrs)
  1977 										end
  1978 									(* int -> unit *)
  1979 									fun compute_loop elem =
  1980 										if elem=size then
  1981 											()
  1982 										else  (* elem < size *)
  1983 											let
  1984 												(* int * int list *)
  1985 												val (c, args) = get_cargs elem
  1986 												(* interpretation * int list -> interpretation *)
  1987 												fun select_subtree (tr, []) =
  1988 													tr  (* return the whole tree *)
  1989 												  | select_subtree (Leaf _, _) =
  1990 													raise REFUTE ("IDT_recursion_interpreter", "interpretation for parameter is a leaf; cannot select a subtree")
  1991 												  | select_subtree (Node tr, x::xs) =
  1992 													select_subtree (List.nth (tr, x), xs)
  1993 												(* select the correct subtree of the parameter corresponding to constructor 'c' *)
  1994 												val p_intr = select_subtree (List.nth (p_intrs, c), args)
  1995 												(* find the indices of recursive arguments *)
  1996 												val rec_args = map snd (List.filter (DatatypeAux.is_rec_type o fst) ((snd (List.nth (constrs, c))) ~~ args))
  1997 												(* apply 'p_intr' to recursively computed results *)
  1998 												val rec_p_intr = Library.foldl (fn (i, n) => interpretation_apply (i, Array.sub (INTRS, n))) (p_intr, rec_args)
  1999 												(* update 'INTRS' *)
  2000 												val _ = Array.update (INTRS, elem, rec_p_intr)
  2001 											in
  2002 												compute_loop (elem+1)
  2003 											end
  2004 									val _ = compute_loop 0
  2005 									(* 'a Array.array -> 'a list *)
  2006 									fun toList arr =
  2007 										Array.foldr op:: [] arr
  2008 								in
  2009 									SOME (Node (toList INTRS), model', args')
  2010 								end
  2011 						end
  2012 					else
  2013 						NONE  (* not a recursion operator of this datatype *)
  2014 				) (NONE, DatatypePackage.get_datatypes thy)
  2015 		| _ =>  (* head of term is not a constant *)
  2016 			NONE;
  2017 
  2018 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  2019 
  2020 	(* only an optimization: 'card' could in principle be interpreted with    *)
  2021 	(* interpreters available already (using its definition), but the code    *)
  2022 	(* below is more efficient                                                *)
  2023 
  2024 	fun Finite_Set_card_interpreter thy model args t =
  2025 		case t of
  2026 		  Const ("Finite_Set.card", Type ("fun", [Type ("set", [T]), Type ("nat", [])])) =>
  2027 			let
  2028 				val (i_nat, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("nat", [])))
  2029 				val size_nat      = size_of_type i_nat
  2030 				val (i_set, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("set", [T])))
  2031 				val constants     = make_constants i_set
  2032 				(* interpretation -> int *)
  2033 				fun number_of_elements (Node xs) =
  2034 					Library.foldl (fn (n, x) =>
  2035 						if x=TT then
  2036 							n+1
  2037 						else if x=FF then
  2038 							n
  2039 						else
  2040 							raise REFUTE ("Finite_Set_card_interpreter", "interpretation for set type does not yield a Boolean")) (0, xs)
  2041 				  | number_of_elements (Leaf _) =
  2042 					raise REFUTE ("Finite_Set_card_interpreter", "interpretation for set type is a leaf")
  2043 				(* takes an interpretation for a set and returns an interpretation for a 'nat' *)
  2044 				(* interpretation -> interpretation *)
  2045 				fun card i =
  2046 					let
  2047 						val n = number_of_elements i
  2048 					in
  2049 						if n<size_nat then
  2050 							Leaf ((replicate n False) @ True :: (replicate (size_nat-n-1) False))
  2051 						else
  2052 							Leaf (replicate size_nat False)
  2053 					end
  2054 			in
  2055 				SOME (Node (map card constants), model, args)
  2056 			end
  2057 		| _ =>
  2058 			NONE;
  2059 
  2060 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  2061 
  2062 	(* only an optimization: 'Finites' could in principle be interpreted with *)
  2063 	(* interpreters available already (using its definition), but the code    *)
  2064 	(* below is more efficient                                                *)
  2065 
  2066 	fun Finite_Set_Finites_interpreter thy model args t =
  2067 		case t of
  2068 		  Const ("Finite_Set.Finites", Type ("set", [Type ("set", [T])])) =>
  2069 			let
  2070 				val (i_set, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("set", [T])))
  2071 				val size_set      = size_of_type i_set
  2072 			in
  2073 				(* we only consider finite models anyway, hence EVERY set is in "Finites" *)
  2074 				SOME (Node (replicate size_set TT), model, args)
  2075 			end
  2076 		| _ =>
  2077 			NONE;
  2078 
  2079 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  2080 
  2081 	(* only an optimization: 'op <' could in principle be interpreted with    *)
  2082 	(* interpreters available already (using its definition), but the code    *)
  2083 	(* below is more efficient                                                *)
  2084 
  2085 	fun Nat_less_interpreter thy model args t =
  2086 		case t of
  2087 		  Const ("op <", Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("bool", [])])])) =>
  2088 			let
  2089 				val (i_nat, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("nat", [])))
  2090 				val size_nat      = size_of_type i_nat
  2091 				(* int -> interpretation *)
  2092 				(* the 'n'-th nat is not less than the first 'n' nats, while it *)
  2093 				(* is less than the remaining 'size_nat - n' nats               *)
  2094 				fun less n = Node ((replicate n FF) @ (replicate (size_nat - n) TT))
  2095 			in
  2096 				SOME (Node (map less (1 upto size_nat)), model, args)
  2097 			end
  2098 		| _ =>
  2099 			NONE;
  2100 
  2101 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  2102 
  2103 	(* only an optimization: 'op +' could in principle be interpreted with    *)
  2104 	(* interpreters available already (using its definition), but the code    *)
  2105 	(* below is more efficient                                                *)
  2106 
  2107 	fun Nat_plus_interpreter thy model args t =
  2108 		case t of
  2109 		  Const ("op +", Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("nat", [])])])) =>
  2110 			let
  2111 				val (i_nat, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("nat", [])))
  2112 				val size_nat      = size_of_type i_nat
  2113 				(* int -> int -> interpretation *)
  2114 				fun plus m n = let
  2115 						val element = (m+n)+1
  2116 					in
  2117 						if element > size_nat then
  2118 							Leaf (replicate size_nat False)
  2119 						else
  2120 							Leaf ((replicate (element-1) False) @ True :: (replicate (size_nat - element) False))
  2121 					end
  2122 			in
  2123 				SOME (Node (map (fn m => Node (map (plus m) (0 upto size_nat-1))) (0 upto size_nat-1)), model, args)
  2124 			end
  2125 		| _ =>
  2126 			NONE;
  2127 
  2128 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  2129 
  2130 	(* only an optimization: 'op -' could in principle be interpreted with    *)
  2131 	(* interpreters available already (using its definition), but the code    *)
  2132 	(* below is more efficient                                                *)
  2133 
  2134 	fun Nat_minus_interpreter thy model args t =
  2135 		case t of
  2136 		  Const ("op -", Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("nat", [])])])) =>
  2137 			let
  2138 				val (i_nat, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("nat", [])))
  2139 				val size_nat      = size_of_type i_nat
  2140 				(* int -> int -> interpretation *)
  2141 				fun minus m n = let
  2142 						val element = Int.max (m-n, 0) + 1
  2143 					in
  2144 						Leaf ((replicate (element-1) False) @ True :: (replicate (size_nat - element) False))
  2145 					end
  2146 			in
  2147 				SOME (Node (map (fn m => Node (map (minus m) (0 upto size_nat-1))) (0 upto size_nat-1)), model, args)
  2148 			end
  2149 		| _ =>
  2150 			NONE;
  2151 
  2152 	(* theory -> model -> arguments -> Term.term -> (interpretation * model * arguments) option *)
  2153 
  2154 	(* only an optimization: 'op *' could in principle be interpreted with    *)
  2155 	(* interpreters available already (using its definition), but the code    *)
  2156 	(* below is more efficient                                                *)
  2157 
  2158 	fun Nat_mult_interpreter thy model args t =
  2159 		case t of
  2160 		  Const ("op *", Type ("fun", [Type ("nat", []), Type ("fun", [Type ("nat", []), Type ("nat", [])])])) =>
  2161 			let
  2162 				val (i_nat, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", Type ("nat", [])))
  2163 				val size_nat      = size_of_type i_nat
  2164 				(* nat -> nat -> interpretation *)
  2165 				fun mult m n = let
  2166 						val element = (m*n)+1
  2167 					in
  2168 						if element > size_nat then
  2169 							Leaf (replicate size_nat False)
  2170 						else
  2171 							Leaf ((replicate (element-1) False) @ True :: (replicate (size_nat - element) False))
  2172 					end
  2173 			in
  2174 				SOME (Node (map (fn m => Node (map (mult m) (0 upto size_nat-1))) (0 upto size_nat-1)), model, args)
  2175 			end
  2176 		| _ =>
  2177 			NONE;
  2178 
  2179 
  2180 (* ------------------------------------------------------------------------- *)
  2181 (* PRINTERS                                                                  *)
  2182 (* ------------------------------------------------------------------------- *)
  2183 
  2184 	(* theory -> model -> Term.term -> interpretation -> (int -> bool) -> Term.term option *)
  2185 
  2186 	fun stlc_printer thy model t intr assignment =
  2187 	let
  2188 		(* Term.term -> Term.typ option *)
  2189 		fun typeof (Free (_, T))  = SOME T
  2190 		  | typeof (Var (_, T))   = SOME T
  2191 		  | typeof (Const (_, T)) = SOME T
  2192 		  | typeof _              = NONE
  2193 		(* string -> string *)
  2194 		fun strip_leading_quote s =
  2195 			(implode o (fn ss => case ss of [] => [] | x::xs => if x="'" then xs else ss) o explode) s
  2196 		(* Term.typ -> string *)
  2197 		fun string_of_typ (Type (s, _))     = s
  2198 		  | string_of_typ (TFree (x, _))    = strip_leading_quote x
  2199 		  | string_of_typ (TVar ((x,i), _)) = strip_leading_quote x ^ string_of_int i
  2200 		(* interpretation -> int *)
  2201 		fun index_from_interpretation (Leaf xs) =
  2202 			find_index (PropLogic.eval assignment) xs
  2203 		  | index_from_interpretation _ =
  2204 			raise REFUTE ("stlc_printer", "interpretation for ground type is not a leaf")
  2205 	in
  2206 		case typeof t of
  2207 		  SOME T =>
  2208 			(case T of
  2209 			  Type ("fun", [T1, T2]) =>
  2210 				let
  2211 					(* create all constants of type 'T1' *)
  2212 					val (i, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T1))
  2213 					val constants = make_constants i
  2214 					(* interpretation list *)
  2215 					val results = (case intr of
  2216 						  Node xs => xs
  2217 						| _       => raise REFUTE ("stlc_printer", "interpretation for function type is a leaf"))
  2218 					(* Term.term list *)
  2219 					val pairs = map (fn (arg, result) =>
  2220 						HOLogic.mk_prod
  2221 							(print thy model (Free ("dummy", T1)) arg assignment,
  2222 							 print thy model (Free ("dummy", T2)) result assignment))
  2223 						(constants ~~ results)
  2224 					(* Term.typ *)
  2225 					val HOLogic_prodT = HOLogic.mk_prodT (T1, T2)
  2226 					val HOLogic_setT  = HOLogic.mk_setT HOLogic_prodT
  2227 					(* Term.term *)
  2228 					val HOLogic_empty_set = Const ("{}", HOLogic_setT)
  2229 					val HOLogic_insert    = Const ("insert", HOLogic_prodT --> HOLogic_setT --> HOLogic_setT)
  2230 				in
  2231 					SOME (foldr (fn (pair, acc) => HOLogic_insert $ pair $ acc) HOLogic_empty_set pairs)
  2232 				end
  2233 			| Type ("prop", [])      =>
  2234 				(case index_from_interpretation intr of
  2235 				  (~1) => SOME (HOLogic.mk_Trueprop (Const ("arbitrary", HOLogic.boolT)))
  2236 				| 0    => SOME (HOLogic.mk_Trueprop HOLogic.true_const)
  2237 				| 1    => SOME (HOLogic.mk_Trueprop HOLogic.false_const)
  2238 				| _    => raise REFUTE ("stlc_interpreter", "illegal interpretation for a propositional value"))
  2239 			| Type _  => if index_from_interpretation intr = (~1) then
  2240 					SOME (Const ("arbitrary", T))
  2241 				else
  2242 					SOME (Const (string_of_typ T ^ string_of_int (index_from_interpretation intr), T))
  2243 			| TFree _ => if index_from_interpretation intr = (~1) then
  2244 					SOME (Const ("arbitrary", T))
  2245 				else
  2246 					SOME (Const (string_of_typ T ^ string_of_int (index_from_interpretation intr), T))
  2247 			| TVar _  => if index_from_interpretation intr = (~1) then
  2248 					SOME (Const ("arbitrary", T))
  2249 				else
  2250 					SOME (Const (string_of_typ T ^ string_of_int (index_from_interpretation intr), T)))
  2251 		| NONE =>
  2252 			NONE
  2253 	end;
  2254 
  2255 	(* theory -> model -> Term.term -> interpretation -> (int -> bool) -> string option *)
  2256 
  2257 	fun set_printer thy model t intr assignment =
  2258 	let
  2259 		(* Term.term -> Term.typ option *)
  2260 		fun typeof (Free (_, T))  = SOME T
  2261 		  | typeof (Var (_, T))   = SOME T
  2262 		  | typeof (Const (_, T)) = SOME T
  2263 		  | typeof _              = NONE
  2264 	in
  2265 		case typeof t of
  2266 		  SOME (Type ("set", [T])) =>
  2267 			let
  2268 				(* create all constants of type 'T' *)
  2269 				val (i, _, _) = interpret thy model {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", T))
  2270 				val constants = make_constants i
  2271 				(* interpretation list *)
  2272 				val results = (case intr of
  2273 					  Node xs => xs
  2274 					| _       => raise REFUTE ("set_printer", "interpretation for set type is a leaf"))
  2275 				(* Term.term list *)
  2276 				val elements = List.mapPartial (fn (arg, result) =>
  2277 					case result of
  2278 					  Leaf [fmTrue, fmFalse] =>
  2279 						if PropLogic.eval assignment fmTrue then
  2280 							SOME (print thy model (Free ("dummy", T)) arg assignment)
  2281 						else (*if PropLogic.eval assignment fmFalse then*)
  2282 							NONE
  2283 					| _ =>
  2284 						raise REFUTE ("set_printer", "illegal interpretation for a Boolean value"))
  2285 					(constants ~~ results)
  2286 				(* Term.typ *)
  2287 				val HOLogic_setT  = HOLogic.mk_setT T
  2288 				(* Term.term *)
  2289 				val HOLogic_empty_set = Const ("{}", HOLogic_setT)
  2290 				val HOLogic_insert    = Const ("insert", T --> HOLogic_setT --> HOLogic_setT)
  2291 			in
  2292 				SOME (Library.foldl (fn (acc, elem) => HOLogic_insert $ elem $ acc) (HOLogic_empty_set, elements))
  2293 			end
  2294 		| _ =>
  2295 			NONE
  2296 	end;
  2297 
  2298 	(* theory -> model -> Term.term -> interpretation -> (int -> bool) -> Term.term option *)
  2299 
  2300 	fun IDT_printer thy model t intr assignment =
  2301 	let
  2302 		(* Term.term -> Term.typ option *)
  2303 		fun typeof (Free (_, T))  = SOME T
  2304 		  | typeof (Var (_, T))   = SOME T
  2305 		  | typeof (Const (_, T)) = SOME T
  2306 		  | typeof _              = NONE
  2307 	in
  2308 		case typeof t of
  2309 		  SOME (Type (s, Ts)) =>
  2310 			(case DatatypePackage.datatype_info thy s of
  2311 			  SOME info =>  (* inductive datatype *)
  2312 				let
  2313 					val (typs, _)           = model
  2314 					val index               = #index info
  2315 					val descr               = #descr info
  2316 					val (_, dtyps, constrs) = (valOf o assoc) (descr, index)
  2317 					val typ_assoc           = dtyps ~~ Ts
  2318 					(* sanity check: every element in 'dtyps' must be a 'DtTFree' *)
  2319 					val _ = (if Library.exists (fn d =>
  2320 							case d of DatatypeAux.DtTFree _ => false | _ => true) dtyps
  2321 						then
  2322 							raise REFUTE ("IDT_printer", "datatype argument (for type " ^ Sign.string_of_typ (sign_of thy) (Type (s, Ts)) ^ ") is not a variable")
  2323 						else
  2324 							())
  2325 					(* the index of the element in the datatype *)
  2326 					val element = (case intr of
  2327 						  Leaf xs => find_index (PropLogic.eval assignment) xs
  2328 						| Node _  => raise REFUTE ("IDT_printer", "interpretation is not a leaf"))
  2329 				in
  2330 					if element < 0 then
  2331 						SOME (Const ("arbitrary", Type (s, Ts)))
  2332 					else let
  2333 						(* takes a datatype constructor, and if for some arguments this constructor *)
  2334 						(* generates the datatype's element that is given by 'element', returns the *)
  2335 						(* constructor (as a term) as well as the indices of the arguments          *)
  2336 						(* string * DatatypeAux.dtyp list -> (Term.term * int list) option *)
  2337 						fun get_constr_args (cname, cargs) =
  2338 							let
  2339 								val cTerm      = Const (cname, (map (typ_of_dtyp descr typ_assoc) cargs) ---> Type (s, Ts))
  2340 								val (iC, _, _) = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} cTerm
  2341 								(* interpretation -> int list option *)
  2342 								fun get_args (Leaf xs) =
  2343 									if find_index_eq True xs = element then
  2344 										SOME []
  2345 									else
  2346 										NONE
  2347 								  | get_args (Node xs) =
  2348 									let
  2349 										(* interpretation * int -> int list option *)
  2350 										fun search ([], _) =
  2351 											NONE
  2352 										  | search (x::xs, n) =
  2353 											(case get_args x of
  2354 											  SOME result => SOME (n::result)
  2355 											| NONE        => search (xs, n+1))
  2356 									in
  2357 										search (xs, 0)
  2358 									end
  2359 							in
  2360 								Option.map (fn args => (cTerm, cargs, args)) (get_args iC)
  2361 							end
  2362 						(* Term.term * DatatypeAux.dtyp list * int list *)
  2363 						val (cTerm, cargs, args) = (case get_first get_constr_args constrs of
  2364 							  SOME x => x
  2365 							| NONE   => raise REFUTE ("IDT_printer", "no matching constructor found for element " ^ string_of_int element))
  2366 						val argsTerms = map (fn (d, n) =>
  2367 							let
  2368 								val dT        = typ_of_dtyp descr typ_assoc d
  2369 								val (i, _, _) = interpret thy (typs, []) {maxvars=0, def_eq=false, next_idx=1, bounds=[], wellformed=True} (Free ("dummy", dT))
  2370 								val consts    = make_constants i  (* we only need the n-th element of this *)
  2371 									(* list, so there might be a more efficient implementation that does    *)
  2372 									(* not generate all constants                                           *)
  2373 							in
  2374 								print thy (typs, []) (Free ("dummy", dT)) (List.nth (consts, n)) assignment
  2375 							end) (cargs ~~ args)
  2376 					in
  2377 						SOME (Library.foldl op$ (cTerm, argsTerms))
  2378 					end
  2379 				end
  2380 			| NONE =>  (* not an inductive datatype *)
  2381 				NONE)
  2382 		| _ =>  (* a (free or schematic) type variable *)
  2383 			NONE
  2384 	end;
  2385 
  2386 
  2387 (* ------------------------------------------------------------------------- *)
  2388 (* use 'setup Refute.setup' in an Isabelle theory to initialize the 'Refute' *)
  2389 (* structure                                                                 *)
  2390 (* ------------------------------------------------------------------------- *)
  2391 
  2392 (* ------------------------------------------------------------------------- *)
  2393 (* Note: the interpreters and printers are used in reverse order; however,   *)
  2394 (*       an interpreter that can handle non-atomic terms ends up being       *)
  2395 (*       applied before the 'stlc_interpreter' breaks the term apart into    *)
  2396 (*       subterms that are then passed to other interpreters!                *)
  2397 (* ------------------------------------------------------------------------- *)
  2398 
  2399 	(* (theory -> theory) list *)
  2400 
  2401 	val setup =
  2402 		[RefuteData.init,
  2403 		 add_interpreter "stlc"    stlc_interpreter,
  2404 		 add_interpreter "Pure"    Pure_interpreter,
  2405 		 add_interpreter "HOLogic" HOLogic_interpreter,
  2406 		 add_interpreter "set"     set_interpreter,
  2407 		 add_interpreter "IDT"             IDT_interpreter,
  2408 		 add_interpreter "IDT_constructor" IDT_constructor_interpreter,
  2409 		 add_interpreter "IDT_recursion"   IDT_recursion_interpreter,
  2410 		 add_interpreter "Finite_Set.card"    Finite_Set_card_interpreter,
  2411 		 add_interpreter "Finite_Set.Finites" Finite_Set_Finites_interpreter,
  2412 		 add_interpreter "Nat.op <" Nat_less_interpreter,
  2413 		 add_interpreter "Nat.op +" Nat_plus_interpreter,
  2414 		 add_interpreter "Nat.op -" Nat_minus_interpreter,
  2415 		 add_interpreter "Nat.op *" Nat_mult_interpreter,
  2416 		 add_printer "stlc" stlc_printer,
  2417 		 add_printer "set"  set_printer,
  2418 		 add_printer "IDT"  IDT_printer];
  2419 
  2420 end