TFL/post.sml
changeset 3405 2cccd0e3e9ea
parent 3391 5e45dd3b64e9
child 3459 112cbb8301dc
equal deleted inserted replaced
3404:91a91790899a 3405:2cccd0e3e9ea
     4     Copyright   1997  University of Cambridge
     4     Copyright   1997  University of Cambridge
     5 
     5 
     6 Postprocessing of TFL definitions
     6 Postprocessing of TFL definitions
     7 *)
     7 *)
     8 
     8 
     9 (*-------------------------------------------------------------------------
       
    10 Three postprocessors are applied to the definition:
       
    11     - a wellfoundedness prover (WF_TAC)
       
    12     - a simplifier (tries to eliminate the language of termination expressions)
       
    13     - a termination prover
       
    14 *-------------------------------------------------------------------------*)
       
    15 
       
    16 signature TFL = 
     9 signature TFL = 
    17   sig
    10   sig
    18    structure Prim : TFL_sig
    11    structure Prim : TFL_sig
    19 
    12 
    20    val tgoalw : theory -> thm list -> thm list -> thm list
    13    val tgoalw : theory -> thm list -> thm list -> thm list
    21    val tgoal: theory -> thm list -> thm list
    14    val tgoal: theory -> thm list -> thm list
    22 
    15 
    23    val WF_TAC : thm list -> tactic
    16    val std_postprocessor : simpset -> theory 
    24 
       
    25    val simplifier : thm -> thm
       
    26    val std_postprocessor : theory 
       
    27                            -> {induction:thm, rules:thm, TCs:term list list} 
    17                            -> {induction:thm, rules:thm, TCs:term list list} 
    28                            -> {induction:thm, rules:thm, nested_tcs:thm list}
    18                            -> {induction:thm, rules:thm, nested_tcs:thm list}
    29 
    19 
    30    val define_i : theory -> string -> term -> term list
    20    val define_i : theory -> string -> term -> term list
    31                   -> theory * (thm * Prim.pattern list)
    21                   -> theory * Prim.pattern list
    32 
    22 
    33    val define   : theory -> string -> string -> string list 
    23    val define   : theory -> string -> string -> string list 
    34                   -> theory * Prim.pattern list
    24                   -> theory * Prim.pattern list
    35 
    25 
    36    val simplify_defn : theory * (string * Prim.pattern list)
    26    val simplify_defn : simpset -> theory * (string * Prim.pattern list)
    37                         -> {rules:thm list, induct:thm, tcs:term list}
    27                         -> {rules:thm list, induct:thm, tcs:term list}
    38 
    28 
    39   (*-------------------------------------------------------------------------
    29   (*-------------------------------------------------------------------------
    40        val function : theory -> term -> {theory:theory, eq_ind : thm}
    30        val function : theory -> term -> {theory:theory, eq_ind : thm}
    41        val lazyR_def: theory -> term -> {theory:theory, eqns : thm}
    31        val lazyR_def: theory -> term -> {theory:theory, eqns : thm}
    54 (*---------------------------------------------------------------------------
    44 (*---------------------------------------------------------------------------
    55  * Extract termination goals so that they can be put it into a goalstack, or 
    45  * Extract termination goals so that they can be put it into a goalstack, or 
    56  * have a tactic directly applied to them.
    46  * have a tactic directly applied to them.
    57  *--------------------------------------------------------------------------*)
    47  *--------------------------------------------------------------------------*)
    58 fun termination_goals rules = 
    48 fun termination_goals rules = 
    59     map (Logic.freeze_vars o HOLogic.dest_Trueprop)
    49     map (#1 o Type.freeze_thaw o HOLogic.dest_Trueprop)
    60       (foldr (fn (th,A) => union_term (prems_of th, A)) (rules, []));
    50       (foldr (fn (th,A) => union_term (prems_of th, A)) (rules, []));
    61 
    51 
    62  (*---------------------------------------------------------------------------
    52 (*---------------------------------------------------------------------------
    63   * Finds the termination conditions in (highly massaged) definition and 
    53  * Finds the termination conditions in (highly massaged) definition and 
    64   * puts them into a goalstack.
    54  * puts them into a goalstack.
    65   *--------------------------------------------------------------------------*)
    55  *--------------------------------------------------------------------------*)
    66  fun tgoalw thy defs rules = 
    56 fun tgoalw thy defs rules = 
    67     let val L = termination_goals rules
    57    let val L = termination_goals rules
    68         open USyntax
    58        open USyntax
    69         val g = cterm_of (sign_of thy) (HOLogic.mk_Trueprop(list_mk_conj L))
    59        val g = cterm_of (sign_of thy) (HOLogic.mk_Trueprop(list_mk_conj L))
    70     in goalw_cterm defs g
    60    in goalw_cterm defs g
    71     end;
    61    end;
    72 
    62 
    73  fun tgoal thy = tgoalw thy [];
    63 fun tgoal thy = tgoalw thy [];
    74 
    64 
    75  (*---------------------------------------------------------------------------
    65 (*---------------------------------------------------------------------------
    76   * Simple wellfoundedness prover.
    66 * Three postprocessors are applied to the definition.  It
    77   *--------------------------------------------------------------------------*)
    67 * attempts to prove wellfoundedness of the given relation, simplifies the
    78  fun WF_TAC thms = REPEAT(FIRST1(map rtac thms))
    68 * non-proved termination conditions, and finally attempts to prove the 
    79  val WFtac = WF_TAC[wf_measure, wf_inv_image, wf_lex_prod, wf_less_than, 
    69 * simplified termination conditions.
    80                     wf_trancl];
    70 *--------------------------------------------------------------------------*)
    81 
    71 fun std_postprocessor ss =
    82  val terminator = simp_tac(!simpset addsimps [less_Suc_eq]) 1
    72   Prim.postprocess
    83                   THEN TRY(best_tac
    73    {WFtac      = REPEAT (ares_tac [wf_measure, wf_inv_image, wf_lex_prod, 
    84                            (!claset addSDs [not0_implies_Suc]
    74 				   wf_less_than, wf_trancl] 1),
    85                                     addss (!simpset)) 1);
    75     terminator = asm_simp_tac ss 1
    86 
    76 		 THEN TRY(best_tac
    87  val simpls = [less_eq RS eq_reflection,
    77 			  (!claset addSDs [not0_implies_Suc] addss ss) 1),
    88                lex_prod_def, measure_def, inv_image_def];
    78     simplifier = Rules.simpl_conv ss []};
    89 
    79 
    90  (*---------------------------------------------------------------------------
    80 fun tflcongs thy = Prim.Context.read() @ (#case_congs(Thry.extract_info thy));
    91   * Does some standard things with the termination conditions of a definition:
       
    92   * attempts to prove wellfoundedness of the given relation; simplifies the
       
    93   * non-proven termination conditions; and finally attempts to prove the 
       
    94   * simplified termination conditions.
       
    95   *--------------------------------------------------------------------------*)
       
    96  val std_postprocessor = Prim.postprocess{WFtac = WFtac,
       
    97                                     terminator = terminator, 
       
    98                                     simplifier = Rules.simpl_conv simpls};
       
    99 
       
   100  val simplifier = rewrite_rule (simpls @ #simps(rep_ss (!simpset)) @ 
       
   101                                 [pred_list_def]);
       
   102 
       
   103  fun tflcongs thy = Prim.Context.read() @ (#case_congs(Thry.extract_info thy));
       
   104 
    81 
   105 
    82 
   106 val concl = #2 o Rules.dest_thm;
    83 val concl = #2 o Rules.dest_thm;
   107 
    84 
   108 (*---------------------------------------------------------------------------
    85 (*---------------------------------------------------------------------------
   109  * Defining a function with an associated termination relation. 
    86  * Defining a function with an associated termination relation. 
   110  *---------------------------------------------------------------------------*)
    87  *---------------------------------------------------------------------------*)
   111 fun define_i thy fid R eqs = 
    88 fun define_i thy fid R eqs = 
   112   let val dummy = require_thy thy "WF_Rel" "recursive function definitions"
    89   let val dummy = require_thy thy "WF_Rel" "recursive function definitions"
   113       val {functional,pats} = Prim.mk_functional thy eqs
    90       val {functional,pats} = Prim.mk_functional thy eqs
   114       val (thm,thry) = Prim.wfrec_definition0 thy fid R functional
    91   in (Prim.wfrec_definition0 thy fid R functional, pats)
   115   in (thry,(thm,pats))
       
   116   end;
    92   end;
   117 
    93 
   118 (*lcp's version: takes strings; doesn't return "thm" 
    94 (*lcp's version: takes strings; doesn't return "thm" 
   119         (whose signature is a draft and therefore useless) *)
    95         (whose signature is a draft and therefore useless) *)
   120 fun define thy fid R eqs = 
    96 fun define thy fid R eqs = 
   121   let fun read thy = readtm (sign_of thy) (TVar(("DUMMY",0),[])) 
    97   let fun read thy = readtm (sign_of thy) (TVar(("DUMMY",0),[])) 
   122       val (thy',(_,pats)) =
    98   in  define_i thy fid (read thy R) (map (read thy) eqs)  end
   123              define_i thy fid (read thy R) (map (read thy) eqs)
       
   124   in  (thy',pats)  end
       
   125   handle Utils.ERR {mesg,...} => error mesg;
    99   handle Utils.ERR {mesg,...} => error mesg;
   126 
   100 
   127 (*---------------------------------------------------------------------------
   101 (*---------------------------------------------------------------------------
   128  * Postprocess a definition made by "define". This is a separate stage of 
   102  * Postprocess a definition made by "define". This is a separate stage of 
   129  * processing from the definition stage.
   103  * processing from the definition stage.
   145 val P_imp_P_eq_True = P_imp_P_iff_True RS eq_reflection;
   119 val P_imp_P_eq_True = P_imp_P_iff_True RS eq_reflection;
   146 fun mk_meta_eq r = case concl_of r of
   120 fun mk_meta_eq r = case concl_of r of
   147      Const("==",_)$_$_ => r
   121      Const("==",_)$_$_ => r
   148   |   _$(Const("op =",_)$_$_) => r RS eq_reflection
   122   |   _$(Const("op =",_)$_$_) => r RS eq_reflection
   149   |   _ => r RS P_imp_P_eq_True
   123   |   _ => r RS P_imp_P_eq_True
       
   124 
       
   125 (*Is this the best way to invoke the simplifier??*)
   150 fun rewrite L = rewrite_rule (map mk_meta_eq (filter(not o id_thm) L))
   126 fun rewrite L = rewrite_rule (map mk_meta_eq (filter(not o id_thm) L))
   151 fun reducer thl = rewrite (map standard thl @ #simps(rep_ss (!simpset)))
       
   152 
   127 
   153 fun join_assums th = 
   128 fun join_assums th = 
   154   let val {sign,...} = rep_thm th
   129   let val {sign,...} = rep_thm th
   155       val tych = cterm_of sign
   130       val tych = cterm_of sign
   156       val {lhs,rhs} = S.dest_eq(#2 (S.strip_forall (concl th)))
   131       val {lhs,rhs} = S.dest_eq(#2 (S.strip_forall (concl th)))
   162       (R.DISCH_ALL 
   137       (R.DISCH_ALL 
   163          (rewrite (map (R.ASSUME o tych) cntxt) (R.SPEC_ALL th)))
   138          (rewrite (map (R.ASSUME o tych) cntxt) (R.SPEC_ALL th)))
   164   end
   139   end
   165   val gen_all = S.gen_all
   140   val gen_all = S.gen_all
   166 in
   141 in
   167 (*---------------------------------------------------------------------------
   142 fun proof_stage ss theory {f, R, rules, full_pats_TCs, TCs} =
   168  * The "reducer" argument is 
       
   169  *  (fn thl => rewrite (map standard thl @ #simps(rep_ss (!simpset)))); 
       
   170  *---------------------------------------------------------------------------*)
       
   171 fun proof_stage theory reducer {f, R, rules, full_pats_TCs, TCs} =
       
   172   let val dummy = prs "Proving induction theorem..  "
   143   let val dummy = prs "Proving induction theorem..  "
   173       val ind = Prim.mk_induction theory f R full_pats_TCs
   144       val ind = Prim.mk_induction theory f R full_pats_TCs
   174       val dummy = writeln "Proved induction theorem."
   145       val dummy = prs "Proved induction theorem.\nPostprocessing..  "
   175       val pp = std_postprocessor theory
   146       val {rules, induction, nested_tcs} = 
   176       val dummy = prs "Postprocessing..  "
   147 	  std_postprocessor ss theory {rules=rules, induction=ind, TCs=TCs}
   177       val {rules,induction,nested_tcs} = pp{rules=rules,induction=ind,TCs=TCs}
       
   178   in
   148   in
   179   case nested_tcs
   149   case nested_tcs
   180   of [] => (writeln "Postprocessing done.";
   150   of [] => (writeln "Postprocessing done.";
   181             {induction=induction, rules=rules,tcs=[]})
   151             {induction=induction, rules=rules,tcs=[]})
   182   | L  => let val dummy = prs "Simplifying nested TCs..  "
   152   | L  => let val dummy = prs "Simplifying nested TCs..  "
   184                U.itlist (fn th => fn (So,Si,St) =>
   154                U.itlist (fn th => fn (So,Si,St) =>
   185                      if (id_thm th) then (So, Si, th::St) else
   155                      if (id_thm th) then (So, Si, th::St) else
   186                      if (solved th) then (th::So, Si, St) 
   156                      if (solved th) then (th::So, Si, St) 
   187                      else (So, th::Si, St)) nested_tcs ([],[],[])
   157                      else (So, th::Si, St)) nested_tcs ([],[],[])
   188               val simplified' = map join_assums simplified
   158               val simplified' = map join_assums simplified
   189               val induction' = reducer (solved@simplified') induction
   159               val rewr = rewrite (solved @ simplified' @ #simps(rep_ss ss))
   190               val rules' = reducer (solved@simplified') rules
   160               val induction' = rewr induction
       
   161               and rules'     = rewr rules
   191               val dummy = writeln "Postprocessing done."
   162               val dummy = writeln "Postprocessing done."
   192           in
   163           in
   193           {induction = induction',
   164           {induction = induction',
   194                rules = rules',
   165                rules = rules',
   195                  tcs = map (gen_all o S.rhs o #2 o S.strip_forall o concl)
   166                  tcs = map (gen_all o S.rhs o #2 o S.strip_forall o concl)
   210 				  ORELSE' etac conjE));
   181 				  ORELSE' etac conjE));
   211 
   182 
   212 (*Strip off the outer !P*)
   183 (*Strip off the outer !P*)
   213 val spec'= read_instantiate [("x","P::?'b=>bool")] spec;
   184 val spec'= read_instantiate [("x","P::?'b=>bool")] spec;
   214 
   185 
   215 
   186 val wf_rel_defs = [lex_prod_def, measure_def, inv_image_def];
   216 fun simplify_defn (thy,(id,pats)) =
   187 
       
   188 fun simplify_defn ss (thy,(id,pats)) =
   217    let val dummy = deny (id  mem  map ! (stamps_of_thy thy))
   189    let val dummy = deny (id  mem  map ! (stamps_of_thy thy))
   218                         ("Recursive definition " ^ id ^ 
   190                         ("Recursive definition " ^ id ^ 
   219                          " would clash with the theory of the same name!")
   191                          " would clash with the theory of the same name!")
   220        val def = freezeT(get_def thy id  RS  meta_eq_to_obj_eq)
   192        val def =  freezeT(get_def thy id)   RS   meta_eq_to_obj_eq
       
   193        val ss' = ss addsimps ((less_Suc_eq RS iffD2) :: wf_rel_defs)
   221        val {theory,rules,TCs,full_pats_TCs,patterns} = 
   194        val {theory,rules,TCs,full_pats_TCs,patterns} = 
   222                 Prim.post_definition (thy,(def,pats))
   195                 Prim.post_definition ss' (thy,(def,pats))
   223        val {lhs=f,rhs} = S.dest_eq(concl def)
   196        val {lhs=f,rhs} = S.dest_eq(concl def)
   224        val (_,[R,_]) = S.strip_comb rhs
   197        val (_,[R,_]) = S.strip_comb rhs
   225        val {induction, rules, tcs} = 
   198        val {induction, rules, tcs} = 
   226              proof_stage theory reducer
   199              proof_stage ss' theory 
   227                {f = f, R = R, rules = rules,
   200                {f = f, R = R, rules = rules,
   228                 full_pats_TCs = full_pats_TCs,
   201                 full_pats_TCs = full_pats_TCs,
   229                 TCs = TCs}
   202                 TCs = TCs}
   230        val rules' = map (standard o normalize_thm [RSmp]) (R.CONJUNCTS rules)
   203        val rules' = map (standard o normalize_thm [RSmp]) (R.CONJUNCTS rules)
   231    in  {induct = meta_outer
   204    in  {induct = meta_outer
   233         rules = rules', 
   206         rules = rules', 
   234         tcs = (termination_goals rules') @ tcs}
   207         tcs = (termination_goals rules') @ tcs}
   235    end
   208    end
   236   handle Utils.ERR {mesg,func,module} => 
   209   handle Utils.ERR {mesg,func,module} => 
   237                error (mesg ^ 
   210                error (mesg ^ 
   238 		      "\n    (In TFL function " ^ module ^ "." ^ func ^ ")")
   211 		      "\n    (In TFL function " ^ module ^ "." ^ func ^ ")");
   239        |  e => print_exn e;
       
   240 end;
   212 end;
   241 
   213 
   242 (*---------------------------------------------------------------------------
   214 (*---------------------------------------------------------------------------
   243  *
   215  *
   244  *     Definitions with synthesized termination relation temporarily
   216  *     Definitions with synthesized termination relation temporarily
   258      val induction = Prim.mk_induction theory f R full_pats_TCs
   230      val induction = Prim.mk_induction theory f R full_pats_TCs
   259      val dummy = prs "Induction theorem proved.\n"
   231      val dummy = prs "Induction theorem proved.\n"
   260  in {theory = theory, 
   232  in {theory = theory, 
   261      eq_ind = standard (induction RS (rules RS conjI))}
   233      eq_ind = standard (induction RS (rules RS conjI))}
   262  end
   234  end
   263  handle    e              => print_exn e
       
   264 end;
   235 end;
   265 
   236 
   266 
   237 
   267 fun lazyR_def theory eqs = 
   238 fun lazyR_def theory eqs = 
   268    let val {rules,theory, ...} = Prim.lazyR_def theory eqs
   239    let val {rules,theory, ...} = Prim.lazyR_def theory eqs