TFL/post.ML
author mengj
Fri, 28 Oct 2005 02:28:20 +0200
changeset 18002 35ec4681d38f
parent 17959 8db36a108213
child 18139 b15981aedb7b
permissions -rw-r--r--
Added several new functions that are used to prove HOL goals. Added new methods "vampireH" and "eproverH" that can prove both FOL and HOL goals. The old "vampire" and "eprover" methods are renamed to "vampireF" and "eproverF"; they can only prove FOL goals.
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
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    40
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    41
 * Extract termination goals so that they can be put it into a goalstack, or
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    42
 * have a tactic directly applied to them.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    43
 *--------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    44
fun termination_goals rules =
16287
7a03b4b4df67 Type.freeze;
wenzelm
parents: 15574
diff changeset
    45
    map (Type.freeze o HOLogic.dest_Trueprop)
15574
b1d1b5bfc464 Removed practically all references to Library.foldr.
skalberg
parents: 15570
diff changeset
    46
      (foldr (fn (th,A) => union_term (prems_of th, A)) [] rules);
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    47
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    48
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    49
 * Finds the termination conditions in (highly massaged) definition and
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    50
 * puts them into a goalstack.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    51
 *--------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    52
fun tgoalw thy defs rules =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    53
  case termination_goals rules of
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    54
      [] => error "tgoalw: no termination conditions to prove"
17959
8db36a108213 OldGoals;
wenzelm
parents: 17615
diff changeset
    55
    | L  => OldGoals.goalw_cterm defs
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    56
              (Thm.cterm_of (Theory.sign_of thy)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    57
                        (HOLogic.mk_Trueprop(USyntax.list_mk_conj L)));
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    58
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    59
fun tgoal thy = tgoalw thy [];
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    60
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    61
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    62
 * Three postprocessors are applied to the definition.  It
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    63
 * attempts to prove wellfoundedness of the given relation, simplifies the
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    64
 * non-proved termination conditions, and finally attempts to prove the
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    65
 * simplified termination conditions.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    66
 *--------------------------------------------------------------------------*)
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
    67
fun std_postprocessor strict cs ss wfs =
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
    68
  Prim.postprocess strict
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    69
   {wf_tac     = REPEAT (ares_tac wfs 1),
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    70
    terminator = asm_simp_tac ss 1
13501
79242cccaddc arith_tac should not produce counter example
nipkow
parents: 12488
diff changeset
    71
                 THEN TRY (silent_arith_tac 1 ORELSE
12488
83acab8042ad Terminator now uses arith_tac as well.
nipkow
parents: 12341
diff changeset
    72
                           fast_tac (cs addSDs [not0_implies_Suc] addss ss) 1),
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    73
    simplifier = Rules.simpl_conv ss []};
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    74
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    75
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    76
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    77
val concl = #2 o Rules.dest_thm;
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
 * Postprocess a definition made by "define". This is a separate stage of
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    81
 * processing from the definition stage.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    82
 *---------------------------------------------------------------------------*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    83
local
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    84
structure R = Rules
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    85
structure U = Utils
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    86
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    87
(* The rest of these local definitions are for the tricky nested case *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    88
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
    89
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    90
fun id_thm th =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    91
   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
    92
   in lhs aconv rhs end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    93
   handle U.ERR _ => false;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    94
   
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    95
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    96
fun prover s = prove_goal HOL.thy s (fn _ => [fast_tac HOL_cs 1]);
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    97
val P_imp_P_iff_True = prover "P --> (P= True)" RS mp;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    98
val P_imp_P_eq_True = P_imp_P_iff_True RS eq_reflection;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
    99
fun mk_meta_eq r = case concl_of r of
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   100
     Const("==",_)$_$_ => r
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   101
  |   _ $(Const("op =",_)$_$_) => r RS eq_reflection
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   102
  |   _ => r RS P_imp_P_eq_True
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   103
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   104
(*Is this the best way to invoke the simplifier??*)
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   105
fun rewrite L = rewrite_rule (map mk_meta_eq (List.filter(not o id_thm) L))
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   106
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   107
fun join_assums th =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   108
  let val {sign,...} = rep_thm th
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   109
      val tych = cterm_of sign
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   110
      val {lhs,rhs} = S.dest_eq(#2 (S.strip_forall (concl th)))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   111
      val cntxtl = (#1 o S.strip_imp) lhs  (* cntxtl should = cntxtr *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   112
      val cntxtr = (#1 o S.strip_imp) rhs  (* but union is solider *)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   113
      val cntxt = gen_union (op aconv) (cntxtl, cntxtr)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   114
  in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   115
    R.GEN_ALL
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   116
      (R.DISCH_ALL
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   117
         (rewrite (map (R.ASSUME o tych) cntxt) (R.SPEC_ALL th)))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   118
  end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   119
  val gen_all = S.gen_all
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   120
in
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   121
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
   122
  let
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   123
    val _ = message "Proving induction theorem ..."
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   124
    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
   125
    val _ = message "Postprocessing ...";
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   126
    val {rules, induction, nested_tcs} =
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   127
      std_postprocessor strict cs ss wfs theory {rules=rules, induction=ind, TCs=TCs}
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   128
  in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   129
  case nested_tcs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   130
  of [] => {induction=induction, rules=rules,tcs=[]}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   131
  | L  => let val dummy = message "Simplifying nested TCs ..."
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   132
              val (solved,simplified,stubborn) =
16852
b950180e243d replaced itlist by fold_rev;
wenzelm
parents: 16287
diff changeset
   133
               fold_rev (fn th => fn (So,Si,St) =>
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   134
                     if (id_thm th) then (So, Si, th::St) else
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   135
                     if (solved th) then (th::So, Si, St)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   136
                     else (So, th::Si, St)) nested_tcs ([],[],[])
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   137
              val simplified' = map join_assums simplified
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   138
              val dummy = (Prim.trace_thms "solved =" solved;
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   139
                           Prim.trace_thms "simplified' =" simplified')
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   140
              val rewr = full_simplify (ss addsimps (solved @ simplified'));
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   141
              val dummy = Prim.trace_thms "Simplifying the induction rule..."
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   142
                                          [induction]
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   143
              val induction' = rewr induction
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   144
              val dummy = Prim.trace_thms "Simplifying the recursion rules..."
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   145
                                          [rules]
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   146
              val rules'     = rewr rules
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   147
              val _ = message "... Postprocessing finished";
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   148
          in
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   149
          {induction = induction',
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   150
               rules = rules',
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   151
                 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
   152
                           (simplified@stubborn)}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   153
          end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   154
  end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   155
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   156
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   157
(*lcp: curry the predicate of the induction rule*)
11038
wenzelm
parents: 10769
diff changeset
   158
fun curry_rule rl =
wenzelm
parents: 10769
diff changeset
   159
  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
   160
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   161
(*lcp: put a theorem into Isabelle form, using meta-level connectives*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   162
val meta_outer =
11038
wenzelm
parents: 10769
diff changeset
   163
  curry_rule o standard o
wenzelm
parents: 10769
diff changeset
   164
  rule_by_tactic (REPEAT (FIRSTGOAL (resolve_tac [allI, impI, conjI] ORELSE' etac conjE)));
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   165
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   166
(*Strip off the outer !P*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   167
val spec'= read_instantiate [("x","P::?'b=>bool")] spec;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   168
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   169
fun tracing true _ = ()
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   170
  | tracing false msg = writeln msg;
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   171
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   172
fun simplify_defn strict thy cs ss congs wfs id pats def0 =
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   173
   let val def = freezeT def0 RS meta_eq_to_obj_eq
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   174
       val {theory,rules,rows,TCs,full_pats_TCs} =
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   175
           Prim.post_definition congs (thy, (def,pats))
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   176
       val {lhs=f,rhs} = S.dest_eq (concl def)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   177
       val (_,[R,_]) = S.strip_comb rhs
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   178
       val dummy = Prim.trace_thms "congs =" congs
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   179
       (*the next step has caused simplifier looping in some cases*)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   180
       val {induction, rules, tcs} =
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   181
             proof_stage strict cs ss wfs theory
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   182
               {f = f, R = R, rules = rules,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   183
                full_pats_TCs = full_pats_TCs,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   184
                TCs = TCs}
14240
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   185
       val rules' = map (standard o ObjectLogic.rulify_no_asm)
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   186
                        (R.CONJUNCTS rules)
d3843feb9de7 improved tracing
paulson
parents: 13501
diff changeset
   187
         in  {induct = meta_outer (ObjectLogic.rulify_no_asm (induction RS spec')),
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   188
        rules = ListPair.zip(rules', rows),
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   189
        tcs = (termination_goals rules') @ tcs}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   190
   end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   191
  handle U.ERR {mesg,func,module} =>
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   192
               error (mesg ^
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   193
                      "\n    (In TFL function " ^ module ^ "." ^ func ^ ")");
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   194
15150
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   195
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   196
(* 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
   197
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
   198
 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
   199
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
   200
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
   201
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
   202
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
   203
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
   204
-- Lucas Dixon, Aug 2004 *)
15150
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   205
local
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   206
  fun get_related_thms i = 
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   207
      List.mapPartial ((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
   208
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   209
  fun solve_eq (th, [], i) = 
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   210
      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
   211
    | 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
   212
    | 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
   213
      (writeln "Proving unsplit equation...";
15150
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   214
      [((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
   215
          (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
   216
      (* 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
   217
         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
   218
      handle ERROR_MESSAGE s => 
17615
3c5b158be33c tuned msg;
wenzelm
parents: 16975
diff changeset
   219
             (warning ("recdef (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
   220
in
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   221
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
   222
    let 
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   223
      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
   224
                      eqs
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   225
      fun countlist l = 
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   226
          (rev o snd o (Library.foldl (fn ((i,L), e) => (i + 1,(e,i) :: L)))) ((0,[]), l)
15150
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   227
    in
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   228
      List.concat (map (fn (e,i) => solve_eq (e, (get_related_thms i rules), i))
15150
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   229
                (countlist eqths))
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   230
    end;
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   231
end;
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   232
c7af682b9ee5 fix to eliminate excessive case-splits in the recursion equations, by Luca Dixon
paulson
parents: 14240
diff changeset
   233
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   234
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   235
 * Defining a function with an associated termination relation.
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   236
 *---------------------------------------------------------------------------*)
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   237
fun define_i strict thy cs ss congs wfs fid R eqs =
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   238
  let val {functional,pats} = Prim.mk_functional thy eqs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   239
      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
   240
      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
   241
          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
   242
      val rules' = 
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   243
          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
   244
          else rules
e0cd537c4325 added code to make use of case splitting to prove the specification equations for recursive definitions.
dixon
parents: 15150
diff changeset
   245
  in (thy, {rules = rules', induct = induct, tcs = tcs}) end;
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   246
11632
6fc8de600f58 prove: ``strict'' argument;
wenzelm
parents: 11038
diff changeset
   247
fun define strict thy cs ss congs wfs fid R seqs =
16975
34ed8d5d4f16 Sign.read_term;
wenzelm
parents: 16852
diff changeset
   248
  define_i strict thy cs ss congs wfs fid (Sign.read_term thy R) (map (Sign.read_term thy) seqs)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   249
    handle U.ERR {mesg,...} => error mesg;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   250
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   251
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   252
(*---------------------------------------------------------------------------
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   253
 *
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   254
 *     Definitions with synthesized termination relation
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
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   258
fun func_of_cond_eqn tm =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   259
  #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
   260
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   261
fun defer_i thy congs fid eqs =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   262
 let val {rules,R,theory,full_pats_TCs,SV,...} =
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   263
             Prim.lazyR_def thy (Sign.base_name fid) congs eqs
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   264
     val f = func_of_cond_eqn (concl (R.CONJUNCT1 rules handle U.ERR _ => rules));
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   265
     val dummy = message "Proving induction theorem ...";
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   266
     val induction = Prim.mk_induction theory
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   267
                        {fconst=f, R=R, SV=SV, pat_TCs_list=full_pats_TCs}
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   268
 in (theory,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   269
     (*return the conjoined induction rule and recursion equations,
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   270
       with assumptions remaining to discharge*)
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   271
     standard (induction RS (rules RS conjI)))
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   272
 end
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   273
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   274
fun defer thy congs fid seqs =
16975
34ed8d5d4f16 Sign.read_term;
wenzelm
parents: 16852
diff changeset
   275
  defer_i thy congs fid (map (Sign.read_term thy) seqs)
10769
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   276
    handle U.ERR {mesg,...} => error mesg;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   277
end;
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   278
70b9b0cfe05f renamed .sml files to .ML;
wenzelm
parents:
diff changeset
   279
end;