TFL/post.ML
author dixon
Wed, 02 Mar 2005 10:33:10 +0100
changeset 15560 c862d556fb18
parent 15531 08c8dad8e399
child 15570 8d8c70b41bab
permissions -rw-r--r--
lucas - fixed bug with name capture variables bound outside redex could (previously)conflict with scheme variables that occur in the conditions of an equation, and which were renamed to avoid conflict with another instantiation. This has now been fixed.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     1
(*  Title:      TFL/post.ML
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     2
    ID:         $Id$
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     3
    Author:     Konrad Slind, Cambridge University Computer Laboratory
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     4
    Copyright   1997  University of Cambridge
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     5
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     6
Second part of main module (postprocessing of TFL definitions).
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     7
*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     8
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
     9
signature TFL =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    10
sig
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    11
  val trace: bool ref
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    12
  val quiet_mode: bool ref
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    13
  val message: string -> unit
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    14
  val tgoalw: theory -> thm list -> thm list -> thm list
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    15
  val tgoal: theory -> thm list -> thm list
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
    16
  val define_i: bool -> theory -> claset -> simpset -> thm list -> thm list -> xstring ->
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    17
    term -> term list -> theory * {rules: (thm * int) list, induct: thm, tcs: term list}
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
    18
  val define: bool -> theory -> claset -> simpset -> thm list -> thm list -> xstring ->
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    19
    string -> string list -> theory * {rules: (thm * int) list, induct: thm, tcs: term list}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    20
  val defer_i: theory -> thm list -> xstring -> term list -> theory * thm
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    21
  val defer: theory -> thm list -> xstring -> string list -> theory * thm
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    22
end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    23
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    24
structure Tfl: TFL =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    25
struct
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    26
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    27
structure S = USyntax
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    28
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    29
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    30
(* messages *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    31
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    32
val trace = Prim.trace
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    33
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    34
val quiet_mode = ref false;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    35
fun message s = if ! quiet_mode then () else writeln s;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    36
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    37
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    38
(* misc *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    39
12341
08afd1003151 HOLogic.read_cterm;
wenzelm
parents: 11771
diff changeset
    40
val read_term = Thm.term_of oo (HOLogic.read_cterm o Theory.sign_of);
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    41
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    42
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    43
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    44
 * Extract termination goals so that they can be put it into a goalstack, or
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    45
 * have a tactic directly applied to them.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    46
 *--------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    47
fun termination_goals rules =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    48
    map (#1 o Type.freeze_thaw o HOLogic.dest_Trueprop)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    49
      (foldr (fn (th,A) => union_term (prems_of th, A)) (rules, []));
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    50
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    51
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    52
 * Finds the termination conditions in (highly massaged) definition and
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    53
 * puts them into a goalstack.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    54
 *--------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    55
fun tgoalw thy defs rules =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    56
  case termination_goals rules of
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    57
      [] => error "tgoalw: no termination conditions to prove"
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    58
    | L  => goalw_cterm defs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    59
              (Thm.cterm_of (Theory.sign_of thy)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    60
                        (HOLogic.mk_Trueprop(USyntax.list_mk_conj L)));
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    61
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    62
fun tgoal thy = tgoalw thy [];
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    63
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    64
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    65
 * Three postprocessors are applied to the definition.  It
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    66
 * attempts to prove wellfoundedness of the given relation, simplifies the
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    67
 * non-proved termination conditions, and finally attempts to prove the
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    68
 * simplified termination conditions.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    69
 *--------------------------------------------------------------------------*)
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
    70
fun std_postprocessor strict cs ss wfs =
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
    71
  Prim.postprocess strict
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    72
   {wf_tac     = REPEAT (ares_tac wfs 1),
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    73
    terminator = asm_simp_tac ss 1
13501
79242cccaddc arith_tac should not produce counter example
nipkow
parents: 12488
diff changeset
    74
                 THEN TRY (silent_arith_tac 1 ORELSE
12488
83acab8042ad Terminator now uses arith_tac as well.
nipkow
parents: 12341
diff changeset
    75
                           fast_tac (cs addSDs [not0_implies_Suc] addss ss) 1),
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    76
    simplifier = Rules.simpl_conv ss []};
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    77
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    78
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    79
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    80
val concl = #2 o Rules.dest_thm;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    81
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    82
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    83
 * Postprocess a definition made by "define". This is a separate stage of
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    84
 * processing from the definition stage.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    85
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    86
local
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    87
structure R = Rules
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    88
structure U = Utils
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    89
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    90
(* The rest of these local definitions are for the tricky nested case *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    91
val solved = not o can S.dest_eq o #2 o S.strip_forall o concl
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    92
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    93
fun id_thm th =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    94
   let val {lhs,rhs} = S.dest_eq (#2 (S.strip_forall (#2 (R.dest_thm th))));
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    95
   in lhs aconv rhs end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    96
   handle U.ERR _ => false;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    97
   
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    98
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    99
fun prover s = prove_goal HOL.thy s (fn _ => [fast_tac HOL_cs 1]);
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   100
val P_imp_P_iff_True = prover "P --> (P= True)" RS mp;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   101
val P_imp_P_eq_True = P_imp_P_iff_True RS eq_reflection;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   102
fun mk_meta_eq r = case concl_of r of
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   103
     Const("==",_)$_$_ => r
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   104
  |   _ $(Const("op =",_)$_$_) => r RS eq_reflection
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   105
  |   _ => r RS P_imp_P_eq_True
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   106
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   107
(*Is this the best way to invoke the simplifier??*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   108
fun rewrite L = rewrite_rule (map mk_meta_eq (filter(not o id_thm) L))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   109
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   110
fun join_assums th =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   111
  let val {sign,...} = rep_thm th
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   112
      val tych = cterm_of sign
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   113
      val {lhs,rhs} = S.dest_eq(#2 (S.strip_forall (concl th)))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   114
      val cntxtl = (#1 o S.strip_imp) lhs  (* cntxtl should = cntxtr *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   115
      val cntxtr = (#1 o S.strip_imp) rhs  (* but union is solider *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   116
      val cntxt = gen_union (op aconv) (cntxtl, cntxtr)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   117
  in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   118
    R.GEN_ALL
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   119
      (R.DISCH_ALL
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   120
         (rewrite (map (R.ASSUME o tych) cntxt) (R.SPEC_ALL th)))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   121
  end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   122
  val gen_all = S.gen_all
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   123
in
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   124
fun proof_stage strict cs ss wfs theory {f, R, rules, full_pats_TCs, TCs} =
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   125
  let
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   126
    val _ = message "Proving induction theorem ..."
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   127
    val ind = Prim.mk_induction theory {fconst=f, R=R, SV=[], pat_TCs_list=full_pats_TCs}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   128
    val _ = message "Postprocessing ...";
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   129
    val {rules, induction, nested_tcs} =
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   130
      std_postprocessor strict cs ss wfs theory {rules=rules, induction=ind, TCs=TCs}
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   131
  in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   132
  case nested_tcs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   133
  of [] => {induction=induction, rules=rules,tcs=[]}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   134
  | L  => let val dummy = message "Simplifying nested TCs ..."
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   135
              val (solved,simplified,stubborn) =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   136
               U.itlist (fn th => fn (So,Si,St) =>
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   137
                     if (id_thm th) then (So, Si, th::St) else
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   138
                     if (solved th) then (th::So, Si, St)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   139
                     else (So, th::Si, St)) nested_tcs ([],[],[])
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   140
              val simplified' = map join_assums simplified
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   141
              val dummy = (Prim.trace_thms "solved =" solved;
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   142
                           Prim.trace_thms "simplified' =" simplified')
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   143
              val rewr = full_simplify (ss addsimps (solved @ simplified'));
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   144
              val dummy = Prim.trace_thms "Simplifying the induction rule..."
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   145
                                          [induction]
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   146
              val induction' = rewr induction
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   147
              val dummy = Prim.trace_thms "Simplifying the recursion rules..."
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   148
                                          [rules]
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   149
              val rules'     = rewr rules
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   150
              val _ = message "... Postprocessing finished";
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   151
          in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   152
          {induction = induction',
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   153
               rules = rules',
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   154
                 tcs = map (gen_all o S.rhs o #2 o S.strip_forall o concl)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   155
                           (simplified@stubborn)}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   156
          end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   157
  end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   158
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   159
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   160
(*lcp: curry the predicate of the induction rule*)
11038
wenzelm
parents: 10769
diff changeset
   161
fun curry_rule rl =
wenzelm
parents: 10769
diff changeset
   162
  SplitRule.split_rule_var (Term.head_of (HOLogic.dest_Trueprop (concl_of rl)), rl);
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   163
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   164
(*lcp: put a theorem into Isabelle form, using meta-level connectives*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   165
val meta_outer =
11038
wenzelm
parents: 10769
diff changeset
   166
  curry_rule o standard o
wenzelm
parents: 10769
diff changeset
   167
  rule_by_tactic (REPEAT (FIRSTGOAL (resolve_tac [allI, impI, conjI] ORELSE' etac conjE)));
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   168
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   169
(*Strip off the outer !P*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   170
val spec'= read_instantiate [("x","P::?'b=>bool")] spec;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   171
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   172
fun tracing true _ = ()
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   173
  | tracing false msg = writeln msg;
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   174
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   175
fun simplify_defn strict thy cs ss congs wfs id pats def0 =
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   176
   let val def = freezeT def0 RS meta_eq_to_obj_eq
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   177
       val {theory,rules,rows,TCs,full_pats_TCs} =
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   178
           Prim.post_definition congs (thy, (def,pats))
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   179
       val {lhs=f,rhs} = S.dest_eq (concl def)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   180
       val (_,[R,_]) = S.strip_comb rhs
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   181
       val dummy = Prim.trace_thms "congs =" congs
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   182
       (*the next step has caused simplifier looping in some cases*)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   183
       val {induction, rules, tcs} =
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   184
             proof_stage strict cs ss wfs theory
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   185
               {f = f, R = R, rules = rules,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   186
                full_pats_TCs = full_pats_TCs,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   187
                TCs = TCs}
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   188
       val rules' = map (standard o ObjectLogic.rulify_no_asm)
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   189
                        (R.CONJUNCTS rules)
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   190
         in  {induct = meta_outer (ObjectLogic.rulify_no_asm (induction RS spec')),
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   191
        rules = ListPair.zip(rules', rows),
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   192
        tcs = (termination_goals rules') @ tcs}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   193
   end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   194
  handle U.ERR {mesg,func,module} =>
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   195
               error (mesg ^
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   196
                      "\n    (In TFL function " ^ module ^ "." ^ func ^ ")");
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   197
15150
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   198
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   199
(* Derive the initial equations from the case-split rules to meet the
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   200
users specification of the recursive function. 
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   201
 Note: We don't do this if the wf conditions fail to be solved, as each
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   202
case may have a different wf condition. We could group the conditions
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   203
together and say that they must be true to solve the general case,
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   204
but that would hide from the user which sub-case they were related
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   205
to. Probably this is not important, and it would work fine, but, for now, I
15171
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   206
prefer leaving more fine-grain control to the user. 
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   207
-- Lucas Dixon, Aug 2004 *)
15150
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   208
local
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   209
  fun get_related_thms i = 
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 15171
diff changeset
   210
      mapfilter ((fn (r,x) => if x = i then SOME r else NONE));
15150
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   211
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   212
  fun solve_eq (th, [], i) = 
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   213
      raise ERROR_MESSAGE "derive_init_eqs: missing rules"
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   214
    | solve_eq (th, [a], i) = [(a, i)]
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   215
    | solve_eq (th, splitths as (_ :: _), i) = 
15171
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   216
      (writeln "Proving unsplit equation...";
15150
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   217
      [((standard o ObjectLogic.rulify_no_asm)
15171
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   218
          (CaseSplit.splitto splitths th), i)])
15150
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   219
      (* if there's an error, pretend nothing happened with this definition 
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   220
         We should probably print something out so that the user knows...? *)
15171
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   221
      handle ERROR_MESSAGE s => 
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   222
             (writeln ("WARNING:post.ML:solve_eq: " ^ s); map (fn x => (x,i)) splitths); 
15150
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   223
in
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   224
fun derive_init_eqs sgn rules eqs = 
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   225
    let 
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   226
      val eqths = map (Thm.trivial o (Thm.cterm_of sgn) o HOLogic.mk_Trueprop) 
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   227
                      eqs
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   228
      fun countlist l = 
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   229
          (rev o snd o (foldl (fn ((i,L), e) => (i + 1,(e,i) :: L)))) ((0,[]), l)
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   230
    in
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   231
      flat (map (fn (e,i) => solve_eq (e, (get_related_thms i rules), i))
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   232
                (countlist eqths))
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   233
    end;
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   234
end;
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   235
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   236
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   237
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   238
 * Defining a function with an associated termination relation.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   239
 *---------------------------------------------------------------------------*)
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   240
fun define_i strict thy cs ss congs wfs fid R eqs =
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   241
  let val {functional,pats} = Prim.mk_functional thy eqs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   242
      val (thy, def) = Prim.wfrec_definition0 thy (Sign.base_name fid) R functional
15171
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   243
      val {induct, rules, tcs} = 
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   244
          simplify_defn strict thy cs ss congs wfs fid pats def
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   245
      val rules' = 
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   246
          if strict then derive_init_eqs (Theory.sign_of thy) rules eqs
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   247
          else rules
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   248
  in (thy, {rules = rules', induct = induct, tcs = tcs}) end;
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   249
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   250
fun define strict thy cs ss congs wfs fid R seqs =
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   251
  define_i strict thy cs ss congs wfs fid (read_term thy R) (map (read_term thy) seqs)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   252
    handle U.ERR {mesg,...} => error mesg;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   253
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   254
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   255
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   256
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   257
 *     Definitions with synthesized termination relation
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   258
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   259
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   260
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   261
fun func_of_cond_eqn tm =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   262
  #1 (S.strip_comb (#lhs (S.dest_eq (#2 (S.strip_forall (#2 (S.strip_imp tm)))))));
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   263
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   264
fun defer_i thy congs fid eqs =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   265
 let val {rules,R,theory,full_pats_TCs,SV,...} =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   266
             Prim.lazyR_def thy (Sign.base_name fid) congs eqs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   267
     val f = func_of_cond_eqn (concl (R.CONJUNCT1 rules handle U.ERR _ => rules));
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   268
     val dummy = message "Proving induction theorem ...";
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   269
     val induction = Prim.mk_induction theory
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   270
                        {fconst=f, R=R, SV=SV, pat_TCs_list=full_pats_TCs}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   271
 in (theory,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   272
     (*return the conjoined induction rule and recursion equations,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   273
       with assumptions remaining to discharge*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   274
     standard (induction RS (rules RS conjI)))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   275
 end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   276
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   277
fun defer thy congs fid seqs =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   278
  defer_i thy congs fid (map (read_term thy) seqs)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   279
    handle U.ERR {mesg,...} => error mesg;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   280
end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   281
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   282
end;