src/HOL/Tools/res_axioms.ML
changeset 20863 4ee61dbf192d
parent 20789 e279499c4f80
child 20867 e7b92a48e22b
equal deleted inserted replaced
20862:1059f2316f88 20863:4ee61dbf192d
    36   CANNOT be a ref, as the setting is used while Isabelle is built.*)
    36   CANNOT be a ref, as the setting is used while Isabelle is built.*)
    37 val abstract_lambdas = true;
    37 val abstract_lambdas = true;
    38 
    38 
    39 val trace_abs = ref false;
    39 val trace_abs = ref false;
    40 
    40 
       
    41 (*FIXME: move some of these functions to Pure/drule.ML *)
       
    42 
       
    43 fun freeze_thm th = #1 (Drule.freeze_thaw th);
       
    44 
       
    45 fun lhs_of th =
       
    46   case prop_of th of (Const("==",_) $ lhs $ _) => lhs
       
    47     | _ => raise THM ("lhs_of", 1, [th]);
       
    48 
       
    49 fun rhs_of th =
       
    50   case prop_of th of (Const("==",_) $ _ $ rhs) => rhs
       
    51     | _ => raise THM ("rhs_of", 1, [th]);
       
    52 
    41 (*Store definitions of abstraction functions, ensuring that identical right-hand
    53 (*Store definitions of abstraction functions, ensuring that identical right-hand
    42   sides are denoted by the same functions and thereby reducing the need for
    54   sides are denoted by the same functions and thereby reducing the need for
    43   extensionality in proofs.
    55   extensionality in proofs.
    44   FIXME!  Store in theory data!!*)
    56   FIXME!  Store in theory data!!*)
    45 val abstraction_cache = ref Net.empty : thm Net.net ref;
    57 
       
    58 fun seed th net =
       
    59   let val (_,ct) = Thm.dest_abs NONE (Drule.crhs_of th)
       
    60   in  Net.insert_term eq_thm (term_of ct, th) net end;
       
    61   
       
    62 val abstraction_cache = ref 
       
    63   (seed (thm"COMBI1") (seed (thm"COMBB1") (seed (thm"COMBK1") Net.empty)));
    46 
    64 
    47 (**** Transformation of Elimination Rules into First-Order Formulas****)
    65 (**** Transformation of Elimination Rules into First-Order Formulas****)
    48 
    66 
    49 (* a tactic used to prove an elim-rule. *)
    67 (* a tactic used to prove an elim-rule. *)
    50 fun elimRule_tac th =
    68 fun elimRule_tac th =
    84       let val disjs = foldr1 HOLogic.mk_disj (map (strip_concl [] [] concl) minors)
   102       let val disjs = foldr1 HOLogic.mk_disj (map (strip_concl [] [] concl) minors)
    85       in  HOLogic.mk_imp (major, disjs)  end;
   103       in  HOLogic.mk_imp (major, disjs)  end;
    86 
   104 
    87 (* convert an elim rule into an equivalent formula, of type term. *)
   105 (* convert an elim rule into an equivalent formula, of type term. *)
    88 fun elimR2Fol elimR =
   106 fun elimR2Fol elimR =
    89   let val elimR' = #1 (Drule.freeze_thaw elimR)
   107   let val elimR' = freeze_thm elimR
    90       val (prems,concl) = (prems_of elimR', concl_of elimR')
   108       val (prems,concl) = (prems_of elimR', concl_of elimR')
    91       val cv = case concl of    (*conclusion variable*)
   109       val cv = case concl of    (*conclusion variable*)
    92                   Const("Trueprop",_) $ (v as Free(_,Type("bool",[]))) => v
   110                   Const("Trueprop",_) $ (v as Free(_,Type("bool",[]))) => v
    93                 | v as Free(_, Type("prop",[])) => v
   111                 | v as Free(_, Type("prop",[])) => v
    94                 | _ => raise ELIMR2FOL
   112                 | _ => raise ELIMR2FOL
   205     fun mkvar a = cterm_of thy (Var((a,0),ty));
   223     fun mkvar a = cterm_of thy (Var((a,0),ty));
   206 in
   224 in
   207 fun xfun_cong x = Thm.instantiate ([], [(cx, mkvar x)]) fun_cong'
   225 fun xfun_cong x = Thm.instantiate ([], [(cx, mkvar x)]) fun_cong'
   208 end;
   226 end;
   209 
   227 
   210 (*Removes the lambdas from an equation of the form t = (%x. u)*)
   228 (*Removes the lambdas from an equation of the form t = (%x. u).  A non-negative n,
   211 fun strip_lambdas th =
   229   serves as an upper bound on how many to remove.*)
   212   case prop_of th of
   230 fun strip_lambdas 0 th = th
   213       _ $ (Const ("op =", _) $ _ $ Abs (x,_,_)) =>
   231   | strip_lambdas n th = 
   214           strip_lambdas (#1 (Drule.freeze_thaw (th RS xfun_cong x)))
   232       case prop_of th of
   215     | _ => th;
   233 	  _ $ (Const ("op =", _) $ _ $ Abs (x,_,_)) =>
       
   234 	      strip_lambdas (n-1) (freeze_thm (th RS xfun_cong x))
       
   235 	| _ => th;
   216 
   236 
   217 (*Convert meta- to object-equality. Fails for theorems like split_comp_eq,
   237 (*Convert meta- to object-equality. Fails for theorems like split_comp_eq,
   218   where some types have the empty sort.*)
   238   where some types have the empty sort.*)
   219 fun object_eq th = th RS def_imp_eq
   239 fun mk_object_eq th = th RS def_imp_eq
   220     handle THM _ => error ("Theorem contains empty sort: " ^ string_of_thm th);
   240     handle THM _ => error ("Theorem contains empty sort: " ^ string_of_thm th);
   221 
       
   222 (*Contract all eta-redexes in the theorem, lest they give rise to needless abstractions*)
       
   223 fun eta_conversion_rule th =
       
   224   equal_elim (eta_conversion (cprop_of th)) th;
       
   225 
       
   226 fun crhs_of th =
       
   227   case Drule.strip_comb (cprop_of th) of
       
   228       (f, [_, rhs]) =>
       
   229           (case term_of f of Const ("==", _) => rhs
       
   230              | _ => raise THM ("crhs_of", 0, [th]))
       
   231     | _ => raise THM ("crhs_of", 1, [th]);
       
   232 
       
   233 fun lhs_of th =
       
   234   case prop_of th of (Const("==",_) $ lhs $ _) => lhs
       
   235     | _ => raise THM ("lhs_of", 1, [th]);
       
   236 
       
   237 fun rhs_of th =
       
   238   case prop_of th of (Const("==",_) $ _ $ rhs) => rhs
       
   239     | _ => raise THM ("rhs_of", 1, [th]);
       
   240 
   241 
   241 (*Apply a function definition to an argument, beta-reducing the result.*)
   242 (*Apply a function definition to an argument, beta-reducing the result.*)
   242 fun beta_comb cf x =
   243 fun beta_comb cf x =
   243   let val th1 = combination cf (reflexive x)
   244   let val th1 = combination cf (reflexive x)
   244       val th2 = beta_conversion false (crhs_of th1)
   245       val th2 = beta_conversion false (Drule.crhs_of th1)
   245   in  transitive th1 th2  end;
   246   in  transitive th1 th2  end;
   246 
   247 
   247 (*Apply a function definition to arguments, beta-reducing along the way.*)
   248 (*Apply a function definition to arguments, beta-reducing along the way.*)
   248 fun list_combination cf [] = cf
   249 fun list_combination cf [] = cf
   249   | list_combination cf (x::xs) = list_combination (beta_comb cf x) xs;
   250   | list_combination cf (x::xs) = list_combination (beta_comb cf x) xs;
   278   | lambda_list (v::vs) u = lambda v (lambda_list vs u);
   279   | lambda_list (v::vs) u = lambda v (lambda_list vs u);
   279 
   280 
   280 fun abstract_rule_list [] [] th = th
   281 fun abstract_rule_list [] [] th = th
   281   | abstract_rule_list (v::vs) (ct::cts) th = abstract_rule v ct (abstract_rule_list vs cts th)
   282   | abstract_rule_list (v::vs) (ct::cts) th = abstract_rule v ct (abstract_rule_list vs cts th)
   282   | abstract_rule_list _ _ th = raise THM ("abstract_rule_list", 0, [th]);
   283   | abstract_rule_list _ _ th = raise THM ("abstract_rule_list", 0, [th]);
       
   284 
       
   285 
       
   286 val Envir.Envir {asol = tenv0, iTs = tyenv0, ...} = Envir.empty 0
       
   287 
       
   288 (*Does an existing abstraction definition have an RHS that matches the one we need now?*)
       
   289 fun match_rhs thy0 t th =
       
   290   let val thy = theory_of_thm th
       
   291       val _ = if !trace_abs then warning ("match_rhs: " ^ string_of_cterm (cterm_of thy t) ^ 
       
   292                                           " against\n" ^ string_of_thm th) else ();
       
   293       val (tyenv,tenv) = if Context.joinable (thy0,thy) then
       
   294                             Pattern.first_order_match thy (rhs_of th, t) (tyenv0,tenv0)
       
   295                          else raise Pattern.MATCH
       
   296       val term_insts = map Meson.term_pair_of (Vartab.dest tenv)
       
   297       val ct_pairs = if forall lambda_free (map #2 term_insts) then
       
   298                          map (pairself (cterm_of thy)) term_insts
       
   299                      else raise Pattern.MATCH (*Cannot allow lambdas in the instantiation*)
       
   300       fun ctyp2 (ixn, (S, T)) = (ctyp_of thy (TVar (ixn, S)), ctyp_of thy T)
       
   301       val th' = cterm_instantiate ct_pairs th
       
   302   in  SOME (th, instantiate (map ctyp2 (Vartab.dest tyenv), []) th')  end
       
   303   handle _ => NONE;
   283 
   304 
   284 (*Traverse a theorem, declaring abstraction function definitions. String s is the suggested
   305 (*Traverse a theorem, declaring abstraction function definitions. String s is the suggested
   285   prefix for the constants. Resulting theory is returned in the first theorem. *)
   306   prefix for the constants. Resulting theory is returned in the first theorem. *)
   286 fun declare_absfuns th =
   307 fun declare_absfuns th =
   287   let fun abstract thy ct =
   308   let fun abstract thy ct =
   291           Abs _ =>
   312           Abs _ =>
   292             let val cname = Name.internal (gensym "abs_");
   313             let val cname = Name.internal (gensym "abs_");
   293                 val _ = assert_eta_free ct;
   314                 val _ = assert_eta_free ct;
   294                 val (cvs,cta) = dest_abs_list ct
   315                 val (cvs,cta) = dest_abs_list ct
   295                 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs)
   316                 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs)
       
   317                 val _ = if !trace_abs then warning ("Nested lambda: " ^ string_of_cterm cta) else ();
   296                 val (u'_th,defs) = abstract thy cta
   318                 val (u'_th,defs) = abstract thy cta
   297                 val cu' = crhs_of u'_th
   319                 val _ = if !trace_abs then warning ("Returned " ^ string_of_thm u'_th) else ();
   298                 val abs_v_u = lambda_list (map term_of cvs) (term_of cu')
   320                 val cu' = Drule.crhs_of u'_th
       
   321                 val u' = term_of cu'
       
   322                 val abs_v_u = lambda_list (map term_of cvs) u'
   299                 (*get the formal parameters: ALL variables free in the term*)
   323                 (*get the formal parameters: ALL variables free in the term*)
   300                 val args = term_frees abs_v_u
   324                 val args = term_frees abs_v_u
       
   325                 val _ = if !trace_abs then warning (Int.toString (length args) ^ " arguments") else ();
   301                 val rhs = list_abs_free (map dest_Free args, abs_v_u)
   326                 val rhs = list_abs_free (map dest_Free args, abs_v_u)
   302                       (*Forms a lambda-abstraction over the formal parameters*)
   327                       (*Forms a lambda-abstraction over the formal parameters*)
   303                 val v_rhs = Logic.varify rhs
   328                 val v_rhs = Logic.varify rhs
   304                 val (ax,thy) =
   329                 val _ = if !trace_abs then warning ("Looking up " ^ string_of_cterm cu') else ();
   305                  case List.find (fn ax => v_rhs aconv rhs_of ax)
   330                 val (ax,ax',thy) =
   306                         (Net.match_term (!abstraction_cache) v_rhs) of
   331                  case List.mapPartial (match_rhs thy abs_v_u) (Net.match_term (!abstraction_cache) u')
   307                      SOME ax => (ax,thy)   (*cached axiom, current theory*)
   332                         of
   308                    | NONE =>
   333                      (ax,ax')::_ => 
   309                       let val Ts = map type_of args
   334                        (if !trace_abs then warning ("Re-using axiom " ^ string_of_thm ax) else ();
       
   335                         (ax,ax',thy))
       
   336                    | [] =>
       
   337                       let val _ = if !trace_abs then warning "Lookup was empty" else ();
       
   338                           val Ts = map type_of args
   310                           val cT = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu'))
   339                           val cT = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu'))
   311                           val thy = theory_of_thm u'_th
   340                           val thy = theory_of_thm u'_th
   312                           val c = Const (Sign.full_name thy cname, cT)
   341                           val c = Const (Sign.full_name thy cname, cT)
   313                           val thy = Sign.add_consts_authentic [(cname, cT, NoSyn)] thy
   342                           val thy = Sign.add_consts_authentic [(cname, cT, NoSyn)] thy
   314                                      (*Theory is augmented with the constant,
   343                                      (*Theory is augmented with the constant,
   315                                        then its definition*)
   344                                        then its definition*)
   316                           val cdef = cname ^ "_def"
   345                           val cdef = cname ^ "_def"
   317                           val thy = Theory.add_defs_i false false
   346                           val thy = Theory.add_defs_i false false
   318                                        [(cdef, equals cT $ c $ rhs)] thy
   347                                        [(cdef, equals cT $ c $ rhs)] thy
   319                           val ax = get_axiom thy cdef
   348                           val _ = if !trace_abs then (warning ("Definition is " ^ 
   320                           val _ = abstraction_cache := Net.insert_term eq_absdef (v_rhs,ax)
   349                                                       string_of_thm (get_axiom thy cdef))) 
   321                                     (!abstraction_cache)
   350                                   else ();
       
   351                           val ax = get_axiom thy cdef |> freeze_thm
       
   352                                      |> mk_object_eq |> strip_lambdas (length args)
       
   353                                      |> mk_meta_eq |> Meson.generalize
       
   354                           val (_,ax') = Option.valOf (match_rhs thy abs_v_u ax)
       
   355                           val _ = if !trace_abs then 
       
   356                                     (warning ("Declaring: " ^ string_of_thm ax);
       
   357                                      warning ("Instance: " ^ string_of_thm ax')) 
       
   358                                   else ();
       
   359                           val _ = abstraction_cache := Net.insert_term eq_absdef 
       
   360                                             ((Logic.varify u'), ax) (!abstraction_cache)
   322                             handle Net.INSERT =>
   361                             handle Net.INSERT =>
   323                               raise THM ("declare_absfuns: INSERT", 0, [th,u'_th,ax])
   362                               raise THM ("declare_absfuns: INSERT", 0, [th,u'_th,ax])
   324                        in  (ax,thy)  end
   363                        in  (ax,ax',thy)  end
   325                 val _ = assert (v_rhs aconv rhs_of ax) "declare_absfuns: rhs mismatch"
   364             in if !trace_abs then warning ("Lookup result: " ^ string_of_thm ax') else ();
   326                 val def = #1 (Drule.freeze_thaw ax)
   365                (transitive (abstract_rule_list vs cvs u'_th) (symmetric ax'), ax::defs) end
   327                 val def_args = list_combination def (map (cterm_of thy) args)
       
   328             in (transitive (abstract_rule_list vs cvs u'_th) (symmetric def_args),
       
   329                 def :: defs) end
       
   330         | (t1$t2) =>
   366         | (t1$t2) =>
   331             let val (ct1,ct2) = Thm.dest_comb ct
   367             let val (ct1,ct2) = Thm.dest_comb ct
   332                 val (th1,defs1) = abstract thy ct1
   368                 val (th1,defs1) = abstract thy ct1
   333                 val (th2,defs2) = abstract (theory_of_thm th1) ct2
   369                 val (th2,defs2) = abstract (theory_of_thm th1) ct2
   334             in  (combination th1 th2, defs1@defs2)  end
   370             in  (combination th1 th2, defs1@defs2)  end
   335       val _ = if !trace_abs then warning (string_of_thm th) else ();
   371       val _ = if !trace_abs then warning ("declare_absfuns, Abstracting: " ^ string_of_thm th) else ();
   336       val (eqth,defs) = abstract (theory_of_thm th) (cprop_of th)
   372       val (eqth,defs) = abstract (theory_of_thm th) (cprop_of th)
   337       val ths = equal_elim eqth th ::
   373       val ths = equal_elim eqth th :: map (strip_lambdas ~1 o mk_object_eq o freeze_thm) defs
   338                 map (forall_intr_vars o strip_lambdas o object_eq) defs
   374       val _ = if !trace_abs then warning ("declare_absfuns, Result: " ^ string_of_thm (hd ths)) else ();
   339   in  (theory_of_thm eqth, ths)  end;
   375   in  (theory_of_thm eqth, map Drule.eta_contraction_rule ths)  end;
   340 
   376 
   341 fun name_of def = SOME (#1 (dest_Free (lhs_of def))) handle _ => NONE;
   377 fun name_of def = SOME (#1 (dest_Free (lhs_of def))) handle _ => NONE;
   342 
   378 
   343 (*A name is valid provided it isn't the name of a defined abstraction.*)
   379 (*A name is valid provided it isn't the name of a defined abstraction.*)
   344 fun valid_name defs (Free(x,T)) = not (x mem_string (List.mapPartial name_of defs))
   380 fun valid_name defs (Free(x,T)) = not (x mem_string (List.mapPartial name_of defs))
   354           Abs (_,T,u) =>
   390           Abs (_,T,u) =>
   355             let val _ = assert_eta_free ct;
   391             let val _ = assert_eta_free ct;
   356                 val (cvs,cta) = dest_abs_list ct
   392                 val (cvs,cta) = dest_abs_list ct
   357                 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs)
   393                 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs)
   358                 val (u'_th,defs) = abstract cta
   394                 val (u'_th,defs) = abstract cta
   359                 val cu' = crhs_of u'_th
   395                 val cu' = Drule.crhs_of u'_th
       
   396                 val u' = term_of cu'
   360                 (*Could use Thm.cabs instead of lambda to work at level of cterms*)
   397                 (*Could use Thm.cabs instead of lambda to work at level of cterms*)
   361                 val abs_v_u = lambda_list (map term_of cvs) (term_of cu')
   398                 val abs_v_u = lambda_list (map term_of cvs) (term_of cu')
   362                 (*get the formal parameters: free variables not present in the defs
   399                 (*get the formal parameters: free variables not present in the defs
   363                   (to avoid taking abstraction function names as parameters) *)
   400                   (to avoid taking abstraction function names as parameters) *)
   364                 val args = filter (valid_name defs) (term_frees abs_v_u)
   401                 val args = filter (valid_name defs) (term_frees abs_v_u)
   365                 val crhs = list_cabs (map cterm args, cterm abs_v_u)
   402                 val crhs = list_cabs (map cterm args, cterm abs_v_u)
   366                       (*Forms a lambda-abstraction over the formal parameters*)
   403                       (*Forms a lambda-abstraction over the formal parameters*)
   367                 val rhs = term_of crhs
   404                 val rhs = term_of crhs
   368                 val def =  (*FIXME: can we also reuse the const-abstractions?*)
   405                 val (ax,ax') =
   369                  case List.find (fn ax => rhs aconv rhs_of ax andalso
   406                  case List.mapPartial (match_rhs thy abs_v_u) 
   370                                           Context.joinable (thy, theory_of_thm ax))
   407                         (Net.match_term (!abstraction_cache) u') of
   371                         (Net.match_term (!abstraction_cache) rhs) of
   408                      (ax,ax')::_ => 
   372                      SOME ax => ax
   409                        (if !trace_abs then warning ("Re-using axiom " ^ string_of_thm ax) else ();
   373                    | NONE =>
   410                         (ax,ax'))
       
   411                    | [] =>
   374                       let val Ts = map type_of args
   412                       let val Ts = map type_of args
   375                           val const_ty = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu'))
   413                           val const_ty = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu'))
   376                           val c = Free (gensym "abs_", const_ty)
   414                           val c = Free (gensym "abs_", const_ty)
   377                           val ax = assume (Thm.capply (cterm (equals const_ty $ c)) crhs)
   415                           val ax = assume (Thm.capply (cterm (equals const_ty $ c)) crhs)
       
   416                                      |> mk_object_eq |> strip_lambdas (length args)
       
   417                                      |> mk_meta_eq |> Meson.generalize
       
   418                           val (_,ax') = Option.valOf (match_rhs thy abs_v_u ax)
   378                           val _ = abstraction_cache := Net.insert_term eq_absdef (rhs,ax)
   419                           val _ = abstraction_cache := Net.insert_term eq_absdef (rhs,ax)
   379                                     (!abstraction_cache)
   420                                     (!abstraction_cache)
   380                             handle Net.INSERT =>
   421                             handle Net.INSERT =>
   381                               raise THM ("assume_absfuns: INSERT", 0, [th,u'_th,ax])
   422                               raise THM ("assume_absfuns: INSERT", 0, [th,u'_th,ax])
   382                       in ax end
   423                       in (ax,ax') end
   383                 val _ = assert (rhs aconv rhs_of def) "assume_absfuns: rhs mismatch"
   424             in if !trace_abs then warning ("Lookup result: " ^ string_of_thm ax') else ();
   384                 val def_args = list_combination def (map cterm args)
   425                (transitive (abstract_rule_list vs cvs u'_th) (symmetric ax'), ax::defs) end
   385             in (transitive (abstract_rule_list vs cvs u'_th) (symmetric def_args),
       
   386                 def :: defs) end
       
   387         | (t1$t2) =>
   426         | (t1$t2) =>
   388             let val (ct1,ct2) = Thm.dest_comb ct
   427             let val (ct1,ct2) = Thm.dest_comb ct
   389                 val (t1',defs1) = abstract ct1
   428                 val (t1',defs1) = abstract ct1
   390                 val (t2',defs2) = abstract ct2
   429                 val (t2',defs2) = abstract ct2
   391             in  (combination t1' t2', defs1@defs2)  end
   430             in  (combination t1' t2', defs1@defs2)  end
       
   431       val _ = if !trace_abs then warning ("assume_absfuns, Abstracting: " ^ string_of_thm th) else ();
   392       val (eqth,defs) = abstract (cprop_of th)
   432       val (eqth,defs) = abstract (cprop_of th)
   393   in  equal_elim eqth th ::
   433       val ths = equal_elim eqth th :: map (strip_lambdas ~1 o mk_object_eq o freeze_thm) defs
   394       map (forall_intr_vars o strip_lambdas o object_eq) defs
   434       val _ = if !trace_abs then warning ("assume_absfuns, Result: " ^ string_of_thm (hd ths)) else ();
   395   end;
   435   in  map Drule.eta_contraction_rule ths  end;
   396 
   436 
   397 
   437 
   398 (*cterms are used throughout for efficiency*)
   438 (*cterms are used throughout for efficiency*)
   399 val cTrueprop = Thm.cterm_of HOL.thy HOLogic.Trueprop;
   439 val cTrueprop = Thm.cterm_of HOL.thy HOLogic.Trueprop;
   400 
   440 
   410 
   450 
   411 (*Given the definition of a Skolem function, return a theorem to replace
   451 (*Given the definition of a Skolem function, return a theorem to replace
   412   an existential formula by a use of that function.
   452   an existential formula by a use of that function.
   413    Example: "EX x. x : A & x ~: B ==> sko A B : A & sko A B ~: B"  [.] *)
   453    Example: "EX x. x : A & x ~: B ==> sko A B : A & sko A B ~: B"  [.] *)
   414 fun skolem_of_def def =
   454 fun skolem_of_def def =
   415   let val (c,rhs) = Drule.dest_equals (cprop_of (#1 (Drule.freeze_thaw def)))
   455   let val (c,rhs) = Drule.dest_equals (cprop_of (freeze_thm def))
   416       val (ch, frees) = c_variant_abs_multi (rhs, [])
   456       val (ch, frees) = c_variant_abs_multi (rhs, [])
   417       val (chilbert,cabs) = Thm.dest_comb ch
   457       val (chilbert,cabs) = Thm.dest_comb ch
   418       val {sign,t, ...} = rep_cterm chilbert
   458       val {sign,t, ...} = rep_cterm chilbert
   419       val T = case t of Const ("Hilbert_Choice.Eps", Type("fun",[_,T])) => T
   459       val T = case t of Const ("Hilbert_Choice.Eps", Type("fun",[_,T])) => T
   420                       | _ => raise THM ("skolem_of_def: expected Eps", 0, [def])
   460                       | _ => raise THM ("skolem_of_def: expected Eps", 0, [def])
   426        |> forall_intr_list frees
   466        |> forall_intr_list frees
   427        |> forall_elim_vars 0  (*Introduce Vars, but don't discharge defs.*)
   467        |> forall_elim_vars 0  (*Introduce Vars, but don't discharge defs.*)
   428        |> Thm.varifyT
   468        |> Thm.varifyT
   429   end;
   469   end;
   430 
   470 
   431 (*Converts an Isabelle theorem (intro, elim or simp format) into nnf.*)
   471 (*Converts an Isabelle theorem (intro, elim or simp format, even higher-order) into NNF.*)
   432 (*It now works for HOL too. *)
       
   433 fun to_nnf th =
   472 fun to_nnf th =
   434     th |> transfer_to_Reconstruction
   473     th |> transfer_to_Reconstruction
   435        |> transform_elim |> zero_var_indexes |> Drule.freeze_thaw |> #1
   474        |> transform_elim |> zero_var_indexes |> freeze_thm
   436        |> ObjectLogic.atomize_thm |> make_nnf |> strip_lambdas;
   475        |> ObjectLogic.atomize_thm |> make_nnf |> strip_lambdas ~1;
   437 
   476 
   438 (*The cache prevents repeated clausification of a theorem,
   477 (*The cache prevents repeated clausification of a theorem,
   439   and also repeated declaration of Skolem functions*)
   478   and also repeated declaration of Skolem functions*)
   440   (* FIXME better use Termtab!? No, we MUST use theory data!!*)
   479   (* FIXME better use Termtab!? No, we MUST use theory data!!*)
   441 val clause_cache = ref (Symtab.empty : (thm * thm list) Symtab.table)
   480 val clause_cache = ref (Symtab.empty : (thm * thm list) Symtab.table)
   443 
   482 
   444 (*Generate Skolem functions for a theorem supplied in nnf*)
   483 (*Generate Skolem functions for a theorem supplied in nnf*)
   445 fun skolem_of_nnf th =
   484 fun skolem_of_nnf th =
   446   map (skolem_of_def o assume o (cterm_of (theory_of_thm th))) (assume_skofuns th);
   485   map (skolem_of_def o assume o (cterm_of (theory_of_thm th))) (assume_skofuns th);
   447 
   486 
   448 fun assert_lambda_free ths = assert (forall (lambda_free o prop_of) ths);
   487 fun assert_lambda_free ths msg = 
       
   488   case filter (not o lambda_free o prop_of) ths of
       
   489       [] => ()
       
   490      | ths' => error (msg ^ "\n" ^ space_implode "\n" (map string_of_thm ths'));
   449 
   491 
   450 fun assume_abstract th =
   492 fun assume_abstract th =
   451   if lambda_free (prop_of th) then [th]
   493   if lambda_free (prop_of th) then [th]
   452   else th |> eta_conversion_rule |> assume_absfuns
   494   else th |> Drule.eta_contraction_rule |> assume_absfuns
   453           |> tap (fn ths => assert_lambda_free ths "assume_abstract: lambdas")
   495           |> tap (fn ths => assert_lambda_free ths "assume_abstract: lambdas")
   454 
   496 
   455 (*Replace lambdas by assumed function definitions in the theorems*)
   497 (*Replace lambdas by assumed function definitions in the theorems*)
   456 fun assume_abstract_list ths =
   498 fun assume_abstract_list ths =
   457   if abstract_lambdas then List.concat (map assume_abstract ths)
   499   if abstract_lambdas then List.concat (map assume_abstract ths)
   458   else map eta_conversion_rule ths;
   500   else map Drule.eta_contraction_rule ths;
   459 
   501 
   460 (*Replace lambdas by declared function definitions in the theorems*)
   502 (*Replace lambdas by declared function definitions in the theorems*)
   461 fun declare_abstract' (thy, []) = (thy, [])
   503 fun declare_abstract' (thy, []) = (thy, [])
   462   | declare_abstract' (thy, th::ths) =
   504   | declare_abstract' (thy, th::ths) =
   463       let val (thy', th_defs) =
   505       let val (thy', th_defs) =
   464             if lambda_free (prop_of th) then (thy, [th])
   506             if lambda_free (prop_of th) then (thy, [th])
   465             else
   507             else
   466                 th |> zero_var_indexes |> Drule.freeze_thaw |> #1
   508                 th |> zero_var_indexes |> freeze_thm
   467                    |> eta_conversion_rule |> transfer thy |> declare_absfuns
   509                    |> Drule.eta_contraction_rule |> transfer thy |> declare_absfuns
   468           val _ = assert_lambda_free th_defs "declare_abstract: lambdas"
   510           val _ = assert_lambda_free th_defs "declare_abstract: lambdas"
   469           val (thy'', ths') = declare_abstract' (thy', ths)
   511           val (thy'', ths') = declare_abstract' (thy', ths)
   470       in  (thy'', th_defs @ ths')  end;
   512       in  (thy'', th_defs @ ths')  end;
   471 
   513 
   472 (*FIXME DELETE if we decide to switch to abstractions*)
   514 (*FIXME DELETE if we decide to switch to abstractions*)
   473 fun declare_abstract (thy, ths) =
   515 fun declare_abstract (thy, ths) =
   474   if abstract_lambdas then declare_abstract' (thy, ths)
   516   if abstract_lambdas then declare_abstract' (thy, ths)
   475   else (thy, map eta_conversion_rule ths);
   517   else (thy, map Drule.eta_contraction_rule ths);
   476 
   518 
   477 (*Skolemize a named theorem, with Skolem functions as additional premises.*)
   519 (*Skolemize a named theorem, with Skolem functions as additional premises.*)
   478 (*also works for HOL*)
   520 (*also works for HOL*)
   479 fun skolem_thm th =
   521 fun skolem_thm th =
   480   let val nnfth = to_nnf th
   522   let val nnfth = to_nnf th
   601 (*Setup function: takes a theory and installs ALL known theorems into the clause cache*)
   643 (*Setup function: takes a theory and installs ALL known theorems into the clause cache*)
   602 
   644 
   603 fun skolem_cache (name,th) thy =
   645 fun skolem_cache (name,th) thy =
   604   let val prop = Thm.prop_of th
   646   let val prop = Thm.prop_of th
   605   in
   647   in
   606       if lambda_free prop orelse monomorphic prop
   648       if lambda_free prop (*orelse monomorphic prop*)
   607       then thy    (*monomorphic theorems can be Skolemized on demand*)
   649       then thy    (*monomorphic theorems can be Skolemized on demand*)
   608       else #2 (skolem_cache_thm (name,th) thy)
   650       else #2 (skolem_cache_thm (name,th) thy)
   609   end;
   651   end;
   610 
   652 
   611 fun clause_cache_setup thy = fold skolem_cache (PureThy.all_thms_of thy) thy;
   653 fun clause_cache_setup thy = fold skolem_cache (PureThy.all_thms_of thy) thy;