src/HOL/Tools/res_axioms.ML
changeset 24827 646bdc51eb7d
parent 24821 cc55041ca8ba
child 24854 0ebcd575d3c6
equal deleted inserted replaced
24826:78e6a3cea367 24827:646bdc51eb7d
    13   val skolem_thm: thm -> thm list
    13   val skolem_thm: thm -> thm list
    14   val cnf_rules_pairs: (string * thm) list -> (thm * (string * int)) list
    14   val cnf_rules_pairs: (string * thm) list -> (thm * (string * int)) list
    15   val cnf_rules_of_ths: thm list -> thm list
    15   val cnf_rules_of_ths: thm list -> thm list
    16   val neg_clausify: thm list -> thm list
    16   val neg_clausify: thm list -> thm list
    17   val expand_defs_tac: thm -> tactic
    17   val expand_defs_tac: thm -> tactic
    18   val assume_abstract_list: string -> thm list -> thm list
    18   val combinators: thm -> thm
    19   val neg_conjecture_clauses: thm -> int -> thm list * (string * typ) list
    19   val neg_conjecture_clauses: thm -> int -> thm list * (string * typ) list
    20   val claset_rules_of: Proof.context -> (string * thm) list   (*FIXME DELETE*)
    20   val claset_rules_of: Proof.context -> (string * thm) list   (*FIXME DELETE*)
    21   val simpset_rules_of: Proof.context -> (string * thm) list  (*FIXME DELETE*)
    21   val simpset_rules_of: Proof.context -> (string * thm) list  (*FIXME DELETE*)
    22   val atpset_rules_of: Proof.context -> (string * thm) list
    22   val atpset_rules_of: Proof.context -> (string * thm) list
    23   val meson_method_setup: theory -> theory
    23   val meson_method_setup: theory -> theory
    28 structure ResAxioms: RES_AXIOMS =
    28 structure ResAxioms: RES_AXIOMS =
    29 struct
    29 struct
    30 
    30 
    31 (* FIXME legacy *)
    31 (* FIXME legacy *)
    32 fun freeze_thm th = #1 (Drule.freeze_thaw th);
    32 fun freeze_thm th = #1 (Drule.freeze_thaw th);
    33 
       
    34 val lhs_of = #1 o Logic.dest_equals o Thm.prop_of;
       
    35 val rhs_of = #2 o Logic.dest_equals o Thm.prop_of;
       
    36 
       
    37 
       
    38 (*Store definitions of abstraction functions, ensuring that identical right-hand
       
    39   sides are denoted by the same functions and thereby reducing the need for
       
    40   extensionality in proofs.
       
    41   FIXME!  Store in theory data!!*)
       
    42 
       
    43 (*Populate the abstraction cache with common combinators.*)
       
    44 fun seed th net =
       
    45   let val (_,ct) = Thm.dest_abs NONE (Thm.rhs_of th)
       
    46       val t = Logic.legacy_varify (term_of ct)
       
    47   in  Net.insert_term Thm.eq_thm (t, th) net end;
       
    48 
       
    49 val abstraction_cache = ref
       
    50       (seed (thm"ATP_Linkup.I_simp")
       
    51        (seed (thm"ATP_Linkup.B_simp")
       
    52         (seed (thm"ATP_Linkup.K_simp") Net.empty)));
       
    53 
    33 
    54 
    34 
    55 (**** Transformation of Elimination Rules into First-Order Formulas****)
    35 (**** Transformation of Elimination Rules into First-Order Formulas****)
    56 
    36 
    57 val cfalse = cterm_of HOL.thy HOLogic.false_const;
    37 val cfalse = cterm_of HOL.thy HOLogic.false_const;
   147         | dec_sko (Const ("Trueprop", _) $ p) defs = dec_sko p defs
   127         | dec_sko (Const ("Trueprop", _) $ p) defs = dec_sko p defs
   148         | dec_sko t defs = defs (*Do nothing otherwise*)
   128         | dec_sko t defs = defs (*Do nothing otherwise*)
   149   in  dec_sko (prop_of th) []  end;
   129   in  dec_sko (prop_of th) []  end;
   150 
   130 
   151 
   131 
   152 (**** REPLACING ABSTRACTIONS BY FUNCTION DEFINITIONS ****)
   132 (**** REPLACING ABSTRACTIONS BY COMBINATORS ****)
   153 
   133 
   154 (*Returns the vars of a theorem*)
   134 (*Returns the vars of a theorem*)
   155 fun vars_of_thm th =
   135 fun vars_of_thm th =
   156   map (Thm.cterm_of (theory_of_thm th) o Var) (Thm.fold_terms Term.add_vars th []);
   136   map (Thm.cterm_of (theory_of_thm th) o Var) (Thm.fold_terms Term.add_vars th []);
   157 
   137 
   173       case prop_of th of
   153       case prop_of th of
   174           _ $ (Const ("op =", _) $ _ $ Abs (x,_,_)) =>
   154           _ $ (Const ("op =", _) $ _ $ Abs (x,_,_)) =>
   175               strip_lambdas (n-1) (freeze_thm (th RS xfun_cong x))
   155               strip_lambdas (n-1) (freeze_thm (th RS xfun_cong x))
   176         | _ => th;
   156         | _ => th;
   177 
   157 
   178 (*Convert meta- to object-equality. Fails for theorems like split_comp_eq,
       
   179   where some types have the empty sort.*)
       
   180 val meta_eq_to_obj_eq = thm "meta_eq_to_obj_eq";
       
   181 fun mk_object_eq th = th RS meta_eq_to_obj_eq
       
   182     handle THM _ => error ("Theorem contains empty sort: " ^ string_of_thm th);
       
   183 
       
   184 (*Apply a function definition to an argument, beta-reducing the result.*)
       
   185 fun beta_comb cf x =
       
   186   let val th1 = combination cf (reflexive x)
       
   187       val th2 = beta_conversion false (Thm.rhs_of th1)
       
   188   in  transitive th1 th2  end;
       
   189 
       
   190 (*Apply a function definition to arguments, beta-reducing along the way.*)
       
   191 fun list_combination cf [] = cf
       
   192   | list_combination cf (x::xs) = list_combination (beta_comb cf x) xs;
       
   193 
       
   194 fun list_cabs ([] ,     t) = t
       
   195   | list_cabs (v::vars, t) = Thm.cabs v (list_cabs(vars,t));
       
   196 
       
   197 fun assert_eta_free ct =
   158 fun assert_eta_free ct =
   198   let val t = term_of ct
   159   let val t = term_of ct
   199   in if (t aconv Envir.eta_contract t) then ()
   160   in if (t aconv Envir.eta_contract t) then ()
   200      else error ("Eta redex in term: " ^ string_of_cterm ct)
   161      else error ("Eta redex in term: " ^ string_of_cterm ct)
   201   end;
   162   end;
   202 
   163 
   203 fun eq_absdef (th1, th2) =
       
   204     Context.joinable (theory_of_thm th1, theory_of_thm th2)  andalso
       
   205     rhs_of th1 aconv rhs_of th2;
       
   206 
       
   207 val lambda_free = not o Term.has_abs;
   164 val lambda_free = not o Term.has_abs;
   208 
   165 
   209 val monomorphic = not o Term.exists_type (Term.exists_subtype Term.is_TVar);
   166 val monomorphic = not o Term.exists_type (Term.exists_subtype Term.is_TVar);
   210 
   167 
   211 fun dest_abs_list ct =
   168 val abs_S = @{thm"abs_S"};
   212   let val (cv,ct') = Thm.dest_abs NONE ct
   169 val abs_K = @{thm"abs_K"};
   213       val (cvs,cu) = dest_abs_list ct'
   170 val abs_I = @{thm"abs_I"};
   214   in (cv::cvs, cu) end
   171 val abs_B = @{thm"abs_B"};
   215   handle CTERM _ => ([],ct);
   172 val abs_C = @{thm"abs_C"};
   216 
   173 
   217 fun abstract_rule_list [] [] th = th
   174 val [f_B,g_B] = map (cterm_of @{theory}) (term_vars (prop_of abs_B));
   218   | abstract_rule_list (v::vs) (ct::cts) th = abstract_rule v ct (abstract_rule_list vs cts th)
   175 val [g_C,f_C] = map (cterm_of @{theory}) (term_vars (prop_of abs_C));
   219   | abstract_rule_list _ _ th = raise THM ("abstract_rule_list", 0, [th]);
   176 val [f_S,g_S] = map (cterm_of @{theory}) (term_vars (prop_of abs_S));
   220 
   177 
   221 
   178 (*FIXME: requires more use of cterm constructors*)
   222 val Envir.Envir {asol = tenv0, iTs = tyenv0, ...} = Envir.empty 0
   179 fun abstract ct =
   223 
   180   let val Abs(x,_,body) = term_of ct
   224 (*Does an existing abstraction definition have an RHS that matches the one we need now?
   181       val thy = theory_of_cterm ct
   225   thy is the current theory, which must extend that of theorem th.*)
   182       val Type("fun",[xT,bodyT]) = typ_of (ctyp_of_term ct)
   226 fun match_rhs thy t th =
   183       val cxT = ctyp_of thy xT and cbodyT = ctyp_of thy bodyT
   227   let val _ = Output.debug (fn()=> "match_rhs: " ^ string_of_cterm (cterm_of thy t) ^
   184       fun makeK() = instantiate' [SOME cxT, SOME cbodyT] [SOME (cterm_of thy body)] abs_K
   228                                    " against\n" ^ string_of_thm th);
   185   in
   229       val (tyenv,tenv) = Pattern.first_order_match thy (rhs_of th, t) (tyenv0,tenv0)
   186       case body of
   230       val term_insts = map Meson.term_pair_of (Vartab.dest tenv)
   187           Const _ => makeK()
   231       val ct_pairs = if subthy (theory_of_thm th, thy) andalso
   188         | Free _ => makeK()
   232                         forall lambda_free (map #2 term_insts)
   189         | Var _ => makeK()  (*though Var isn't expected*)
   233                      then map (pairself (cterm_of thy)) term_insts
   190         | Bound 0 => instantiate' [SOME cxT] [] abs_I (*identity: I*)
   234                      else raise Pattern.MATCH (*Cannot allow lambdas in the instantiation*)
   191         | rator$rand =>
   235       fun ctyp2 (ixn, (S, T)) = (ctyp_of thy (TVar (ixn, S)), ctyp_of thy T)
   192 	    if loose_bvar1 (rator,0) then (*C or S*) 
   236       val th' = cterm_instantiate ct_pairs th
   193 	       if loose_bvar1 (rand,0) then (*S*)
   237   in  SOME (th, instantiate (map ctyp2 (Vartab.dest tyenv), []) th')  end
   194 	         let val crator = cterm_of thy (Abs(x,xT,rator))
   238   handle _ => NONE;
   195 	             val crand = cterm_of thy (Abs(x,xT,rand))
       
   196 	             val abs_S' = cterm_instantiate [(f_S,crator),(g_S,crand)] abs_S
       
   197 	             val (_,rhs) = Thm.dest_equals (cprop_of abs_S') 
       
   198 	         in
       
   199 	           Thm.transitive abs_S' (Conv.binop_conv abstract rhs)
       
   200 	         end
       
   201 	       else (*C*)
       
   202 	         let val crator = cterm_of thy (Abs(x,xT,rator))
       
   203 	             val abs_C' = cterm_instantiate [(f_C,crator),(g_C,cterm_of thy rand)] abs_C
       
   204 	             val (_,rhs) = Thm.dest_equals (cprop_of abs_C') 
       
   205 	         in
       
   206 	           Thm.transitive abs_C' (Conv.fun_conv (Conv.arg_conv abstract) rhs)
       
   207 	         end
       
   208 	    else if loose_bvar1 (rand,0) then (*B or eta*) 
       
   209 	       if rand = Bound 0 then eta_conversion ct
       
   210 	       else (*B*)
       
   211 	         let val crand = cterm_of thy (Abs(x,xT,rand))
       
   212 	             val abs_B' = cterm_instantiate [(f_B, cterm_of thy rator),(g_B,crand)] abs_B
       
   213 	             val (_,rhs) = Thm.dest_equals (cprop_of abs_B') 
       
   214 	         in
       
   215 	           Thm.transitive abs_B' (Conv.arg_conv abstract rhs)
       
   216 	         end
       
   217 	    else makeK()
       
   218         | _ => error "abstract: Bad term"
       
   219   end;
   239 
   220 
   240 (*Traverse a theorem, declaring abstraction function definitions. String s is the suggested
   221 (*Traverse a theorem, declaring abstraction function definitions. String s is the suggested
   241   prefix for the constants. Resulting theory is returned in the first theorem. *)
   222   prefix for the constants. Resulting theory is returned in the first theorem. *)
   242 fun declare_absfuns s th =
   223 fun combinators_aux ct =
   243   let val nref = ref 0
   224   if lambda_free (term_of ct) then reflexive ct
   244       fun abstract thy ct =
   225   else
   245         if lambda_free (term_of ct) then (transfer thy (reflexive ct), [])
   226   case term_of ct of
   246         else
   227       Abs _ =>
   247         case term_of ct of
   228 	let val _ = assert_eta_free ct;
   248           Abs _ =>
   229 	    val (cv,cta) = Thm.dest_abs NONE ct
   249             let val cname = "llabs_" ^ s ^ "_" ^ Int.toString (inc nref)
   230 	    val (v,Tv) = (dest_Free o term_of) cv
   250                 val _ = assert_eta_free ct;
   231 	    val _ = Output.debug (fn()=>"  recursion: " ^ string_of_cterm cta);
   251                 val (cvs,cta) = dest_abs_list ct
   232 	    val u_th = combinators_aux cta
   252                 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs)
   233 	    val _ = Output.debug (fn()=>"  returned " ^ string_of_thm u_th);
   253                 val _ = Output.debug (fn()=>"Nested lambda: " ^ string_of_cterm cta);
   234 	    val cu = Thm.rhs_of u_th
   254                 val (u'_th,defs) = abstract thy cta
   235 	    val comb_eq = abstract (Thm.cabs cv cu)
   255                 val _ = Output.debug (fn()=>"Returned " ^ string_of_thm u'_th);
   236 	in Output.debug (fn()=>"  abstraction result: " ^ string_of_thm comb_eq);
   256                 val cu' = Thm.rhs_of u'_th
   237 	   (transitive (abstract_rule v cv u_th) comb_eq) end
   257                 val u' = term_of cu'
   238     | t1 $ t2 =>
   258                 val abs_v_u = fold_rev (lambda o term_of) cvs u'
   239 	let val (ct1,ct2) = Thm.dest_comb ct
   259                 (*get the formal parameters: ALL variables free in the term*)
   240 	in  combination (combinators_aux ct1) (combinators_aux ct2)  end;
   260                 val args = term_frees abs_v_u
   241             
   261                 val _ = Output.debug (fn()=>Int.toString (length args) ^ " arguments");
   242 fun combinators th =
   262                 val rhs = list_abs_free (map dest_Free args, abs_v_u)
   243   if lambda_free (prop_of th) then th 
   263                       (*Forms a lambda-abstraction over the formal parameters*)
   244   else
   264                 val _ = Output.debug (fn()=>"Looking up " ^ string_of_cterm cu');
   245     let val _ = Output.debug (fn()=>"Conversion to combinators: " ^ string_of_thm th);
   265                 val thy = theory_of_thm u'_th
   246 	val th = Drule.eta_contraction_rule th
   266                 val (ax,ax',thy) =
   247 	val eqth = combinators_aux (cprop_of th)
   267                  case List.mapPartial (match_rhs thy abs_v_u)
   248 	val _ = Output.debug (fn()=>"Conversion result: " ^ string_of_thm eqth);
   268                          (Net.match_term (!abstraction_cache) u') of
   249     in  equal_elim eqth th   end;
   269                      (ax,ax')::_ =>
       
   270                        (Output.debug (fn()=>"Re-using axiom " ^ string_of_thm ax);
       
   271                         (ax,ax',thy))
       
   272                    | [] =>
       
   273                       let val _ = Output.debug (fn()=>"Lookup was empty");
       
   274                           val Ts = map type_of args
       
   275                           val cT = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu'))
       
   276                           val c = Const (Sign.full_name thy cname, cT)
       
   277                           val thy =
       
   278                             Sign.add_consts_authentic [Markup.property_internal] [(cname, cT, NoSyn)] thy
       
   279                                      (*Theory is augmented with the constant,
       
   280                                        then its definition*)
       
   281                           val cdef = cname ^ "_def"
       
   282                           val thy = Theory.add_defs_i true false
       
   283                                        [(cdef, equals cT $ c $ rhs)] thy
       
   284                                     handle ERROR _ => raise Clausify_failure thy
       
   285                           val ax = Thm.get_axiom_i thy (Sign.full_name thy cdef)
       
   286                                      |> Drule.unvarify
       
   287                                      |> mk_object_eq |> strip_lambdas (length args)
       
   288                                      |> mk_meta_eq |> Meson.generalize
       
   289                           val (_,ax') = Option.valOf (match_rhs thy abs_v_u ax)
       
   290                           val _ = Output.debug (fn()=> "Declaring: " ^ string_of_thm ax ^ "\n" ^
       
   291                                                        "Instance: " ^ string_of_thm ax');
       
   292                           val _ = abstraction_cache := Net.insert_term eq_absdef
       
   293                                             ((Logic.varify u'), ax) (!abstraction_cache)
       
   294                             handle Net.INSERT =>
       
   295                               raise THM ("declare_absfuns: INSERT", 0, [th,u'_th,ax])
       
   296                        in  (ax,ax',thy)  end
       
   297             in Output.debug (fn()=>"Lookup result: " ^ string_of_thm ax');
       
   298                (transitive (abstract_rule_list vs cvs u'_th) (symmetric ax'), ax::defs) end
       
   299         | (t1$t2) =>
       
   300             let val (ct1,ct2) = Thm.dest_comb ct
       
   301                 val (th1,defs1) = abstract thy ct1
       
   302                 val (th2,defs2) = abstract (theory_of_thm th1) ct2
       
   303             in  (combination th1 th2, defs1@defs2)  end
       
   304       val _ = Output.debug (fn()=>"declare_absfuns, Abstracting: " ^ string_of_thm th);
       
   305       val (eqth,defs) = abstract (theory_of_thm th) (cprop_of th)
       
   306       val ths = equal_elim eqth th :: map (strip_lambdas ~1 o mk_object_eq o freeze_thm) defs
       
   307       val _ = Output.debug (fn()=>"declare_absfuns, Result: " ^ string_of_thm (hd ths));
       
   308   in  (theory_of_thm eqth, map Drule.eta_contraction_rule ths)  end;
       
   309 
       
   310 fun name_of def = try (#1 o dest_Free o lhs_of) def;
       
   311 
       
   312 (*A name is valid provided it isn't the name of a defined abstraction.*)
       
   313 fun valid_name defs (Free(x,T)) = not (x mem_string (List.mapPartial name_of defs))
       
   314   | valid_name defs _ = false;
       
   315 
       
   316 (*s is the theorem name (hint) or the word "subgoal"*)
       
   317 fun assume_absfuns s th =
       
   318   let val thy = theory_of_thm th
       
   319       val cterm = cterm_of thy
       
   320       val abs_count = ref 0
       
   321       fun abstract ct =
       
   322         if lambda_free (term_of ct) then (reflexive ct, [])
       
   323         else
       
   324         case term_of ct of
       
   325           Abs (_,T,u) =>
       
   326             let val _ = assert_eta_free ct;
       
   327                 val (cvs,cta) = dest_abs_list ct
       
   328                 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs)
       
   329                 val (u'_th,defs) = abstract cta
       
   330                 val cu' = Thm.rhs_of u'_th
       
   331                 val u' = term_of cu'
       
   332                 (*Could use Thm.cabs instead of lambda to work at level of cterms*)
       
   333                 val abs_v_u = fold_rev (lambda o term_of) cvs (term_of cu')
       
   334                 (*get the formal parameters: free variables not present in the defs
       
   335                   (to avoid taking abstraction function names as parameters) *)
       
   336                 val args = filter (valid_name defs) (term_frees abs_v_u)
       
   337                 val crhs = list_cabs (map cterm args, cterm abs_v_u)
       
   338                       (*Forms a lambda-abstraction over the formal parameters*)
       
   339                 val rhs = term_of crhs
       
   340                 val (ax,ax') =
       
   341                  case List.mapPartial (match_rhs thy abs_v_u)
       
   342                         (Net.match_term (!abstraction_cache) u') of
       
   343                      (ax,ax')::_ =>
       
   344                        (Output.debug (fn()=>"Re-using axiom " ^ string_of_thm ax);
       
   345                         (ax,ax'))
       
   346                    | [] =>
       
   347                       let val Ts = map type_of args
       
   348                           val const_ty = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu'))
       
   349                           val id = "llabs_" ^ s ^ "_" ^ Int.toString (inc abs_count)
       
   350                           val c = Free (id, const_ty)
       
   351                           val ax = assume (Thm.capply (cterm (equals const_ty $ c)) crhs)
       
   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 _ = abstraction_cache := Net.insert_term eq_absdef (rhs,ax)
       
   356                                     (!abstraction_cache)
       
   357                             handle Net.INSERT =>
       
   358                               raise THM ("assume_absfuns: INSERT", 0, [th,u'_th,ax])
       
   359                       in (ax,ax') end
       
   360             in Output.debug (fn()=>"Lookup result: " ^ string_of_thm ax');
       
   361                (transitive (abstract_rule_list vs cvs u'_th) (symmetric ax'), ax::defs) end
       
   362         | (t1$t2) =>
       
   363             let val (ct1,ct2) = Thm.dest_comb ct
       
   364                 val (t1',defs1) = abstract ct1
       
   365                 val (t2',defs2) = abstract ct2
       
   366             in  (combination t1' t2', defs1@defs2)  end
       
   367       val _ = Output.debug (fn()=>"assume_absfuns, Abstracting: " ^ string_of_thm th);
       
   368       val (eqth,defs) = abstract (cprop_of th)
       
   369       val ths = equal_elim eqth th :: map (strip_lambdas ~1 o mk_object_eq o freeze_thm) defs
       
   370       val _ = Output.debug (fn()=>"assume_absfuns, Result: " ^ string_of_thm (hd ths));
       
   371   in  map Drule.eta_contraction_rule ths  end;
       
   372 
       
   373 
   250 
   374 (*cterms are used throughout for efficiency*)
   251 (*cterms are used throughout for efficiency*)
   375 val cTrueprop = Thm.cterm_of HOL.thy HOLogic.Trueprop;
   252 val cTrueprop = Thm.cterm_of HOL.thy HOLogic.Trueprop;
   376 
   253 
   377 (*cterm version of mk_cTrueprop*)
   254 (*cterm version of mk_cTrueprop*)
   428 fun assert_lambda_free ths msg =
   305 fun assert_lambda_free ths msg =
   429   case filter (not o lambda_free o prop_of) ths of
   306   case filter (not o lambda_free o prop_of) ths of
   430       [] => ()
   307       [] => ()
   431     | ths' => error (msg ^ "\n" ^ cat_lines (map string_of_thm ths'));
   308     | ths' => error (msg ^ "\n" ^ cat_lines (map string_of_thm ths'));
   432 
   309 
   433 fun assume_abstract s th =
       
   434   if lambda_free (prop_of th) then [th]
       
   435   else th |> Drule.eta_contraction_rule |> assume_absfuns s
       
   436           |> tap (fn ths => assert_lambda_free ths "assume_abstract: lambdas")
       
   437 
       
   438 (*Replace lambdas by assumed function definitions in the theorems*)
       
   439 fun assume_abstract_list s ths = List.concat (map (assume_abstract s) ths);
       
   440 
       
   441 (*Replace lambdas by declared function definitions in the theorems*)
       
   442 fun declare_abstract s (thy, []) = (thy, [])
       
   443   | declare_abstract s (thy, th::ths) =
       
   444       let val (thy', th_defs) =
       
   445             if lambda_free (prop_of th) then (thy, [th])
       
   446             else
       
   447                 th |> zero_var_indexes |> freeze_thm
       
   448                    |> Drule.eta_contraction_rule |> transfer thy |> declare_absfuns s
       
   449                 handle Clausify_failure thy_e => (thy_e,[])
       
   450           val _ = assert_lambda_free th_defs "declare_abstract: lambdas"
       
   451           val (thy'', ths') = declare_abstract (s^"'") (thy', ths)
       
   452       in  (thy'', th_defs @ ths')  end;
       
   453 
       
   454 (*Keep the full complexity of the original name*)
   310 (*Keep the full complexity of the original name*)
   455 fun flatten_name s = space_implode "_X" (NameSpace.explode s);
   311 fun flatten_name s = space_implode "_X" (NameSpace.explode s);
   456 
   312 
   457 fun fake_name th =
   313 fun fake_name th =
   458   if PureThy.has_name_hint th then flatten_name (PureThy.get_name_hint th)
   314   if PureThy.has_name_hint th then flatten_name (PureThy.get_name_hint th)
   463   else string_of_thm th;
   319   else string_of_thm th;
   464 
   320 
   465 (*Skolemize a named theorem, with Skolem functions as additional premises.*)
   321 (*Skolemize a named theorem, with Skolem functions as additional premises.*)
   466 fun skolem_thm th =
   322 fun skolem_thm th =
   467   let val nnfth = to_nnf th and s = fake_name th
   323   let val nnfth = to_nnf th and s = fake_name th
   468   in  Meson.make_cnf (skolem_of_nnf s nnfth) nnfth |> assume_abstract_list s |> Meson.finish_cnf
   324   in  Meson.make_cnf (skolem_of_nnf s nnfth) nnfth |>  map combinators |> Meson.finish_cnf
   469   end
   325   end
   470   handle THM _ => [];
   326   handle THM _ => [];
   471 
   327 
   472 (*Declare Skolem functions for a theorem, supplied in nnf and with its name.
   328 (*Declare Skolem functions for a theorem, supplied in nnf and with its name.
   473   It returns a modified theory, unless skolemization fails.*)
   329   It returns a modified theory, unless skolemization fails.*)
   478               val _ = Output.debug (fn () => string_of_thm nnfth)
   334               val _ = Output.debug (fn () => string_of_thm nnfth)
   479               val s = fake_name th
   335               val s = fake_name th
   480               val (thy',defs) = declare_skofuns s nnfth thy
   336               val (thy',defs) = declare_skofuns s nnfth thy
   481               val cnfs = Meson.make_cnf (map skolem_of_def defs) nnfth
   337               val cnfs = Meson.make_cnf (map skolem_of_def defs) nnfth
   482               val _ = Output.debug (fn () => Int.toString (length cnfs) ^ " clauses yielded")
   338               val _ = Output.debug (fn () => Int.toString (length cnfs) ^ " clauses yielded")
   483               val (thy'',cnfs') = declare_abstract s (thy',cnfs)
   339               val cnfs' = map combinators cnfs
   484           in (map Goal.close_result (Meson.finish_cnf cnfs'), thy'') end
   340           in (map Goal.close_result (Meson.finish_cnf cnfs'), thy') end
   485           handle Clausify_failure thy_e => ([],thy_e)
   341           handle Clausify_failure thy_e => ([],thy_e)
   486         )
   342         )
   487       (try to_nnf th);
   343       (try to_nnf th);
   488 
   344 
   489 (*The cache prevents repeated clausification of a theorem, and also repeated declaration of
   345 (*The cache prevents repeated clausification of a theorem, and also repeated declaration of
   573 
   429 
   574 (*Setup function: takes a theory and installs ALL known theorems into the clause cache*)
   430 (*Setup function: takes a theory and installs ALL known theorems into the clause cache*)
   575 
   431 
   576 val mark_skolemized = Sign.add_consts_i [("ResAxioms_endtheory", HOLogic.boolT, NoSyn)];
   432 val mark_skolemized = Sign.add_consts_i [("ResAxioms_endtheory", HOLogic.boolT, NoSyn)];
   577 
   433 
       
   434 val max_lambda_nesting = 3;
       
   435      
       
   436 fun excessive_lambdas (f$t, k) = excessive_lambdas (f,k) orelse excessive_lambdas (t,k)
       
   437   | excessive_lambdas (Abs(_,_,t), k) = k=0 orelse excessive_lambdas (t,k-1)
       
   438   | excessive_lambdas _ = false;
       
   439 
       
   440 fun is_formula_type T = (T = HOLogic.boolT orelse T = propT);
       
   441 
       
   442 (*Don't count nested lambdas at the level of formulas, as they are quantifiers*)
       
   443 fun excessive_lambdas_fm Ts (Abs(_,T,t)) = excessive_lambdas_fm (T::Ts) t
       
   444   | excessive_lambdas_fm Ts t =
       
   445       if is_formula_type (fastype_of1 (Ts, t))
       
   446       then exists (excessive_lambdas_fm Ts) (#2 (strip_comb t))
       
   447       else excessive_lambdas (t, max_lambda_nesting);
       
   448 
       
   449 fun too_complex t = 
       
   450   Meson.too_many_clauses t orelse excessive_lambdas_fm [] t;
       
   451   
   578 fun skolem_cache th thy =
   452 fun skolem_cache th thy =
   579   if PureThy.is_internal th then thy
   453   if PureThy.is_internal th orelse too_complex (prop_of th) then thy
   580   else #2 (skolem_cache_thm th thy);
   454   else #2 (skolem_cache_thm th thy);
   581 
   455 
   582 val skolem_cache_theorems_of = Symtab.fold (fold skolem_cache o snd) o #2 o PureThy.theorems_of;
   456 val skolem_cache_theorems_of = Symtab.fold (fold skolem_cache o snd) o #2 o PureThy.theorems_of;
   583 fun skolem_cache_node thy = skolem_cache_theorems_of thy thy;
   457 fun skolem_cache_node thy = skolem_cache_theorems_of thy thy;
   584 fun skolem_cache_all thy = fold skolem_cache_theorems_of (thy :: Theory.ancestors_of thy) thy;
   458 fun skolem_cache_all thy = fold skolem_cache_theorems_of (thy :: Theory.ancestors_of thy) thy;
   596 (*** meson proof methods ***)
   470 (*** meson proof methods ***)
   597 
   471 
   598 fun cnf_rules_of_ths ths = List.concat (map cnf_axiom ths);
   472 fun cnf_rules_of_ths ths = List.concat (map cnf_axiom ths);
   599 
   473 
   600 (*Expand all new*definitions of abstraction or Skolem functions in a proof state.*)
   474 (*Expand all new*definitions of abstraction or Skolem functions in a proof state.*)
   601 fun is_absko (Const ("==", _) $ Free (a,_) $ u) = String.isPrefix "llabs_" a orelse String.isPrefix "sko_" a
   475 fun is_absko (Const ("==", _) $ Free (a,_) $ u) = String.isPrefix "sko_" a
   602   | is_absko _ = false;
   476   | is_absko _ = false;
   603 
   477 
   604 fun is_okdef xs (Const ("==", _) $ t $ u) =   (*Definition of Free, not in certain terms*)
   478 fun is_okdef xs (Const ("==", _) $ t $ u) =   (*Definition of Free, not in certain terms*)
   605       is_Free t andalso not (member (op aconv) xs t)
   479       is_Free t andalso not (member (op aconv) xs t)
   606   | is_okdef _ _ = false
   480   | is_okdef _ _ = false
   607 
   481 
   608 (*This function tries to cope with open locales, which introduce hypotheses of the form
   482 (*This function tries to cope with open locales, which introduce hypotheses of the form
   609   Free == t, conjecture clauses, which introduce various hypotheses, and also definitions
   483   Free == t, conjecture clauses, which introduce various hypotheses, and also definitions
   610   of llabs_ and sko_ functions. *)
   484   of sko_ functions. *)
   611 fun expand_defs_tac st0 st =
   485 fun expand_defs_tac st0 st =
   612   let val hyps0 = #hyps (rep_thm st0)
   486   let val hyps0 = #hyps (rep_thm st0)
   613       val hyps = #hyps (crep_thm st)
   487       val hyps = #hyps (crep_thm st)
   614       val newhyps = filter_out (member (op aconv) hyps0 o Thm.term_of) hyps
   488       val newhyps = filter_out (member (op aconv) hyps0 o Thm.term_of) hyps
   615       val defs = filter (is_absko o Thm.term_of) newhyps
   489       val defs = filter (is_absko o Thm.term_of) newhyps
   650 (*finish_cnf removes tautologies and functional reflexivity axioms, but by calling Thm.varifyT
   524 (*finish_cnf removes tautologies and functional reflexivity axioms, but by calling Thm.varifyT
   651   it can introduce TVars, which are useless in conjecture clauses.*)
   525   it can introduce TVars, which are useless in conjecture clauses.*)
   652 val no_tvars = null o term_tvars o prop_of;
   526 val no_tvars = null o term_tvars o prop_of;
   653 
   527 
   654 val neg_clausify =
   528 val neg_clausify =
   655   filter no_tvars o Meson.finish_cnf o assume_abstract_list "subgoal" o Meson.make_clauses;
   529   filter no_tvars o Meson.finish_cnf o map combinators o Meson.make_clauses;
   656 
   530 
   657 fun neg_conjecture_clauses st0 n =
   531 fun neg_conjecture_clauses st0 n =
   658   let val st = Seq.hd (neg_skolemize_tac n st0)
   532   let val st = Seq.hd (neg_skolemize_tac n st0)
   659       val (params,_,_) = strip_context (Logic.nth_prem (n, Thm.prop_of st))
   533       val (params,_,_) = strip_context (Logic.nth_prem (n, Thm.prop_of st))
   660   in (neg_clausify (Option.valOf (metahyps_thms n st)), params) end
   534   in (neg_clausify (Option.valOf (metahyps_thms n st)), params) end