src/FOL/simpdata.ML
author wenzelm
Tue, 02 Aug 2005 19:47:12 +0200
changeset 17002 fb9261990ffe
parent 16019 0e1405402d53
child 17325 d9d50222808e
permissions -rw-r--r--
simprocs: Simplifier.inherit_bounds;
wenzelm@9889
     1
(*  Title:      FOL/simpdata.ML
clasohm@0
     2
    ID:         $Id$
clasohm@1459
     3
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
lcp@282
     4
    Copyright   1994  University of Cambridge
clasohm@0
     5
wenzelm@9889
     6
Simplification data for FOL.
clasohm@0
     7
*)
clasohm@0
     8
paulson@9300
     9
paulson@5496
    10
(* Elimination of True from asumptions: *)
paulson@5496
    11
wenzelm@12038
    12
bind_thm ("True_implies_equals", prove_goal IFOL.thy
paulson@5496
    13
 "(True ==> PROP P) == PROP P"
paulson@5496
    14
(K [rtac equal_intr_rule 1, atac 2,
paulson@5496
    15
          METAHYPS (fn prems => resolve_tac prems 1) 1,
wenzelm@12038
    16
          rtac TrueI 1]));
paulson@5496
    17
paulson@5496
    18
clasohm@0
    19
(*** Rewrite rules ***)
clasohm@0
    20
wenzelm@10431
    21
fun int_prove_fun s =
wenzelm@10431
    22
 (writeln s;
lcp@282
    23
  prove_goal IFOL.thy s
wenzelm@10431
    24
   (fn prems => [ (cut_facts_tac prems 1),
paulson@2601
    25
                  (IntPr.fast_tac 1) ]));
clasohm@0
    26
wenzelm@12038
    27
bind_thms ("conj_simps", map int_prove_fun
clasohm@1459
    28
 ["P & True <-> P",      "True & P <-> P",
clasohm@0
    29
  "P & False <-> False", "False & P <-> False",
nipkow@2801
    30
  "P & P <-> P", "P & P & Q <-> P & Q",
clasohm@1459
    31
  "P & ~P <-> False",    "~P & P <-> False",
wenzelm@12038
    32
  "(P & Q) & R <-> P & (Q & R)"]);
clasohm@0
    33
wenzelm@12038
    34
bind_thms ("disj_simps", map int_prove_fun
clasohm@1459
    35
 ["P | True <-> True",  "True | P <-> True",
clasohm@1459
    36
  "P | False <-> P",    "False | P <-> P",
nipkow@2801
    37
  "P | P <-> P", "P | P | Q <-> P | Q",
wenzelm@12038
    38
  "(P | Q) | R <-> P | (Q | R)"]);
clasohm@0
    39
wenzelm@12038
    40
bind_thms ("not_simps", map int_prove_fun
lcp@282
    41
 ["~(P|Q)  <-> ~P & ~Q",
wenzelm@12038
    42
  "~ False <-> True",   "~ True <-> False"]);
clasohm@0
    43
wenzelm@12038
    44
bind_thms ("imp_simps", map int_prove_fun
clasohm@1459
    45
 ["(P --> False) <-> ~P",       "(P --> True) <-> True",
wenzelm@10431
    46
  "(False --> P) <-> True",     "(True --> P) <-> P",
wenzelm@12038
    47
  "(P --> P) <-> True",         "(P --> ~P) <-> ~P"]);
clasohm@0
    48
wenzelm@12038
    49
bind_thms ("iff_simps", map int_prove_fun
clasohm@1459
    50
 ["(True <-> P) <-> P",         "(P <-> True) <-> P",
clasohm@0
    51
  "(P <-> P) <-> True",
wenzelm@12038
    52
  "(False <-> P) <-> ~P",       "(P <-> False) <-> ~P"]);
clasohm@0
    53
paulson@4349
    54
(*The x=t versions are needed for the simplification procedures*)
wenzelm@12038
    55
bind_thms ("quant_simps", map int_prove_fun
wenzelm@10431
    56
 ["(ALL x. P) <-> P",
paulson@4349
    57
  "(ALL x. x=t --> P(x)) <-> P(t)",
paulson@4349
    58
  "(ALL x. t=x --> P(x)) <-> P(t)",
paulson@4349
    59
  "(EX x. P) <-> P",
paulson@13149
    60
  "EX x. x=t", "EX x. t=x",
wenzelm@10431
    61
  "(EX x. x=t & P(x)) <-> P(t)",
wenzelm@12038
    62
  "(EX x. t=x & P(x)) <-> P(t)"]);
clasohm@0
    63
clasohm@0
    64
(*These are NOT supplied by default!*)
wenzelm@12038
    65
bind_thms ("distrib_simps", map int_prove_fun
wenzelm@10431
    66
 ["P & (Q | R) <-> P&Q | P&R",
lcp@282
    67
  "(Q | R) & P <-> Q&P | R&P",
wenzelm@12038
    68
  "(P | Q --> R) <-> (P --> R) & (Q --> R)"]);
clasohm@0
    69
lcp@282
    70
(** Conversion into rewrite rules **)
clasohm@0
    71
wenzelm@12038
    72
bind_thm ("P_iff_F", int_prove_fun "~P ==> (P <-> False)");
wenzelm@12038
    73
bind_thm ("iff_reflection_F", P_iff_F RS iff_reflection);
lcp@282
    74
wenzelm@12038
    75
bind_thm ("P_iff_T", int_prove_fun "P ==> (P <-> True)");
wenzelm@12038
    76
bind_thm ("iff_reflection_T", P_iff_T RS iff_reflection);
lcp@282
    77
lcp@282
    78
(*Make meta-equalities.  The operator below is Trueprop*)
oheimb@5555
    79
lcp@282
    80
fun mk_meta_eq th = case concl_of th of
oheimb@5555
    81
    _ $ (Const("op =",_)$_$_)   => th RS eq_reflection
oheimb@5555
    82
  | _ $ (Const("op <->",_)$_$_) => th RS iff_reflection
wenzelm@10431
    83
  | _                           =>
oheimb@5555
    84
  error("conclusion must be a =-equality or <->");;
oheimb@5555
    85
oheimb@5555
    86
fun mk_eq th = case concl_of th of
nipkow@394
    87
    Const("==",_)$_$_           => th
oheimb@5555
    88
  | _ $ (Const("op =",_)$_$_)   => mk_meta_eq th
oheimb@5555
    89
  | _ $ (Const("op <->",_)$_$_) => mk_meta_eq th
lcp@282
    90
  | _ $ (Const("Not",_)$_)      => th RS iff_reflection_F
lcp@282
    91
  | _                           => th RS iff_reflection_T;
clasohm@0
    92
paulson@6114
    93
(*Replace premises x=y, X<->Y by X==Y*)
wenzelm@10431
    94
val mk_meta_prems =
wenzelm@10431
    95
    rule_by_tactic
paulson@6114
    96
      (REPEAT_FIRST (resolve_tac [meta_eq_to_obj_eq, def_imp_iff]));
paulson@6114
    97
wenzelm@9713
    98
(*Congruence rules for = or <-> (instead of ==)*)
paulson@6114
    99
fun mk_meta_cong rl =
paulson@6114
   100
  standard(mk_meta_eq (mk_meta_prems rl))
paulson@6114
   101
  handle THM _ =>
paulson@6114
   102
  error("Premises and conclusion of congruence rules must use =-equality or <->");
oheimb@5555
   103
oheimb@5304
   104
val mksimps_pairs =
oheimb@5304
   105
  [("op -->", [mp]), ("op &", [conjunct1,conjunct2]),
oheimb@5304
   106
   ("All", [spec]), ("True", []), ("False", [])];
oheimb@5304
   107
wenzelm@16019
   108
(* ###FIXME: move to simplifier.ML
oheimb@5304
   109
val mk_atomize:      (string * thm list) list -> thm -> thm list
oheimb@5304
   110
*)
wenzelm@16019
   111
(* ###FIXME: move to simplifier.ML *)
oheimb@5304
   112
fun mk_atomize pairs =
oheimb@5304
   113
  let fun atoms th =
oheimb@5304
   114
        (case concl_of th of
oheimb@5304
   115
           Const("Trueprop",_) $ p =>
oheimb@5304
   116
             (case head_of p of
oheimb@5304
   117
                Const(a,_) =>
oheimb@5304
   118
                  (case assoc(pairs,a) of
skalberg@15570
   119
                     SOME(rls) => List.concat (map atoms ([th] RL rls))
skalberg@15531
   120
                   | NONE => [th])
oheimb@5304
   121
              | _ => [th])
oheimb@5304
   122
         | _ => [th])
oheimb@5304
   123
  in atoms end;
oheimb@5304
   124
wenzelm@12725
   125
fun mksimps pairs = (map mk_eq o mk_atomize pairs o gen_all);
clasohm@0
   126
paulson@2074
   127
(*** Classical laws ***)
clasohm@0
   128
wenzelm@10431
   129
fun prove_fun s =
wenzelm@10431
   130
 (writeln s;
wenzelm@7355
   131
  prove_goal (the_context ()) s
wenzelm@10431
   132
   (fn prems => [ (cut_facts_tac prems 1),
clasohm@1459
   133
                  (Cla.fast_tac FOL_cs 1) ]));
lcp@745
   134
wenzelm@10431
   135
(*Avoids duplication of subgoals after expand_if, when the true and false
wenzelm@10431
   136
  cases boil down to the same thing.*)
wenzelm@12038
   137
bind_thm ("cases_simp", prove_fun "(P --> Q) & (~P --> Q) <-> Q");
clasohm@0
   138
paulson@1953
   139
paulson@4349
   140
(*** Miniscoping: pushing quantifiers in
paulson@4349
   141
     We do NOT distribute of ALL over &, or dually that of EX over |
wenzelm@10431
   142
     Baaz and Leitsch, On Skolemization and Proof Complexity (1994)
paulson@4349
   143
     show that this step can increase proof length!
paulson@4349
   144
***)
paulson@1953
   145
paulson@4349
   146
(*existential miniscoping*)
wenzelm@12038
   147
bind_thms ("int_ex_simps", map int_prove_fun
wenzelm@12038
   148
 ["(EX x. P(x) & Q) <-> (EX x. P(x)) & Q",
wenzelm@12038
   149
  "(EX x. P & Q(x)) <-> P & (EX x. Q(x))",
wenzelm@12038
   150
  "(EX x. P(x) | Q) <-> (EX x. P(x)) | Q",
wenzelm@12038
   151
  "(EX x. P | Q(x)) <-> P | (EX x. Q(x))"]);
paulson@4349
   152
paulson@4349
   153
(*classical rules*)
wenzelm@12038
   154
bind_thms ("cla_ex_simps", map prove_fun
wenzelm@12038
   155
 ["(EX x. P(x) --> Q) <-> (ALL x. P(x)) --> Q",
wenzelm@12038
   156
  "(EX x. P --> Q(x)) <-> P --> (EX x. Q(x))"]);
paulson@4349
   157
wenzelm@12038
   158
bind_thms ("ex_simps", int_ex_simps @ cla_ex_simps);
paulson@4349
   159
paulson@4349
   160
(*universal miniscoping*)
wenzelm@12038
   161
bind_thms ("int_all_simps", map int_prove_fun
wenzelm@12038
   162
 ["(ALL x. P(x) & Q) <-> (ALL x. P(x)) & Q",
wenzelm@12038
   163
  "(ALL x. P & Q(x)) <-> P & (ALL x. Q(x))",
wenzelm@12038
   164
  "(ALL x. P(x) --> Q) <-> (EX x. P(x)) --> Q",
wenzelm@12038
   165
  "(ALL x. P --> Q(x)) <-> P --> (ALL x. Q(x))"]);
paulson@4349
   166
paulson@4349
   167
(*classical rules*)
wenzelm@12038
   168
bind_thms ("cla_all_simps", map prove_fun
wenzelm@12038
   169
 ["(ALL x. P(x) | Q) <-> (ALL x. P(x)) | Q",
wenzelm@12038
   170
  "(ALL x. P | Q(x)) <-> P | (ALL x. Q(x))"]);
paulson@4349
   171
wenzelm@12038
   172
bind_thms ("all_simps", int_all_simps @ cla_all_simps);
paulson@4349
   173
paulson@4349
   174
paulson@4349
   175
(*** Named rewrite rules proved for IFOL ***)
paulson@1953
   176
paulson@1914
   177
fun int_prove nm thm  = qed_goal nm IFOL.thy thm
wenzelm@10431
   178
    (fn prems => [ (cut_facts_tac prems 1),
paulson@2601
   179
                   (IntPr.fast_tac 1) ]);
paulson@1914
   180
wenzelm@7355
   181
fun prove nm thm  = qed_goal nm (the_context ()) thm (fn _ => [Blast_tac 1]);
paulson@1914
   182
paulson@1914
   183
int_prove "conj_commute" "P&Q <-> Q&P";
paulson@1914
   184
int_prove "conj_left_commute" "P&(Q&R) <-> Q&(P&R)";
wenzelm@12038
   185
bind_thms ("conj_comms", [conj_commute, conj_left_commute]);
paulson@1914
   186
paulson@1914
   187
int_prove "disj_commute" "P|Q <-> Q|P";
paulson@1914
   188
int_prove "disj_left_commute" "P|(Q|R) <-> Q|(P|R)";
wenzelm@12038
   189
bind_thms ("disj_comms", [disj_commute, disj_left_commute]);
paulson@1914
   190
paulson@1914
   191
int_prove "conj_disj_distribL" "P&(Q|R) <-> (P&Q | P&R)";
paulson@1914
   192
int_prove "conj_disj_distribR" "(P|Q)&R <-> (P&R | Q&R)";
paulson@1914
   193
paulson@1914
   194
int_prove "disj_conj_distribL" "P|(Q&R) <-> (P|Q) & (P|R)";
paulson@1914
   195
int_prove "disj_conj_distribR" "(P&Q)|R <-> (P|R) & (Q|R)";
paulson@1914
   196
paulson@1914
   197
int_prove "imp_conj_distrib" "(P --> (Q&R)) <-> (P-->Q) & (P-->R)";
paulson@1914
   198
int_prove "imp_conj"         "((P&Q)-->R)   <-> (P --> (Q --> R))";
paulson@1914
   199
int_prove "imp_disj"         "(P|Q --> R)   <-> (P-->R) & (Q-->R)";
paulson@1914
   200
paulson@3910
   201
prove "imp_disj1" "(P-->Q) | R <-> (P-->Q | R)";
paulson@3910
   202
prove "imp_disj2" "Q | (P-->R) <-> (P-->Q | R)";
paulson@3910
   203
paulson@1914
   204
int_prove "de_Morgan_disj" "(~(P | Q)) <-> (~P & ~Q)";
paulson@1914
   205
prove     "de_Morgan_conj" "(~(P & Q)) <-> (~P | ~Q)";
paulson@1914
   206
paulson@12765
   207
prove     "not_imp" "~(P --> Q) <-> (P & ~Q)";
paulson@1914
   208
prove     "not_iff" "~(P <-> Q) <-> (P <-> ~Q)";
paulson@1914
   209
wenzelm@3835
   210
prove     "not_all" "(~ (ALL x. P(x))) <-> (EX x.~P(x))";
wenzelm@3835
   211
prove     "imp_all" "((ALL x. P(x)) --> Q) <-> (EX x. P(x) --> Q)";
wenzelm@3835
   212
int_prove "not_ex"  "(~ (EX x. P(x))) <-> (ALL x.~P(x))";
paulson@1914
   213
int_prove "imp_ex" "((EX x. P(x)) --> Q) <-> (ALL x. P(x) --> Q)";
paulson@1914
   214
paulson@1914
   215
int_prove "ex_disj_distrib"
paulson@1914
   216
    "(EX x. P(x) | Q(x)) <-> ((EX x. P(x)) | (EX x. Q(x)))";
paulson@1914
   217
int_prove "all_conj_distrib"
paulson@1914
   218
    "(ALL x. P(x) & Q(x)) <-> ((ALL x. P(x)) & (ALL x. Q(x)))";
paulson@1914
   219
paulson@1914
   220
nipkow@11232
   221
local
nipkow@11232
   222
val uncurry = prove_goal (the_context()) "P --> Q --> R ==> P & Q --> R"
nipkow@11232
   223
              (fn prems => [cut_facts_tac prems 1, Blast_tac 1]);
nipkow@11232
   224
nipkow@11232
   225
val iff_allI = allI RS
nipkow@11232
   226
    prove_goal (the_context()) "ALL x. P(x) <-> Q(x) ==> (ALL x. P(x)) <-> (ALL x. Q(x))"
nipkow@11232
   227
               (fn prems => [cut_facts_tac prems 1, Blast_tac 1])
nipkow@12526
   228
val iff_exI = allI RS
nipkow@12526
   229
    prove_goal (the_context()) "ALL x. P(x) <-> Q(x) ==> (EX x. P(x)) <-> (EX x. Q(x))"
nipkow@12526
   230
               (fn prems => [cut_facts_tac prems 1, Blast_tac 1])
nipkow@12526
   231
nipkow@12526
   232
val all_comm = prove_goal (the_context()) "(ALL x y. P(x,y)) <-> (ALL y x. P(x,y))"
nipkow@12526
   233
               (fn _ => [Blast_tac 1])
nipkow@12526
   234
val ex_comm = prove_goal (the_context()) "(EX x y. P(x,y)) <-> (EX y x. P(x,y))"
nipkow@12526
   235
               (fn _ => [Blast_tac 1])
nipkow@11232
   236
in
nipkow@11232
   237
paulson@4349
   238
(** make simplification procedures for quantifier elimination **)
paulson@4349
   239
structure Quantifier1 = Quantifier1Fun(
paulson@4349
   240
struct
paulson@4349
   241
  (*abstract syntax*)
skalberg@15531
   242
  fun dest_eq((c as Const("op =",_)) $ s $ t) = SOME(c,s,t)
skalberg@15531
   243
    | dest_eq _ = NONE;
skalberg@15531
   244
  fun dest_conj((c as Const("op &",_)) $ s $ t) = SOME(c,s,t)
skalberg@15531
   245
    | dest_conj _ = NONE;
skalberg@15531
   246
  fun dest_imp((c as Const("op -->",_)) $ s $ t) = SOME(c,s,t)
skalberg@15531
   247
    | dest_imp _ = NONE;
paulson@4349
   248
  val conj = FOLogic.conj
paulson@4349
   249
  val imp  = FOLogic.imp
paulson@4349
   250
  (*rules*)
paulson@4349
   251
  val iff_reflection = iff_reflection
paulson@4349
   252
  val iffI = iffI
nipkow@12526
   253
  val iff_trans = iff_trans
paulson@4349
   254
  val conjI= conjI
paulson@4349
   255
  val conjE= conjE
paulson@4349
   256
  val impI = impI
paulson@4349
   257
  val mp   = mp
nipkow@11232
   258
  val uncurry = uncurry
paulson@4349
   259
  val exI  = exI
paulson@4349
   260
  val exE  = exE
nipkow@11232
   261
  val iff_allI = iff_allI
nipkow@12526
   262
  val iff_exI = iff_exI
nipkow@12526
   263
  val all_comm = all_comm
nipkow@12526
   264
  val ex_comm = ex_comm
paulson@4349
   265
end);
paulson@4349
   266
nipkow@11232
   267
end;
nipkow@11232
   268
wenzelm@13462
   269
val defEX_regroup =
wenzelm@17002
   270
  Simplifier.simproc (the_context ())
wenzelm@13462
   271
    "defined EX" ["EX x. P(x)"] Quantifier1.rearrange_ex;
wenzelm@7355
   272
paulson@4349
   273
val defALL_regroup =
wenzelm@17002
   274
  Simplifier.simproc (the_context ())
wenzelm@13462
   275
    "defined ALL" ["ALL x. P(x)"] Quantifier1.rearrange_all;
paulson@4349
   276
paulson@4349
   277
paulson@4349
   278
(*** Case splitting ***)
clasohm@0
   279
wenzelm@12038
   280
bind_thm ("meta_eq_to_iff", prove_goal IFOL.thy "x==y ==> x<->y"
wenzelm@12038
   281
  (fn [prem] => [rewtac prem, rtac iffI 1, atac 1, atac 1]));
lcp@282
   282
oheimb@5304
   283
structure SplitterData =
oheimb@5304
   284
  struct
oheimb@5304
   285
  structure Simplifier = Simplifier
oheimb@5555
   286
  val mk_eq          = mk_eq
oheimb@5304
   287
  val meta_eq_to_iff = meta_eq_to_iff
oheimb@5304
   288
  val iffD           = iffD2
oheimb@5304
   289
  val disjE          = disjE
oheimb@5304
   290
  val conjE          = conjE
oheimb@5304
   291
  val exE            = exE
oheimb@5304
   292
  val contrapos      = contrapos
oheimb@5304
   293
  val contrapos2     = contrapos2
oheimb@5304
   294
  val notnotD        = notnotD
oheimb@5304
   295
  end;
berghofe@1722
   296
oheimb@5304
   297
structure Splitter = SplitterFun(SplitterData);
berghofe@1722
   298
oheimb@5304
   299
val split_tac        = Splitter.split_tac;
oheimb@5304
   300
val split_inside_tac = Splitter.split_inside_tac;
oheimb@5304
   301
val split_asm_tac    = Splitter.split_asm_tac;
oheimb@5307
   302
val op addsplits     = Splitter.addsplits;
oheimb@5307
   303
val op delsplits     = Splitter.delsplits;
oheimb@5304
   304
val Addsplits        = Splitter.Addsplits;
oheimb@5304
   305
val Delsplits        = Splitter.Delsplits;
paulson@4325
   306
paulson@4325
   307
paulson@2074
   308
(*** Standard simpsets ***)
paulson@2074
   309
paulson@2074
   310
structure Induction = InductionFun(struct val spec=IFOL.spec end);
paulson@2074
   311
paulson@4349
   312
open Induction;
paulson@2074
   313
oheimb@5555
   314
wenzelm@12038
   315
bind_thms ("meta_simps",
wenzelm@12038
   316
 [triv_forall_equality,   (* prunes params *)
wenzelm@12038
   317
  True_implies_equals]);  (* prune asms `True' *)
paulson@5496
   318
wenzelm@12038
   319
bind_thms ("IFOL_simps",
wenzelm@12038
   320
 [refl RS P_iff_T] @ conj_simps @ disj_simps @ not_simps @
wenzelm@12038
   321
  imp_simps @ iff_simps @ quant_simps);
paulson@2074
   322
wenzelm@12038
   323
bind_thm ("notFalseI", int_prove_fun "~False");
wenzelm@12038
   324
bind_thms ("triv_rls", [TrueI,refl,reflexive_thm,iff_refl,notFalseI]);
paulson@2074
   325
oheimb@2633
   326
fun unsafe_solver prems = FIRST'[resolve_tac (triv_rls@prems),
wenzelm@9713
   327
                                 atac, etac FalseE];
oheimb@2633
   328
(*No premature instantiation of variables during simplification*)
oheimb@2633
   329
fun   safe_solver prems = FIRST'[match_tac (triv_rls@prems),
wenzelm@9713
   330
                                 eq_assume_tac, ematch_tac [FalseE]];
oheimb@2633
   331
paulson@3910
   332
(*No simprules, but basic infastructure for simplification*)
wenzelm@10431
   333
val FOL_basic_ss = empty_ss
wenzelm@10431
   334
  setsubgoaler asm_simp_tac
wenzelm@10431
   335
  setSSolver (mk_solver "FOL safe" safe_solver)
wenzelm@10431
   336
  setSolver (mk_solver "FOL unsafe" unsafe_solver)
wenzelm@10431
   337
  setmksimps (mksimps mksimps_pairs)
wenzelm@10431
   338
  setmkcong mk_meta_cong;
oheimb@5304
   339
wenzelm@17002
   340
fun unfold_tac ss ths =
wenzelm@17002
   341
  ALLGOALS (full_simp_tac
wenzelm@17002
   342
    (Simplifier.inherit_bounds ss (Simplifier.clear_ss FOL_basic_ss) addsimps ths));
wenzelm@17002
   343
oheimb@2633
   344
paulson@3910
   345
(*intuitionistic simprules only*)
wenzelm@10431
   346
val IFOL_ss = FOL_basic_ss
wenzelm@10431
   347
  addsimps (meta_simps @ IFOL_simps @ int_ex_simps @ int_all_simps)
wenzelm@10431
   348
  addsimprocs [defALL_regroup, defEX_regroup]    
wenzelm@10431
   349
  addcongs [imp_cong];
paulson@2074
   350
wenzelm@12038
   351
bind_thms ("cla_simps",
wenzelm@12038
   352
  [de_Morgan_conj, de_Morgan_disj, imp_disj1, imp_disj2,
paulson@12825
   353
   not_imp, not_all, not_ex, cases_simp] @
wenzelm@12038
   354
  map prove_fun
wenzelm@12038
   355
   ["~(P&Q) <-> ~P | ~Q",
wenzelm@12038
   356
    "P | ~P",             "~P | P",
wenzelm@12038
   357
    "~ ~ P <-> P",        "(~P --> P) <-> P",
wenzelm@12038
   358
    "(~P <-> ~Q) <-> (P<->Q)"]);
paulson@2074
   359
paulson@3910
   360
(*classical simprules too*)
paulson@4349
   361
val FOL_ss = IFOL_ss addsimps (cla_simps @ cla_ex_simps @ cla_all_simps);
paulson@2074
   362
wenzelm@7355
   363
val simpsetup = [fn thy => (simpset_ref_of thy := FOL_ss; thy)];
oheimb@2633
   364
oheimb@2633
   365
wenzelm@5219
   366
(*** integration of simplifier with classical reasoner ***)
oheimb@2633
   367
wenzelm@5219
   368
structure Clasimp = ClasimpFun
wenzelm@8472
   369
 (structure Simplifier = Simplifier and Splitter = Splitter
wenzelm@9851
   370
  and Classical  = Cla and Blast = Blast
oheimb@11344
   371
  val iffD1 = iffD1 val iffD2 = iffD2 val notE = notE
wenzelm@9851
   372
  val cla_make_elim = cla_make_elim);
oheimb@4652
   373
open Clasimp;
oheimb@2633
   374
oheimb@2633
   375
val FOL_css = (FOL_cs, FOL_ss);