src/HOL/SMT/Tools/z3_proof_rules.ML
author boehmes
Sat, 27 Mar 2010 02:10:00 +0100
changeset 35983 27e2fa7d4ce7
parent 35012 c3e3ac3ca091
child 36001 992839c4be90
permissions -rw-r--r--
slightly more general simproc (avoids errors of linarith)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     1
(*  Title:      HOL/SMT/Tools/z3_proof_rules.ML
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     2
    Author:     Sascha Boehme, TU Muenchen
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     3
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     4
Z3 proof rules and their reconstruction.
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     5
*)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     6
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     7
signature Z3_PROOF_RULES =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     8
sig
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     9
  (*proof rule names*)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    10
  type rule  
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    11
  val rule_of_string: string -> rule option
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    12
  val string_of_rule: rule -> string
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    13
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    14
  (*proof reconstruction*)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    15
  type proof
33243
17014b1b9353 normalized basic type abbreviations;
wenzelm
parents: 33047
diff changeset
    16
  val make_proof: rule -> int list -> cterm * cterm list -> proof
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    17
  val prove: Proof.context -> thm list option -> proof Inttab.table -> int ->
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    18
    thm
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    19
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    20
  (*setup*)
33749
8aab63a91053 optionally trace theorems used in proof reconstruction
boehmes
parents: 33664
diff changeset
    21
  val trace_assms: bool Config.T
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    22
  val setup: theory -> theory
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    23
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    24
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    25
structure Z3_Proof_Rules: Z3_PROOF_RULES =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    26
struct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    27
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    28
structure T = Z3_Proof_Terms
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    29
33418
1312e8337ce5 added a specific SMT exception captured by smt_tac (prevents the SMT method from failing with an exception),
boehmes
parents: 33243
diff changeset
    30
fun z3_exn msg = raise SMT_Solver.SMT ("Z3 proof reconstruction: " ^ msg)
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    31
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    32
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    33
(* proof rule names *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    34
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    35
datatype rule = TrueAxiom | Asserted | Goal | ModusPonens | Reflexivity |
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    36
  Symmetry | Transitivity | TransitivityStar | Monotonicity | QuantIntro |
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    37
  Distributivity | AndElim | NotOrElim | Rewrite | RewriteStar | PullQuant |
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    38
  PullQuantStar | PushQuant | ElimUnusedVars | DestEqRes | QuantInst |
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    39
  Hypothesis | Lemma | UnitResolution | IffTrue | IffFalse | Commutativity |
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    40
  DefAxiom | IntroDef | ApplyDef | IffOeq | NnfPos | NnfNeg | NnfStar |
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    41
  CnfStar | Skolemize | ModusPonensOeq | ThLemma
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    42
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    43
val rule_names = Symtab.make [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    44
  ("true-axiom", TrueAxiom),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    45
  ("asserted", Asserted),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    46
  ("goal", Goal),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    47
  ("mp", ModusPonens),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    48
  ("refl", Reflexivity),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    49
  ("symm", Symmetry),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    50
  ("trans", Transitivity),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    51
  ("trans*", TransitivityStar),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    52
  ("monotonicity", Monotonicity),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    53
  ("quant-intro", QuantIntro),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    54
  ("distributivity", Distributivity),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    55
  ("and-elim", AndElim),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    56
  ("not-or-elim", NotOrElim),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    57
  ("rewrite", Rewrite),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    58
  ("rewrite*", RewriteStar),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    59
  ("pull-quant", PullQuant),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    60
  ("pull-quant*", PullQuantStar),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    61
  ("push-quant", PushQuant),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    62
  ("elim-unused", ElimUnusedVars),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    63
  ("der", DestEqRes),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    64
  ("quant-inst", QuantInst),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    65
  ("hypothesis", Hypothesis),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    66
  ("lemma", Lemma),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    67
  ("unit-resolution", UnitResolution),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    68
  ("iff-true", IffTrue),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    69
  ("iff-false", IffFalse),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    70
  ("commutativity", Commutativity),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    71
  ("def-axiom", DefAxiom),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    72
  ("intro-def", IntroDef),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    73
  ("apply-def", ApplyDef),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    74
  ("iff~", IffOeq),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    75
  ("nnf-pos", NnfPos),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    76
  ("nnf-neg", NnfNeg),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    77
  ("nnf*", NnfStar),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    78
  ("cnf*", CnfStar),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    79
  ("sk", Skolemize),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    80
  ("mp~", ModusPonensOeq),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    81
  ("th-lemma", ThLemma)]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    82
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    83
val rule_of_string = Symtab.lookup rule_names
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    84
fun string_of_rule r =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    85
  let fun fit (s, r') = if r = r' then SOME s else NONE 
35012
c3e3ac3ca091 removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents: 34960
diff changeset
    86
  in the (Symtab.get_first fit rule_names) end
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    87
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    88
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    89
(* proof representation *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    90
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    91
datatype theorem =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    92
  Thm of thm |
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    93
  MetaEq of thm |
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    94
  Literals of thm * thm Termtab.table
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    95
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    96
fun thm_of (Thm thm) = thm
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    97
  | thm_of (MetaEq thm) = thm COMP @{thm meta_eq_to_obj_eq}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    98
  | thm_of (Literals (thm, _)) = thm
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    99
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   100
fun meta_eq_of (MetaEq thm) = thm
33660
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
   101
  | meta_eq_of p = mk_meta_eq (thm_of p)
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   102
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   103
datatype proof =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   104
  Unproved of {
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   105
    rule: rule,
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   106
    subs: int list,
33243
17014b1b9353 normalized basic type abbreviations;
wenzelm
parents: 33047
diff changeset
   107
    prop: cterm,
17014b1b9353 normalized basic type abbreviations;
wenzelm
parents: 33047
diff changeset
   108
    vars: cterm list } |
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   109
  Sequent of {
33243
17014b1b9353 normalized basic type abbreviations;
wenzelm
parents: 33047
diff changeset
   110
    hyps: cterm list,
17014b1b9353 normalized basic type abbreviations;
wenzelm
parents: 33047
diff changeset
   111
    vars: cterm list,
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   112
    thm: theorem }
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   113
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   114
fun make_proof r ps (ct, cvs) = Unproved {rule=r, subs=ps, prop=ct, vars=cvs}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   115
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   116
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   117
(* proof reconstruction utilities *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   118
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   119
fun try_apply ctxt name nfs ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   120
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   121
    val trace = SMT_Solver.trace_msg ctxt I
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   122
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   123
    fun first [] = z3_exn (name ^ " failed")
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   124
      | first ((n, f) :: nfs) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   125
          (case try f ct of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   126
            SOME thm => (trace (n ^ " succeeded"); thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   127
          | NONE => (trace (n ^ " failed"); first nfs))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   128
  in first nfs end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   129
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   130
fun prop_of thm = (case Thm.prop_of thm of @{term Trueprop} $ t => t | t => t)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   131
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   132
fun as_meta_eq ct = uncurry T.mk_meta_eq (Thm.dest_binop ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   133
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   134
fun by_tac' tac ct = Goal.norm_result (Goal.prove_internal [] ct (K (tac 1)))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   135
fun by_tac tac ct = by_tac' tac (T.mk_prop ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   136
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   137
fun match_instantiate' f ct thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   138
  Thm.instantiate (Thm.match (f (Thm.cprop_of thm), ct)) thm
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   139
val match_instantiate = match_instantiate' I
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   140
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   141
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   142
  fun maybe_instantiate ct thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   143
    try Thm.first_order_match (Thm.cprop_of thm, ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   144
    |> Option.map (fn inst => Thm.instantiate inst thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   145
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   146
fun thm_net_of thms =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   147
  let fun insert thm = Net.insert_term (K false) (Thm.prop_of thm, thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   148
  in fold insert thms Net.empty end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   149
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   150
fun first_of thms ct = get_first (maybe_instantiate ct) thms
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   151
fun net_instance net ct = first_of (Net.match_term net (Thm.term_of ct)) ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   152
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   153
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   154
fun certify ctxt = Thm.cterm_of (ProofContext.theory_of ctxt)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   155
fun certify_var ctxt idx T = certify ctxt (Var (("x", idx), T))
33529
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   156
fun certify_free ctxt idx T = certify ctxt (Free ("x" ^ string_of_int idx, T))
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   157
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   158
fun varify ctxt =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   159
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   160
    fun varify1 cv thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   161
      let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   162
        val T = Thm.typ_of (Thm.ctyp_of_term cv)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   163
        val v = certify_var ctxt (Thm.maxidx_of thm + 1) T
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   164
       in SMT_Normalize.instantiate_free (cv, v) thm end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   165
  in fold varify1 end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   166
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   167
fun under_assumption f ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   168
  let val ct' = T.mk_prop ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   169
  in Thm.implies_intr ct' (f (Thm.assume ct')) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   170
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   171
fun with_conv conv prove ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   172
  let val eq = Thm.symmetric (conv ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   173
  in Thm.equal_elim eq (prove (Thm.lhs_of eq)) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   174
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   175
fun list2 (x, y) = [x, y]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   176
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   177
fun precompose f rule = (f (Thm.cprem_of rule 1), f, rule)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   178
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   179
fun discharge p pq = Thm.implies_elim pq p
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   180
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   181
fun compose (cvs, f, rule) thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   182
  let fun inst thm = Thm.instantiate ([], cvs ~~ f (Thm.cprop_of thm))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   183
  in discharge thm (inst thm rule) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   184
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   185
fun make_hyp_def thm = (* |- c x == t x ==> P (c x)  ~~>  c == t |- P (c x) *) 
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   186
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   187
    val (lhs, rhs) = Thm.dest_binop (Thm.cprem_of thm 1)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   188
    val (cf, cvs) = Drule.strip_comb lhs
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   189
    val eq = T.mk_meta_eq cf (fold_rev Thm.cabs cvs rhs)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   190
    fun apply cv th =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   191
      Thm.combination th (Thm.reflexive cv)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   192
      |> Conv.fconv_rule (Conv.arg_conv (Thm.beta_conversion false))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   193
  in ([eq], Thm.implies_elim thm (fold apply cvs (Thm.assume eq))) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   194
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   195
val true_thm = @{lemma "~False" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   196
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   197
val is_neg = (fn @{term Not} $ _ => true | _ => false)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   198
fun is_neg' f = (fn @{term Not} $ t => f t | _ => false)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   199
val is_conj = (fn @{term "op &"} $ _ $ _ => true | _ => false)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   200
val is_disj = (fn @{term "op |"} $ _ $ _ => true | _ => false)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   201
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   202
(** explosion of conjunctions and disjunctions **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   203
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   204
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   205
  val dest_conj_term = (fn @{term "op &"} $ t $ u => SOME (t, u) | _ => NONE)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   206
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   207
  val negate_term = (fn @{term Not} $ t => t | t => @{term Not} $ t)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   208
  fun dest_disj_term' f = (fn
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   209
      @{term Not} $ (@{term "op |"} $ t $ u) => SOME (f t, f u)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   210
    | _ => NONE)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   211
  val dest_disj_term = dest_disj_term' negate_term
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   212
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   213
  fun destc ct = list2 (Thm.dest_binop (Thm.dest_arg ct))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   214
  val dest_conj1 = precompose destc @{thm conjunct1}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   215
  val dest_conj2 = precompose destc @{thm conjunct2}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   216
  fun dest_conj_rules t =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   217
    dest_conj_term t |> Option.map (K (dest_conj1, dest_conj2))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   218
    
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   219
  fun destd f ct = list2 (f (Thm.dest_binop (Thm.dest_arg (Thm.dest_arg ct))))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   220
  val dn1 = apfst Thm.dest_arg and dn2 = apsnd Thm.dest_arg
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   221
  val dest_disj1 = precompose (destd I) @{lemma "~(P | Q) ==> ~P" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   222
  and dest_disj2 = precompose (destd dn1) @{lemma "~(~P | Q) ==> P" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   223
  and dest_disj3 = precompose (destd I) @{lemma "~(P | Q) ==> ~Q" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   224
  and dest_disj4 = precompose (destd dn2) @{lemma "~(P | ~Q) ==> Q" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   225
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   226
  fun dest_disj_rules t =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   227
    (case dest_disj_term' is_neg t of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   228
      SOME (true, true) => SOME (dest_disj2, dest_disj4)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   229
    | SOME (true, false) => SOME (dest_disj2, dest_disj3)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   230
    | SOME (false, true) => SOME (dest_disj1, dest_disj4)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   231
    | SOME (false, false) => SOME (dest_disj1, dest_disj3)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   232
    | NONE => NONE)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   233
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   234
  val is_dneg = is_neg' is_neg
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   235
  fun destn ct = [Thm.dest_arg (Thm.dest_arg (Thm.dest_arg ct))]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   236
  val dneg_rule = precompose destn @{thm notnotD}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   237
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   238
fun exists_lit is_conj P =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   239
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   240
    val dest = if is_conj then dest_conj_term else dest_disj_term
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   241
    fun exists t = P t orelse
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   242
      (case dest t of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   243
        SOME (t1, t2) => exists t1 orelse exists t2
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   244
      | NONE => false)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   245
  in exists end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   246
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   247
fun explode_term is_conj keep_intermediate =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   248
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   249
    val dest = if is_conj then dest_conj_term else dest_disj_term
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   250
    val dest_rules = if is_conj then dest_conj_rules else dest_disj_rules
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   251
    fun explode1 rules t =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   252
      (case dest t of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   253
        SOME (t1, t2) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   254
          let val (rule1, rule2) = the (dest_rules t)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   255
          in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   256
            explode1 (rule1 :: rules) t1 #>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   257
            explode1 (rule2 :: rules) t2 #>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   258
            keep_intermediate ? cons (t, rev rules)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   259
          end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   260
      | NONE => cons (t, rev rules))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   261
    fun explode0 (@{term Not} $ (@{term Not} $ t)) = [(t, [dneg_rule])]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   262
      | explode0 t = explode1 [] t []
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   263
  in explode0 end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   264
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   265
fun extract_lit thm rules = fold compose rules thm
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   266
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   267
fun explode_thm is_conj full keep_intermediate stop_lits =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   268
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   269
    val dest_rules = if is_conj then dest_conj_rules else dest_disj_rules
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   270
    val tab = fold (Termtab.update o rpair ()) stop_lits Termtab.empty
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   271
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   272
    fun explode1 thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   273
      if Termtab.defined tab (prop_of thm) then cons thm
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   274
      else
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   275
        (case dest_rules (prop_of thm) of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   276
          SOME (rule1, rule2) => explode2 rule1 thm #> explode2 rule2 thm #>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   277
            keep_intermediate ? cons thm
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   278
        | NONE => cons thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   279
    and explode2 dest_rule thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   280
      if full orelse exists_lit is_conj (Termtab.defined tab) (prop_of thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   281
      then explode1 (compose dest_rule thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   282
      else cons (compose dest_rule thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   283
    fun explode0 thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   284
      if not is_conj andalso is_dneg (prop_of thm) then [compose dneg_rule thm]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   285
      else explode1 thm []
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   286
  in explode0 end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   287
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   288
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   289
(** joining of literals to conjunctions or disjunctions **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   290
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   291
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   292
  fun precomp2 f g thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   293
    (f (Thm.cprem_of thm 1), g (Thm.cprem_of thm 2), f, g, thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   294
  fun comp2 (cv1, cv2, f, g, rule) thm1 thm2 =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   295
    let val inst = [(cv1, f (Thm.cprop_of thm1)), (cv2, g (Thm.cprop_of thm2))]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   296
    in Thm.instantiate ([], inst) rule |> discharge thm1 |> discharge thm2 end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   297
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   298
  fun d1 ct = Thm.dest_arg ct and d2 ct = Thm.dest_arg (Thm.dest_arg ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   299
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   300
  val conj_rule = precomp2 d1 d1 @{thm conjI}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   301
  fun comp_conj ((_, thm1), (_, thm2)) = comp2 conj_rule thm1 thm2
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   302
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   303
  val disj1 = precomp2 d2 d2 @{lemma "~P ==> ~Q ==> ~(P | Q)" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   304
  val disj2 = precomp2 d2 d1 @{lemma "~P ==> Q ==> ~(P | ~Q)" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   305
  val disj3 = precomp2 d1 d2 @{lemma "P ==> ~Q ==> ~(~P | Q)" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   306
  val disj4 = precomp2 d1 d1 @{lemma "P ==> Q ==> ~(~P | ~Q)" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   307
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   308
  fun comp_disj ((false, thm1), (false, thm2)) = comp2 disj1 thm1 thm2
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   309
    | comp_disj ((false, thm1), (true, thm2)) = comp2 disj2 thm1 thm2
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   310
    | comp_disj ((true, thm1), (false, thm2)) = comp2 disj3 thm1 thm2
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   311
    | comp_disj ((true, thm1), (true, thm2)) = comp2 disj4 thm1 thm2
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   312
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   313
  fun dest_conj (@{term "op &"} $ t $ u) = ((false, t), (false, u))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   314
    | dest_conj t = raise TERM ("dest_conj", [t])
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   315
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   316
  val neg = (fn @{term Not} $ t => (true, t) | t => (false, @{term Not} $ t))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   317
  fun dest_disj (@{term Not} $ (@{term "op |"} $ t $ u)) = (neg t, neg u)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   318
    | dest_disj t = raise TERM ("dest_disj", [t])
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   319
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   320
  val dnegE = precompose (single o d2 o d1) @{thm notnotD}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   321
  val dnegI = precompose (single o d1) @{lemma "P ==> ~~P" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   322
  fun as_dneg f t = f (@{term Not} $ (@{term Not} $ t))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   323
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   324
  fun dni f = list2 o apsnd f o Thm.dest_binop o f o d1
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   325
  val negIffE = precompose (dni d1) @{lemma "~(P = (~Q)) ==> Q = P" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   326
  val negIffI = precompose (dni I) @{lemma "P = Q ==> ~(Q = (~P))" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   327
  val iff_const = @{term "op = :: bool => _"}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   328
  fun as_negIff f (@{term "op = :: bool => _"} $ t $ u) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   329
        f (@{term Not} $ (iff_const $ u $ (@{term Not} $ t)))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   330
    | as_negIff _ _ = NONE
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   331
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   332
fun make_lit_tab thms = fold (Termtab.update o ` prop_of) thms Termtab.empty
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   333
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   334
fun join is_conj tab t =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   335
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   336
    val comp = if is_conj then comp_conj else comp_disj
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   337
    val dest = if is_conj then dest_conj else dest_disj
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   338
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   339
    val lookup_lit = Termtab.lookup tab
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   340
    fun lookup_lit' t =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   341
      (case t of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   342
        @{term Not} $ (@{term Not} $ t) => (compose dnegI, lookup_lit t)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   343
      | @{term Not} $ (@{term "op = :: bool => _"} $ t $ (@{term Not} $ u)) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   344
          (compose negIffI, lookup_lit (iff_const $ u $ t))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   345
      | @{term Not} $ ((eq as Const (@{const_name "op ="}, _)) $ t $ u) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   346
          let fun rewr lit = lit COMP @{thm not_sym}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   347
          in (rewr, lookup_lit (@{term Not} $ (eq $ u $ t))) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   348
      | _ =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   349
          (case as_dneg lookup_lit t of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   350
            NONE => (compose negIffE, as_negIff lookup_lit t)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   351
          | x => (compose dnegE, x)))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   352
    fun join1 (s, t) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   353
      (case lookup_lit t of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   354
        SOME lit => (s, lit)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   355
      | NONE => 
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   356
          (case lookup_lit' t of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   357
            (rewrite, SOME lit) => (s, rewrite lit)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   358
          | (_, NONE) => (s, comp (pairself join1 (dest t)))))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   359
  in snd (join1 (if is_conj then (false, t) else (true, t))) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   360
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   361
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   362
(** proving equality of conjunctions or disjunctions **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   363
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   364
fun iff_intro thm1 thm2 = thm2 COMP (thm1 COMP @{thm iffI})
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   365
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   366
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   367
  val cp1 = @{lemma "(~P) = (~Q) ==> P = Q" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   368
  val cp2 = @{lemma "(~P) = Q ==> P = (~Q)" by fastsimp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   369
  val cp3 = @{lemma "P = (~Q) ==> (~P) = Q" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   370
  val neg = Thm.capply @{cterm Not}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   371
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   372
fun contrapos1 prove (ct, cu) = prove (neg ct, neg cu) COMP cp1
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   373
fun contrapos2 prove (ct, cu) = prove (neg ct, Thm.dest_arg cu) COMP cp2
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   374
fun contrapos3 prove (ct, cu) = prove (Thm.dest_arg ct, neg cu) COMP cp3
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   375
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   376
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   377
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   378
  fun prove_eq l r (cl, cr) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   379
    let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   380
      fun explode is_conj = explode_thm is_conj true (l <> r) []
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   381
      fun make_tab is_conj thm = make_lit_tab (true_thm :: explode is_conj thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   382
      fun prove is_conj ct tab = join is_conj tab (Thm.term_of ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   383
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   384
      val thm1 = under_assumption (prove r cr o make_tab l) cl
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   385
      val thm2 = under_assumption (prove l cl o make_tab r) cr
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   386
    in iff_intro thm1 thm2 end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   387
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   388
  datatype conj_disj = CONJ | DISJ | NCON | NDIS
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   389
  fun kind_of t =
33047
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   390
    if is_conj t then SOME CONJ
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   391
    else if is_disj t then SOME DISJ
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   392
    else if is_neg' is_conj t then SOME NCON
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   393
    else if is_neg' is_disj t then SOME NDIS
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   394
    else NONE
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   395
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   396
fun prove_conj_disj_eq ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   397
  let val cp = Thm.dest_binop ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   398
  in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   399
    (case pairself (kind_of o Thm.term_of) cp of
33047
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   400
      (SOME CONJ, SOME CONJ) => prove_eq true true cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   401
    | (SOME CONJ, SOME NDIS) => prove_eq true false cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   402
    | (SOME CONJ, NONE) => prove_eq true true cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   403
    | (SOME DISJ, SOME DISJ) => contrapos1 (prove_eq false false) cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   404
    | (SOME DISJ, SOME NCON) => contrapos2 (prove_eq false true) cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   405
    | (SOME DISJ, NONE) => contrapos1 (prove_eq false false) cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   406
    | (SOME NCON, SOME NCON) => contrapos1 (prove_eq true true) cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   407
    | (SOME NCON, SOME DISJ) => contrapos3 (prove_eq true false) cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   408
    | (SOME NCON, NONE) => contrapos3 (prove_eq true false) cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   409
    | (SOME NDIS, SOME NDIS) => prove_eq false false cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   410
    | (SOME NDIS, SOME CONJ) => prove_eq false true cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   411
    | (SOME NDIS, NONE) => prove_eq false true cp
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   412
    | _ => raise CTERM ("prove_conj_disj_eq", [ct]))
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   413
  end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   414
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   415
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   416
(** unfolding of distinct **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   417
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   418
local
33047
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   419
  val set1 = @{lemma "x ~: set [] == ~False" by simp}
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   420
  val set2 = @{lemma "x ~: set [x] == False" by simp}
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   421
  val set3 = @{lemma "x ~: set [y] == x ~= y" by simp}
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   422
  val set4 = @{lemma "x ~: set (x # ys) == False" by simp}
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   423
  val set5 = @{lemma "x ~: set (y # ys) == x ~= y & x ~: set ys" by simp}
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   424
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   425
  fun set_conv ct =
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   426
    (More_Conv.rewrs_conv [set1, set2, set3, set4] else_conv
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   427
    (Conv.rewr_conv set5 then_conv Conv.arg_conv set_conv)) ct
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   428
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   429
  val dist1 = @{lemma "distinct [] == ~False" by simp}
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   430
  val dist2 = @{lemma "distinct [x] == ~False" by simp}
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   431
  val dist3 = @{lemma "distinct (x # xs) == x ~: set xs & distinct xs"
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   432
    by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   433
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   434
  fun binop_conv cv1 cv2 = Conv.combination_conv (Conv.arg_conv cv1) cv2
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   435
in
33047
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   436
fun unfold_distinct_conv ct =
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   437
  (More_Conv.rewrs_conv [dist1, dist2] else_conv
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   438
  (Conv.rewr_conv dist3 then_conv binop_conv set_conv unfold_distinct_conv)) ct
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   439
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   440
33529
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   441
(** proving abstractions **)
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   442
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   443
fun fold_map_op f ct =
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   444
  let val (cf, cu) = Thm.dest_comb ct
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   445
  in f cu #>> Thm.capply cf end
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   446
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   447
fun fold_map_binop f1 f2 ct =
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   448
  let val ((cf, cu1), cu2) = apfst Thm.dest_comb (Thm.dest_comb ct)
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   449
  in f1 cu1 ##>> f2 cu2 #>> uncurry (Thm.mk_binop cf) end
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   450
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   451
fun abstraction_context ctxt = (ctxt, certify_var, 1, false, Ctermtab.empty)
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   452
fun abstraction_context' ctxt = (ctxt, certify_free, 1, true, Ctermtab.empty)
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   453
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   454
fun fresh_abstraction ct (cx as (ctxt, mk_var, idx, gen, tab)) =
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   455
  (case Ctermtab.lookup tab ct of
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   456
    SOME cv => (cv, cx)
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   457
  | NONE =>
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   458
      let val cv = mk_var ctxt idx (#T (Thm.rep_cterm ct))
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   459
      in (cv, (ctxt, mk_var, idx + 1, gen, Ctermtab.update (ct, cv) tab)) end)
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   460
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
   461
fun prove_abstraction tac ct (_, _, _, gen, tab) =
33529
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   462
  let
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   463
    val insts = map swap (Ctermtab.dest tab)
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   464
    val thm = Goal.prove_internal [] ct (fn _ => tac 1)
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   465
  in
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   466
    if gen
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   467
    then fold SMT_Normalize.instantiate_free insts thm
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   468
    else Thm.instantiate ([], insts) thm
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   469
  end
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   470
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   471
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   472
(* core proof rules *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   473
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   474
datatype assms = Some of thm list | Many of thm Net.net
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   475
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   476
val true_false = @{lemma "True == ~ False" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   477
33749
8aab63a91053 optionally trace theorems used in proof reconstruction
boehmes
parents: 33664
diff changeset
   478
val (trace_assms, trace_assms_setup) =
8aab63a91053 optionally trace theorems used in proof reconstruction
boehmes
parents: 33664
diff changeset
   479
  Attrib.config_bool "z3_trace_assms" false
8aab63a91053 optionally trace theorems used in proof reconstruction
boehmes
parents: 33664
diff changeset
   480
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   481
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   482
  val TT_eq = @{lemma "(P = (~False)) == P" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   483
  val remove_trigger = @{lemma "trigger t p == p"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   484
    by (rule eq_reflection, rule trigger_def)}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   485
  val remove_iff = @{lemma "p iff q == p = q"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   486
    by (rule eq_reflection, rule iff_def)}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   487
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   488
  fun with_context simpset ctxt = Simplifier.context ctxt simpset
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   489
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   490
  val prep_ss = with_context (Simplifier.empty_ss addsimps
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   491
    [@{thm Let_def}, remove_trigger, remove_iff, true_false, TT_eq])
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   492
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   493
  val TT_eq_conv = Conv.rewr_conv TT_eq
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   494
  val norm_conv = More_Conv.bottom_conv (K (Conv.try_conv TT_eq_conv))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   495
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   496
  val threshold = 10
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   497
  
33749
8aab63a91053 optionally trace theorems used in proof reconstruction
boehmes
parents: 33664
diff changeset
   498
  fun trace ctxt thm =
8aab63a91053 optionally trace theorems used in proof reconstruction
boehmes
parents: 33664
diff changeset
   499
    if Config.get ctxt trace_assms
8aab63a91053 optionally trace theorems used in proof reconstruction
boehmes
parents: 33664
diff changeset
   500
    then tracing (Display.string_of_thm ctxt thm)
8aab63a91053 optionally trace theorems used in proof reconstruction
boehmes
parents: 33664
diff changeset
   501
    else ()
8aab63a91053 optionally trace theorems used in proof reconstruction
boehmes
parents: 33664
diff changeset
   502
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   503
  val lookup = (fn Some thms => first_of thms | Many net => net_instance net)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   504
  fun lookup_assm ctxt assms ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   505
    (case lookup assms ct of
33749
8aab63a91053 optionally trace theorems used in proof reconstruction
boehmes
parents: 33664
diff changeset
   506
      SOME thm => (trace ctxt thm; thm)
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   507
    | _ => z3_exn ("not asserted: " ^
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   508
        quote (Syntax.string_of_term ctxt (Thm.term_of ct))))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   509
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   510
fun prepare_assms ctxt assms =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   511
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   512
    val rewrite = Conv.fconv_rule (Simplifier.rewrite (prep_ss ctxt))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   513
    val thms = map rewrite assms
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   514
  in if length assms < threshold then Some thms else Many (thm_net_of thms) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   515
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   516
fun asserted _ NONE ct = Thm (Thm.assume (T.mk_prop ct))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   517
  | asserted ctxt (SOME assms) ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   518
      Thm (with_conv (norm_conv ctxt) (lookup_assm ctxt assms) (T.mk_prop ct))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   519
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   520
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   521
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   522
(** P ==> P = Q ==> Q   or   P ==> P --> Q ==> Q **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   523
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   524
  val meta_iffD1 = @{lemma "P == Q ==> P ==> (Q::bool)" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   525
  val meta_iffD1_c = precompose (list2 o Thm.dest_binop) meta_iffD1
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   526
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   527
  val iffD1_c = precompose (list2 o Thm.dest_binop o Thm.dest_arg) @{thm iffD1}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   528
  val mp_c = precompose (list2 o Thm.dest_binop o Thm.dest_arg) @{thm mp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   529
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   530
fun mp (MetaEq thm) p = Thm (Thm.implies_elim (compose meta_iffD1_c thm) p)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   531
  | mp p_q p = 
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   532
      let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   533
        val pq = thm_of p_q
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   534
        val thm = compose iffD1_c pq handle THM _ => compose mp_c pq
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   535
      in Thm (Thm.implies_elim thm p) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   536
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   537
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   538
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   539
(** and_elim:     P1 & ... & Pn ==> Pi **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   540
(** not_or_elim:  ~(P1 | ... | Pn) ==> ~Pi **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   541
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   542
  fun get_lit conj t (l, thm) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   543
    let val is_sublit_of = exists_lit conj (fn u => u aconv t)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   544
    in if is_sublit_of (prop_of thm) then SOME (l, thm) else NONE end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   545
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   546
  fun derive conj t lits idx ptab =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   547
    let
35012
c3e3ac3ca091 removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents: 34960
diff changeset
   548
      val (l, lit) = the (Termtab.get_first (get_lit conj t) lits)
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   549
      val ls = explode_thm conj false false [t] lit
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   550
      val lits' = fold (Termtab.update o ` prop_of) ls (Termtab.delete l lits)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   551
      fun upd (Sequent {hyps, vars, thm}) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   552
            Sequent {hyps=hyps, vars=vars, thm = Literals (thm_of thm, lits')}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   553
        | upd p = p
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   554
    in (the (Termtab.lookup lits' t), Inttab.map_entry idx upd ptab) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   555
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   556
  val mk_tab = make_lit_tab o single
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   557
  val literals_of = (fn Literals (_, lits) => lits | p => mk_tab (thm_of p))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   558
  fun lit_elim conj (p, idx) ct ptab =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   559
    let val lits = literals_of p
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   560
    in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   561
      (case Termtab.lookup lits (Thm.term_of ct) of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   562
        SOME lit => (Thm lit, ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   563
      | NONE => apfst Thm (derive conj (Thm.term_of ct) lits idx ptab))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   564
    end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   565
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   566
val and_elim = lit_elim true
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   567
val not_or_elim = lit_elim false
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   568
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   569
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   570
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   571
(** P1 ... Pn |- False ==> |- ~P1 | ... | ~Pn **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   572
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   573
  fun step lit thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   574
    Thm.implies_elim (Thm.implies_intr (Thm.cprop_of lit) thm) lit
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   575
  val explode_disj = explode_thm false false false
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   576
  fun intro hyps thm th = fold step (explode_disj hyps th) thm
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   577
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   578
  fun dest_ccontr ct = [Thm.dest_arg (Thm.dest_arg (Thm.dest_arg1 ct))]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   579
  val ccontr = precompose dest_ccontr @{thm ccontr}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   580
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   581
fun lemma thm ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   582
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   583
    val cu = Thm.capply @{cterm Not} ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   584
    val hyps = map_filter (try HOLogic.dest_Trueprop) (#hyps (Thm.rep_thm thm))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   585
  in Thm (compose ccontr (under_assumption (intro hyps thm) cu)) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   586
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   587
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   588
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   589
(** \/{P1, ..., Pn, Q1, ..., Qn} & ~P1 & ... & ~Pn ==> \/{Q1, ..., Qn} **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   590
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   591
  val explode_disj = explode_thm false true false and join_disj = join false
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   592
  fun unit thm thms th =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   593
    let val t = @{term Not} $ prop_of thm and ts = map prop_of thms
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   594
    in join_disj (make_lit_tab (thms @ explode_disj ts th)) t end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   595
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   596
  fun dest_arg2 ct = Thm.dest_arg (Thm.dest_arg ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   597
  fun dest ct = list2 (pairself dest_arg2 (Thm.dest_binop ct))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   598
  val contrapos = precompose dest @{lemma "(~P ==> ~Q) ==> Q ==> P" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   599
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   600
fun unit_resolution thm thms ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   601
  under_assumption (unit thm thms) (Thm.capply @{cterm Not} ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   602
  |> Thm o discharge thm o compose contrapos
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   603
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   604
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   605
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   606
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   607
  val iff1 = @{lemma "P ==> P == (~ False)" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   608
  val iff2 = @{lemma "~P ==> P == False" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   609
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   610
fun iff_true thm = MetaEq (thm COMP iff1)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   611
fun iff_false thm = MetaEq (thm COMP iff2)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   612
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   613
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   614
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   615
(** distributivity of | over & **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   616
val distributivity = Thm o by_tac (Classical.fast_tac HOL_cs)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   617
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   618
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   619
(** Tseitin-like axioms **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   620
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   621
  val disjI1 = @{lemma "(P ==> Q) ==> ~P | Q" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   622
  val disjI2 = @{lemma "(~P ==> Q) ==> P | Q" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   623
  val disjI3 = @{lemma "(~Q ==> P) ==> P | Q" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   624
  val disjI4 = @{lemma "(Q ==> P) ==> P | ~Q" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   625
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   626
  fun prove' conj1 conj2 ct2 thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   627
    let val tab =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   628
      make_lit_tab (true_thm :: explode_thm conj1 true (conj1 <> conj2) [] thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   629
    in join conj2 tab (Thm.term_of ct2) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   630
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   631
  fun prove rule (ct1, conj1) (ct2, conj2) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   632
    under_assumption (prove' conj1 conj2 ct2) ct1 COMP rule
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   633
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   634
  fun prove_def_axiom ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   635
    let val (ct1, ct2) = Thm.dest_binop ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   636
    in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   637
      (case Thm.term_of ct1 of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   638
        @{term Not} $ (@{term "op &"} $ _ $ _) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   639
          prove disjI1 (Thm.dest_arg ct1, true) (ct2, true)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   640
      | @{term "op &"} $ _ $ _ =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   641
          prove disjI3 (Thm.capply @{cterm Not} ct2, false) (ct1, true)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   642
      | @{term Not} $ (@{term "op |"} $ _ $ _) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   643
          prove disjI3 (Thm.capply @{cterm Not} ct2, false) (ct1, false)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   644
      | @{term "op |"} $ _ $ _ =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   645
          prove disjI2 (Thm.capply @{cterm Not} ct1, false) (ct2, true)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   646
      | Const (@{const_name distinct}, _) $ _ =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   647
          let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   648
            fun dis_conv cv = Conv.arg_conv (Conv.arg1_conv cv)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   649
            fun prv cu =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   650
              let val (cu1, cu2) = Thm.dest_binop (Thm.dest_arg cu)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   651
              in prove disjI4 (Thm.dest_arg cu2, true) (cu1, true) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   652
          in with_conv (dis_conv unfold_distinct_conv) prv (T.mk_prop ct) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   653
      | @{term Not} $ (Const (@{const_name distinct}, _) $ _) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   654
          let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   655
            fun dis_conv cv = Conv.arg_conv (Conv.arg1_conv (Conv.arg_conv cv))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   656
            fun prv cu =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   657
              let val (cu1, cu2) = Thm.dest_binop (Thm.dest_arg cu)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   658
              in prove disjI1 (Thm.dest_arg cu1, true) (cu2, true) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   659
          in with_conv (dis_conv unfold_distinct_conv) prv (T.mk_prop ct) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   660
      | _ => raise CTERM ("prove_def_axiom", [ct]))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   661
    end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   662
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   663
  val ifI = @{lemma "(P ==> Q1) ==> (~P ==> Q2) ==> if P then Q1 else Q2"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   664
    by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   665
  val ifE = @{lemma
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   666
    "(if P then Q1 else Q2) ==> (P --> Q1 ==> ~P --> Q2 ==> R) ==> R" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   667
  val claset = HOL_cs addIs [ifI] addEs [ifE]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   668
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   669
fun def_axiom ctxt ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   670
  Thm (try_apply ctxt "def_axiom" [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   671
    ("conj/disj", prove_def_axiom),
34960
1d5ee19ef940 support skolem constant for extensional arrays in Z3 proofs
boehmes
parents: 33749
diff changeset
   672
    ("simp", by_tac (Simplifier.simp_tac HOL_ss)),
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   673
    ("fast", by_tac (Classical.fast_tac claset)),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   674
    ("simp+fast", by_tac (Simplifier.simp_tac HOL_ss THEN_ALL_NEW
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   675
      Classical.fast_tac claset))] ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   676
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   677
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   678
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   679
(** local definitions **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   680
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   681
  val intro_rules = [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   682
    @{lemma "n == P ==> (~n | P) & (n | ~P)" by simp},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   683
    @{lemma "n == (if P then s else t) ==> (~P | n = s) & (P | n = t)"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   684
      by simp},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   685
    @{lemma "n == P ==> n = P" by (rule meta_eq_to_obj_eq)} ]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   686
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   687
  val apply_rules = [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   688
    @{lemma "(~n | P) & (n | ~P) ==> P == n" by (atomize(full)) fast},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   689
    @{lemma "(~P | n = s) & (P | n = t) ==> (if P then s else t) == n"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   690
      by (atomize(full)) fastsimp} ]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   691
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   692
  val inst_rule = match_instantiate' Thm.dest_arg
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   693
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   694
  fun apply_rule ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   695
    (case get_first (try (inst_rule (T.mk_prop ct))) intro_rules of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   696
      SOME thm => thm
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   697
    | NONE => raise CTERM ("intro_def", [ct]))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   698
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   699
fun intro_def ct = apsnd Thm (make_hyp_def (apply_rule ct))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   700
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   701
fun apply_def thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   702
  get_first (try (fn rule => MetaEq (thm COMP rule))) apply_rules
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   703
  |> the_default (Thm thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   704
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   705
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   706
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   707
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   708
  val quant_rules1 = ([
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   709
    @{lemma "(!!x. P x == Q) ==> ALL x. P x == Q" by simp},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   710
    @{lemma "(!!x. P x == Q) ==> EX x. P x == Q" by simp}], [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   711
    @{lemma "(!!x. P x == Q x) ==> ALL x. P x == ALL x. Q x" by simp},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   712
    @{lemma "(!!x. P x == Q x) ==> EX x. P x == EX x. Q x" by simp}])
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   713
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   714
  val quant_rules2 = ([
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   715
    @{lemma "(!!x. ~P x == Q) ==> ~(ALL x. P x) == Q" by simp},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   716
    @{lemma "(!!x. ~P x == Q) ==> ~(EX x. P x) == Q" by simp}], [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   717
    @{lemma "(!!x. ~P x == Q x) ==> ~(ALL x. P x) == EX x. Q x" by simp},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   718
    @{lemma "(!!x. ~P x == Q x) ==> ~(EX x. P x) == ALL x. Q x" by simp}])
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   719
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   720
  fun nnf_quant_tac thm (qs as (qs1, qs2)) i st = (
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   721
    Tactic.rtac thm ORELSE'
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   722
    (Tactic.match_tac qs1 THEN' nnf_quant_tac thm qs) ORELSE'
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   723
    (Tactic.match_tac qs2 THEN' nnf_quant_tac thm qs)) i st
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   724
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   725
  fun nnf_quant ctxt qs (p, (vars, _)) ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   726
    as_meta_eq ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   727
    |> by_tac' (nnf_quant_tac (varify ctxt vars (meta_eq_of p)) qs)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   728
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   729
  val nnf_rules = thm_net_of [@{thm not_not}]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   730
33529
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   731
  fun abstract ct =
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   732
    (case Thm.term_of ct of
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   733
      @{term False} => pair
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   734
    | @{term Not} $ _ => fold_map_op abstract
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   735
    | @{term "op &"} $ _ $ _ => fold_map_binop abstract abstract
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   736
    | @{term "op |"} $ _ $ _ => fold_map_binop abstract abstract
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   737
    | @{term "op -->"} $ _ $ _ => fold_map_binop abstract abstract
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   738
    | @{term "op = :: bool => _"} $ _ $ _ => fold_map_binop abstract abstract
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   739
    | _ => fresh_abstraction) ct
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   740
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   741
  fun abstracted ctxt ct =
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   742
    abstraction_context' ctxt
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   743
    |> abstract (Thm.dest_arg ct)
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   744
    |>> T.mk_prop
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   745
    |-> prove_abstraction (Classical.best_tac HOL_cs)
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   746
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   747
  fun prove_nnf ctxt =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   748
    try_apply ctxt "nnf" [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   749
      ("conj/disj", prove_conj_disj_eq o Thm.dest_arg),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   750
      ("rule", the o net_instance nnf_rules),
33529
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
   751
      ("abstract", abstracted ctxt),
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   752
      ("tactic", by_tac' (Classical.best_tac HOL_cs))]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   753
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   754
fun nnf ctxt ps ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   755
  (case Thm.term_of ct of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   756
    _ $ (l as Const _ $ Abs _) $ (r as Const _ $ Abs _) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   757
      if l aconv r then MetaEq (Thm.reflexive (Thm.dest_arg ct))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   758
      else MetaEq (nnf_quant ctxt quant_rules1 (hd ps) ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   759
  | _ $ (@{term Not} $ (Const _ $ Abs _)) $ (Const _ $ Abs _) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   760
      MetaEq (nnf_quant ctxt quant_rules2 (hd ps) ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   761
  | _ =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   762
      let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   763
        val eqs = map (Thm.symmetric o meta_eq_of o fst) ps
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   764
        val nnf_rewr_conv = Conv.arg_conv (Conv.arg_conv
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   765
          (More_Conv.top_sweep_conv (K (More_Conv.rewrs_conv eqs)) ctxt))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   766
      in Thm (with_conv nnf_rewr_conv (prove_nnf ctxt) (T.mk_prop ct)) end)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   767
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   768
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   769
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   770
(* equality proof rules *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   771
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   772
(** t = t **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   773
fun refl ct = MetaEq (Thm.reflexive (Thm.dest_arg ct))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   774
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   775
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   776
(** s = t ==> t = s **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   777
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   778
  val symm_rule = @{lemma "s = t ==> t == s" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   779
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   780
fun symm (MetaEq thm) = MetaEq (Thm.symmetric thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   781
  | symm p = MetaEq (thm_of p COMP symm_rule)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   782
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   783
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   784
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   785
(** s = t ==> t = u ==> s = u **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   786
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   787
  val trans_rule = @{lemma "s = t ==> t = u ==> s == u" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   788
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   789
fun trans (MetaEq thm) q = MetaEq (Thm.transitive thm (meta_eq_of q))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   790
  | trans p (MetaEq thm) = MetaEq (Thm.transitive (meta_eq_of p) thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   791
  | trans p q = MetaEq (thm_of q COMP (thm_of p COMP trans_rule))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   792
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   793
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   794
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   795
(** t1 = s1 & ... & tn = sn ==> f t1 ... tn = f s1 .. sn
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   796
    (reflexive antecendents are droppped) **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   797
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   798
  exception MONO
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   799
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   800
  fun prove_refl (ct, _) = Thm.reflexive ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   801
  fun prove_comb f g cp =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   802
    let val ((ct1, ct2), (cu1, cu2)) = pairself Thm.dest_comb cp
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   803
    in Thm.combination (f (ct1, cu1)) (g (ct2, cu2)) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   804
  fun prove_arg f = prove_comb prove_refl f
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   805
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   806
  fun prove f cp = prove_comb (prove f) f cp handle CTERM _ => prove_refl cp
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   807
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   808
  fun prove_nary is_comb f =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   809
    let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   810
      fun prove (cp as (ct, _)) = f cp handle MONO =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   811
        if is_comb (Thm.term_of ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   812
        then prove_comb (prove_arg prove) prove cp
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   813
        else prove_refl cp
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   814
    in prove end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   815
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   816
  fun prove_list f n cp =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   817
    if n = 0 then prove_refl cp
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   818
    else prove_comb (prove_arg f) (prove_list f (n-1)) cp
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   819
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   820
  fun with_length f (cp as (cl, _)) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   821
    f (length (HOLogic.dest_list (Thm.term_of cl))) cp
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   822
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   823
  fun prove_distinct f = prove_arg (with_length (prove_list f))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   824
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   825
  fun prove_eq exn lookup cp =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   826
    (case lookup (Logic.mk_equals (pairself Thm.term_of cp)) of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   827
      SOME eq => eq
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   828
    | NONE => if exn then raise MONO else prove_refl cp)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   829
  val prove_eq_exn = prove_eq true and prove_eq_safe = prove_eq false
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   830
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   831
  fun mono f (cp as (cl, _)) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   832
    (case Term.head_of (Thm.term_of cl) of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   833
      @{term "op &"} => prove_nary is_conj (prove_eq_exn f)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   834
    | @{term "op |"} => prove_nary is_disj (prove_eq_exn f)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   835
    | Const (@{const_name distinct}, _) => prove_distinct (prove_eq_safe f)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   836
    | _ => prove (prove_eq_safe f)) cp
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   837
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   838
fun monotonicity eqs ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   839
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   840
    val tab = map (` Thm.prop_of o meta_eq_of) eqs
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   841
    val lookup = AList.lookup (op aconv) tab
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   842
    val cp = Thm.dest_binop ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   843
  in MetaEq (prove_eq_exn lookup cp handle MONO => mono lookup cp) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   844
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   845
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   846
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   847
(** f a b = f b a **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   848
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   849
  val rule = @{lemma "a = b == b = a" by (atomize(full)) (rule eq_commute)}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   850
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   851
fun commutativity ct = MetaEq (match_instantiate (as_meta_eq ct) rule)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   852
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   853
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   854
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   855
(* quantifier proof rules *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   856
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   857
(** P ?x = Q ?x ==> (ALL x. P x) = (ALL x. Q x)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   858
    P ?x = Q ?x ==> (EX x. P x) = (EX x. Q x)   **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   859
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   860
  val rules = [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   861
    @{lemma "(!!x. P x == Q x) ==> (EX x. P x) == (EX x. Q x)" by simp},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   862
    @{lemma "(!!x. P x == Q x) ==> (ALL x. P x) == (ALL x. Q x)" by simp}]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   863
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   864
fun quant_intro ctxt (p, (vars, _)) ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   865
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   866
    val rules' = varify ctxt vars (meta_eq_of p) :: rules
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   867
    val cu = as_meta_eq ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   868
  in MetaEq (by_tac' (REPEAT_ALL_NEW (Tactic.match_tac rules')) cu) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   869
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   870
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   871
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   872
(** |- ((ALL x. P x) | Q) = (ALL x. P x | Q) **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   873
val pull_quant =
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 33010
diff changeset
   874
  Thm o by_tac (Tactic.rtac @{thm refl} ORELSE' Classical.best_tac HOL_cs)
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   875
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   876
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   877
(** |- (ALL x. P x & Q x) = ((ALL x. P x) & (ALL x. Q x)) **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   878
val push_quant =
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 33010
diff changeset
   879
  Thm o by_tac (Tactic.rtac @{thm refl} ORELSE' Classical.best_tac HOL_cs)
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   880
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   881
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   882
(**
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   883
  |- (ALL x1 ... xn y1 ... yn. P x1 ... xn) = (ALL x1 ... xn. P x1 ... xn)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   884
**)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   885
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   886
  val elim_all = @{lemma "ALL x. P == P" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   887
  val elim_ex = @{lemma "EX x. P == P" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   888
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   889
  val rule = (fn @{const_name All} => elim_all | _ => elim_ex)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   890
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   891
  fun collect xs tp =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   892
    if (op aconv) tp then rev xs
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   893
    else
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   894
      (case tp of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   895
        (Const (q, _) $ Abs (_, _, l), r' as Const _ $ Abs (_, _, r)) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   896
          if l aconv r then rev xs
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   897
          else if Term.loose_bvar1 (l, 0) then collect (NONE :: xs) (l, r)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   898
          else collect (SOME (rule q) :: xs) (Term.incr_bv (~1, 0, l), r')
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   899
      | (Const (q, _) $ Abs (_, _, l), r) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   900
          collect (SOME (rule q) :: xs) (Term.incr_bv (~1, 0, l), r)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   901
      | (l, r) => raise TERM ("elim_unused", [l, r]))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   902
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   903
  fun elim _ [] ct = Conv.all_conv ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   904
    | elim ctxt (x::xs) ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   905
        (case x of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   906
          SOME rule => Conv.rewr_conv rule then_conv elim ctxt xs
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   907
        | _ => Conv.arg_conv (Conv.abs_conv (fn (_,cx) => elim cx xs) ctxt)) ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   908
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   909
fun elim_unused_vars ctxt ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   910
  let val (lhs, rhs) = Thm.dest_binop ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   911
  in MetaEq (elim ctxt (collect [] (Thm.term_of lhs, Thm.term_of rhs)) lhs) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   912
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   913
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   914
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   915
(** 
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   916
  |- (ALL x1 ... xn. ~(x1 = t1 & ... xn = tn) | P x1 ... xn) = P t1 ... tn
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   917
**)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   918
val dest_eq_res = Thm o by_tac (Simplifier.simp_tac HOL_ss)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   919
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   920
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   921
(** |- ~(ALL x1...xn. P x1...xn) | P a1...an **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   922
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   923
  val rule = @{lemma "~ P x | Q ==> ~(ALL x. P x) | Q" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   924
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   925
val quant_inst = Thm o by_tac (
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   926
  REPEAT_ALL_NEW (Tactic.match_tac [rule])
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   927
  THEN' Tactic.rtac @{thm excluded_middle})
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   928
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   929
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   930
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   931
(** c = SOME x. P x |- (EX x. P x) = P c
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   932
    c = SOME x. ~ P x |- ~(ALL x. P x) = ~ P c **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   933
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   934
  val elim_ex = @{lemma "EX x. P == P" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   935
  val elim_all = @{lemma "~ (ALL x. P) == ~P" by simp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   936
  val sk_ex = @{lemma "c == SOME x. P x ==> EX x. P x == P c"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   937
    by simp (intro eq_reflection some_eq_ex[symmetric])}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   938
  val sk_all = @{lemma "c == SOME x. ~ P x ==> ~(ALL x. P x) == ~ P c"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   939
    by (simp only: not_all) (intro eq_reflection some_eq_ex[symmetric])}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   940
  val sk_ex_rule = ((sk_ex, I), elim_ex)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   941
  and sk_all_rule = ((sk_all, Thm.dest_arg), elim_all)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   942
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   943
  fun dest f sk_rule = 
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   944
    Thm.dest_comb (f (Thm.dest_arg (Thm.dest_arg (Thm.cprop_of sk_rule))))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   945
  fun type_of f sk_rule = Thm.ctyp_of_term (snd (dest f sk_rule))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   946
  fun inst_sk (sk_rule, f) p c =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   947
    Thm.instantiate ([(type_of f sk_rule, Thm.ctyp_of_term c)], []) sk_rule
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   948
    |> (fn sk' => Thm.instantiate ([], (list2 (dest f sk') ~~ [p, c])) sk')
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   949
    |> Conv.fconv_rule (Thm.beta_conversion true)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   950
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   951
  fun kind (Const (q as @{const_name Ex}, _) $ _) = (sk_ex_rule, q, I, I)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   952
    | kind (@{term Not} $ (Const (q as @{const_name All}, _) $ _)) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   953
        (sk_all_rule, q, Thm.dest_arg, Thm.capply @{cterm Not})
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   954
    | kind _ = z3_exn "skolemize: no quantifier"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   955
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   956
  fun bodies_of ctxt ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   957
    let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   958
      val (rule, q, dest, make) = kind (Thm.term_of ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   959
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   960
      fun inst_abs idx T cbs ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   961
        let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   962
          val cv = certify_var ctxt idx T
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   963
          val cu = Drule.beta_conv (Thm.dest_arg ct) cv
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   964
        in dest_body (idx + 1) ((cv, Thm.dest_arg ct) :: cbs) cu end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   965
      and dest_body idx cbs ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   966
        (case Thm.term_of ct of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   967
          Const (qname, _) $ Abs (_, T, _) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   968
            if q = qname then inst_abs idx T cbs ct else (make ct, rev cbs)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   969
        | _ => (make ct, rev cbs))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   970
    in (rule, dest_body (#maxidx (Thm.rep_cterm ct) + 1) [] (dest ct)) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   971
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   972
  fun transitive f thm = Thm.transitive thm (f (Thm.rhs_of thm))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   973
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   974
  fun sk_step (rule, elim) (cv, mct, cb) (is, thm) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   975
    (case mct of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   976
      SOME ct =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   977
        make_hyp_def (inst_sk rule (Thm.instantiate_cterm ([], is) cb) ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   978
        |> apsnd (pair ((cv, ct) :: is) o Thm.transitive thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   979
    | NONE => ([], (is, transitive (Conv.rewr_conv elim) thm)))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   980
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   981
fun skolemize ctxt ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   982
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   983
    val (lhs, rhs) = Thm.dest_binop ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   984
    val (rule, (cu, cbs)) = bodies_of ctxt lhs
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   985
    val ctab = snd (Thm.first_order_match (cu, rhs))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   986
    fun lookup_var (cv, cb) = (cv, AList.lookup (op aconvc) ctab cv, cb)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   987
  in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   988
    ([], Thm.reflexive lhs)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   989
    |> fold_map (sk_step rule) (map lookup_var cbs)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   990
    |> apfst (rev o flat) o apsnd (MetaEq o snd)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   991
  end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   992
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   993
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   994
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   995
(* theory proof rules *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   996
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   997
(** prove linear arithmetic problems via generalization **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   998
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   999
  val is_numeral = can HOLogic.dest_number
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1000
  fun is_number (Const (@{const_name uminus}, _) $ t) = is_numeral t
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1001
    | is_number t = is_numeral t
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1002
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1003
  local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1004
    val int_distrib = @{lemma "n * (x + y) == n * x + n * (y::int)"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1005
      by (simp add: int_distrib)}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1006
    val real_distrib = @{lemma "n * (x + y) == n * x + n * (y::real)"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1007
      by (simp add: mult.add_right)}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1008
    val int_assoc = @{lemma "n * (m * x) == (n * m) * (x::int)" by linarith}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1009
    val real_assoc = @{lemma "n * (m * x) == (n * m) * (x::real)" by linarith}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1011
    val number_of_cong = @{lemma 
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1012
      "number_of x * number_of y == (number_of (x * y) :: int)"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1013
      "number_of x * number_of y == (number_of (x * y) :: real)"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1014
      by simp_all}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1015
    val reduce_ss = HOL_ss addsimps @{thms mult_bin_simps}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1016
      addsimps @{thms add_bin_simps} addsimps @{thms succ_bin_simps}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1017
      addsimps @{thms minus_bin_simps} addsimps @{thms pred_bin_simps}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1018
      addsimps number_of_cong
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1019
    val reduce_conv = Simplifier.rewrite reduce_ss
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1020
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1021
    fun apply_conv distrib assoc u ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1022
     ((case u of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1023
        Const (@{const_name times}, _) $ n $ _ =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1024
          if is_number n
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1025
          then Conv.rewr_conv assoc then_conv Conv.arg1_conv reduce_conv 
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1026
          else Conv.rewr_conv distrib
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1027
      | _ => Conv.rewr_conv distrib)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1028
      then_conv Conv.binop_conv (Conv.try_conv distrib_conv)) ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1029
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1030
    and distrib_conv ct = 
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1031
      (case Thm.term_of ct of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1032
        @{term "op * :: int => _"} $ n $ u =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1033
          if is_number n then apply_conv int_distrib int_assoc u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1034
          else Conv.no_conv
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1035
      | @{term "op * :: real => _"} $ n $ u =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1036
          if is_number n then apply_conv real_distrib real_assoc u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1037
          else Conv.no_conv
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1038
      | _ => Conv.no_conv) ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1039
  in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1040
  val all_distrib_conv = More_Conv.top_sweep_conv (K distrib_conv)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1041
  end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1042
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1043
  local
33529
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
  1044
    fun fresh ct = fresh_abstraction ct
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1045
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1046
    fun mult f1 f2 ct t u =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1047
      if is_number t 
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1048
      then if is_number u then pair ct else fold_map_binop f1 f2 ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1049
      else fresh ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1050
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1051
    fun poly ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1052
      (case Thm.term_of ct of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1053
        Const (@{const_name plus}, _) $ _ $ _ => fold_map_binop poly poly ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1054
      | Const (@{const_name minus}, _) $ _ $ _ => fold_map_binop poly poly ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1055
      | Const (@{const_name times}, _) $ t $ u => mult pair fresh ct t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1056
      | Const (@{const_name div}, _) $ t $ u => mult fresh pair ct t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1057
      | Const (@{const_name mod}, _) $ t $ u => mult fresh pair ct t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1058
      | t => if is_number t then pair ct else fresh ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1059
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1060
    val ineq_ops = [@{term "op = :: int => _"}, @{term "op < :: int => _"},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1061
      @{term "op <= :: int => _"}, @{term "op = :: real => _"},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1062
      @{term "op < :: real => _"}, @{term "op <= :: real => _"}]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1063
    fun ineq ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1064
      (case Thm.term_of ct of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1065
        t $ _ $ _ =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1066
          if member (op =) ineq_ops t then fold_map_binop poly poly ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1067
          else raise CTERM ("arith_lemma", [ct])
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1068
      | @{term Not} $ (t $ _ $ _) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1069
          if member (op =) ineq_ops t
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1070
          then fold_map_op (fold_map_binop poly poly) ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1071
          else raise CTERM ("arith_lemma", [ct])
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1072
      | _ => raise CTERM ("arith_lemma", [ct]))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1073
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1074
    fun conj ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1075
      (case Thm.term_of ct of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1076
        @{term "op &"} $ _ $ _ => fold_map_binop conj conj ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1077
      | @{term "~False"} => pair ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1078
      | _ => ineq ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1079
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1080
    fun disj ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1081
      (case Thm.term_of ct of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1082
        @{term "op |"} $ _ $ _ => fold_map_binop disj disj ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1083
      | @{term False} => pair ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1084
      | _ => conj ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1085
  in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1086
  fun prove_arith ctxt thms ct =
33529
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
  1087
    abstraction_context ctxt
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
  1088
    |> fold_map (fold_map_op ineq o Thm.cprop_of) thms
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
  1089
    ||>> fold_map_op disj ct
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
  1090
    |>> uncurry (fold_rev (Thm.mk_binop @{cterm "op ==>"}))
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
  1091
    |-> prove_abstraction (Arith_Data.arith_tac ctxt)
9fd3de94e6a2 generalized proof by abstraction,
boehmes
parents: 33519
diff changeset
  1092
    |> fold (fn th1 => fn th2 => Thm.implies_elim th2 th1) thms
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1093
  end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1094
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1095
fun arith_lemma ctxt thms ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1096
  let val thms' = map (Conv.fconv_rule (all_distrib_conv ctxt)) thms
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1097
  in with_conv (all_distrib_conv ctxt) (prove_arith ctxt thms') ct end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1098
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1099
33660
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1100
(** theory simpset **)
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1101
local
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1102
  val antisym_le1 = mk_meta_eq @{thm order_class.antisym_conv}
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1103
  val antisym_le2 = mk_meta_eq @{thm linorder_class.antisym_conv2}
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1104
  val antisym_less1 = mk_meta_eq @{thm linorder_class.antisym_conv1}
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1105
  val antisym_less2 = mk_meta_eq @{thm linorder_class.antisym_conv3}
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1106
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1107
  fun eq_prop t thm = HOLogic.mk_Trueprop t aconv Thm.prop_of thm
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
  1108
  fun dest_binop ((c as Const _) $ t $ u) = (c, t, u)
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
  1109
    | dest_binop t = raise TERM ("dest_binop", [t])
33660
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1110
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
  1111
  fun prove_antisym_le ss t =
33660
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1112
    let
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
  1113
      val (le, r, s) = dest_binop t
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
  1114
      val less = Const (@{const_name less}, Term.fastype_of le)
33660
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1115
      val prems = Simplifier.prems_of_ss ss
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1116
    in
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1117
      (case find_first (eq_prop (le $ s $ r)) prems of
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1118
        NONE =>
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1119
          find_first (eq_prop (HOLogic.mk_not (less $ r $ s))) prems
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1120
          |> Option.map (fn thm => thm RS antisym_less1)
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1121
      | SOME thm => SOME (thm RS antisym_le1))
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1122
    end
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1123
    handle THM _ => NONE
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1124
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
  1125
  fun prove_antisym_less ss t =
33660
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1126
    let
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
  1127
      val (less, r, s) = dest_binop (HOLogic.dest_not t)
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
  1128
      val le = Const (@{const_name less_eq}, Term.fastype_of less)
33660
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1129
      val prems = prems_of_ss ss
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1130
    in
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1131
      (case find_first (eq_prop (le $ r $ s)) prems of
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1132
        NONE =>
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1133
          find_first (eq_prop (HOLogic.mk_not (less $ s $ r))) prems
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1134
          |> Option.map (fn thm => thm RS antisym_less2)
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
  1135
      | SOME thm => SOME (thm RS antisym_le2))
33660
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1136
  end
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1137
  handle THM _ => NONE
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1138
in
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1139
val z3_simpset = HOL_ss addsimps @{thms array_rules}
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1140
  addsimps @{thms ring_distribs} addsimps @{thms field_eq_simps}
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1141
  addsimps @{thms arith_special} addsimps @{thms less_bin_simps}
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1142
  addsimps @{thms le_bin_simps} addsimps @{thms eq_bin_simps}
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1143
  addsimps @{thms add_bin_simps} addsimps @{thms succ_bin_simps}
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1144
  addsimps @{thms minus_bin_simps} addsimps @{thms pred_bin_simps}
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1145
  addsimps @{thms mult_bin_simps} addsimps @{thms iszero_simps}
35983
27e2fa7d4ce7 slightly more general simproc (avoids errors of linarith)
boehmes
parents: 35012
diff changeset
  1146
  addsimps [@{thm mult_1_left}]
33660
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1147
  addsimprocs [
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1148
    Simplifier.simproc @{theory} "fast_int_arith" [
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1149
      "(m::int) < n", "(m::int) <= n", "(m::int) = n"] (K Lin_Arith.simproc),
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1150
    Simplifier.simproc @{theory} "fast_real_arith" [
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1151
      "(m::real) < n", "(m::real) <= n", "(m::real) = n"]
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1152
      (K Lin_Arith.simproc),
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1153
    Simplifier.simproc @{theory} "antisym le" ["(x::'a::order) <= y"]
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1154
      (K prove_antisym_le),
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1155
    Simplifier.simproc @{theory} "antisym less" ["~ (x::'a::linorder) < y"]
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1156
      (K prove_antisym_less)]
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1157
end
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1158
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1159
(** theory lemmas: linear arithmetic, arrays **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1160
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1161
  val array_ss = HOL_ss addsimps @{thms array_rules}
34960
1d5ee19ef940 support skolem constant for extensional arrays in Z3 proofs
boehmes
parents: 33749
diff changeset
  1162
  val array_pre_ss = HOL_ss addsimps @{thms apply_def array_ext_def}
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1163
  fun array_tac thms =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1164
    Tactic.cut_facts_tac thms
34960
1d5ee19ef940 support skolem constant for extensional arrays in Z3 proofs
boehmes
parents: 33749
diff changeset
  1165
    THEN' (Simplifier.asm_full_simp_tac array_pre_ss)
1d5ee19ef940 support skolem constant for extensional arrays in Z3 proofs
boehmes
parents: 33749
diff changeset
  1166
    THEN' (SOLVED' (Simplifier.asm_full_simp_tac array_ss) ORELSE'
1d5ee19ef940 support skolem constant for extensional arrays in Z3 proofs
boehmes
parents: 33749
diff changeset
  1167
      Tactic.rtac @{thm someI2_ex}
1d5ee19ef940 support skolem constant for extensional arrays in Z3 proofs
boehmes
parents: 33749
diff changeset
  1168
      THEN_ALL_NEW (SOLVED' (Simplifier.asm_full_simp_tac array_ss) ORELSE'
1d5ee19ef940 support skolem constant for extensional arrays in Z3 proofs
boehmes
parents: 33749
diff changeset
  1169
        Classical.fast_tac HOL_cs))
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1170
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1171
  fun full_arith_tac ctxt thms =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1172
    Tactic.cut_facts_tac thms
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1173
    THEN' Arith_Data.arith_tac ctxt
33660
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1174
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1175
  fun simp_arith_tac ctxt thms =
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1176
    Tactic.cut_facts_tac thms
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1177
    THEN' Simplifier.asm_full_simp_tac z3_simpset
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1178
    THEN' Arith_Data.arith_tac ctxt
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1179
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1180
fun th_lemma ctxt thms ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1181
  Thm (try_apply ctxt "th-lemma" [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1182
    ("abstract arith", arith_lemma ctxt thms),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1183
    ("array", by_tac' (array_tac thms)),
33660
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1184
    ("full arith", by_tac' (full_arith_tac ctxt thms)),
11574d52169d extended theory simpset to simplify non-linear problems
boehmes
parents: 33529
diff changeset
  1185
    ("simp arith", by_tac' (simp_arith_tac ctxt thms))] (T.mk_prop ct))
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1186
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1187
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1188
(** rewriting: prove equalities:
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1189
      * ACI of conjunction/disjunction
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1190
      * contradiction, excluded middle
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1191
      * logical rewriting rules (for negation, implication, equivalence,
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1192
          distinct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1193
      * normal forms for polynoms (integer/real arithmetic)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1194
      * quantifier elimination over linear arithmetic
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1195
      * ... ? **)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1196
structure Z3_Rewrite_Rules =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1197
struct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1198
  val name = "z3_rewrite"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1199
  val descr = "Z3 rewrite rules used in proof reconstruction"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1200
33519
e31a85f92ce9 adapted Generic_Data, Proof_Data;
wenzelm
parents: 33418
diff changeset
  1201
  structure Data = Generic_Data
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1202
  (
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1203
    type T = thm Net.net
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1204
    val empty = Net.empty
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1205
    val extend = I
33519
e31a85f92ce9 adapted Generic_Data, Proof_Data;
wenzelm
parents: 33418
diff changeset
  1206
    val merge = Net.merge Thm.eq_thm_prop
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1207
  )
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1208
  val get = Data.get o Context.Proof
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1209
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1210
  val entry = ` Thm.prop_of o Simplifier.rewrite_rule [true_false]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1211
  val eq = Thm.eq_thm_prop
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1212
  val ins = Net.insert_term eq o entry and del = Net.delete_term eq o entry
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1213
  fun insert thm net = ins thm net handle Net.INSERT => net
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1214
  fun delete thm net = del thm net handle Net.DELETE => net
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1215
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1216
  val add = Thm.declaration_attribute (Data.map o insert)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1217
  val del = Thm.declaration_attribute (Data.map o delete)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1218
  val setup = Attrib.setup (Binding.name name) (Attrib.add_del add del) descr
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1219
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1220
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1221
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1222
  val contra_rule = @{lemma "P ==> ~P ==> False" by (rule notE)}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1223
  fun contra_left conj thm =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1224
    let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1225
      fun make_tab xs = fold Termtab.update xs Termtab.empty
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1226
      val tab = make_tab (explode_term conj true (prop_of thm))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1227
      fun pnlits (t, nrs) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1228
        (case t of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1229
          @{term Not} $ u => Termtab.lookup tab u |> Option.map (pair nrs)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1230
        | _ => NONE)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1231
    in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1232
      (case Termtab.lookup tab @{term False} of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1233
        SOME rs => extract_lit thm rs
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1234
      | NONE =>
35012
c3e3ac3ca091 removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents: 34960
diff changeset
  1235
          pairself (extract_lit thm) (the (Termtab.get_first pnlits tab))
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1236
          |> (fn (nlit, plit) => nlit COMP (plit COMP contra_rule)))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1237
    end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1238
  val falseE_v = Thm.dest_arg (Thm.dest_arg (Thm.cprop_of @{thm FalseE}))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1239
  fun contra_right ct = Thm.instantiate ([], [(falseE_v, ct)]) @{thm FalseE}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1240
  fun contradiction conj ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1241
    iff_intro (under_assumption (contra_left conj) ct) (contra_right ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1242
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1243
  fun conj_disj ct =
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 33010
diff changeset
  1244
    let val cp as (cl, cr) = Thm.dest_binop (Thm.dest_arg ct)
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1245
    in
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 33010
diff changeset
  1246
      (case Thm.term_of cr of
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 33010
diff changeset
  1247
        @{term False} => contradiction true cl
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 33010
diff changeset
  1248
      | @{term "~False"} => contrapos2 (contradiction false o fst) cp
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 33010
diff changeset
  1249
      | _ => prove_conj_disj_eq (Thm.dest_arg ct))
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1250
    end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1251
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1252
  val distinct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1253
    let val try_unfold = Conv.try_conv unfold_distinct_conv
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1254
    in with_conv (Conv.arg_conv (Conv.binop_conv try_unfold)) conj_disj end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1255
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1256
  val nnf_neg_rule = @{lemma "~~P == P" by fastsimp}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1257
  val nnf_cd_rules = @{lemma "~(P | Q) == ~P & ~Q" "~(P & Q) == ~P | ~Q"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1258
    by fastsimp+}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1259
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1260
  fun nnf_conv ct = Conv.try_conv (
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1261
    (Conv.rewr_conv nnf_neg_rule then_conv nnf_conv) else_conv
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1262
    (More_Conv.rewrs_conv nnf_cd_rules then_conv Conv.binop_conv nnf_conv)) ct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1263
  val iffI_rule = @{lemma "~P | Q ==> ~Q | P ==> P = Q" by fast}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1264
  fun arith_tac ctxt = CSUBGOAL (fn (goal, i) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1265
    let val prep_then = with_conv (Conv.arg_conv (Conv.binop_conv nnf_conv))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1266
    in Tactic.rtac (prep_then (arith_lemma ctxt []) goal) i end)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1267
  fun arith_eq_tac ctxt =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1268
    Tactic.rtac iffI_rule THEN_ALL_NEW arith_tac ctxt
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1269
    ORELSE' arith_tac ctxt
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1270
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
  1271
  fun simp_tac thms = CHANGED o Simplifier.simp_tac (z3_simpset addsimps thms)
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1272
    ORELSE' Classical.best_tac HOL_cs
34960
1d5ee19ef940 support skolem constant for extensional arrays in Z3 proofs
boehmes
parents: 33749
diff changeset
  1273
  fun simp_arith_tac ctxt thms = Simplifier.simp_tac (z3_simpset addsimps thms)
1d5ee19ef940 support skolem constant for extensional arrays in Z3 proofs
boehmes
parents: 33749
diff changeset
  1274
    THEN_ALL_NEW Arith_Data.arith_tac ctxt
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1275
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1276
fun rewrite ctxt thms ct =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1277
  let val rules_net = Z3_Rewrite_Rules.get ctxt
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1278
  in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1279
    Thm (try_apply ctxt "rewrite" [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1280
      ("schematic rule", the o net_instance rules_net),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1281
      ("conj/disj", conj_disj),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1282
      ("distinct", distinct),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1283
      ("arith", by_tac' (arith_eq_tac ctxt)),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1284
      ("classical", by_tac' (Classical.best_tac HOL_cs)),
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33660
diff changeset
  1285
      ("simp", by_tac' (simp_tac thms)),
34960
1d5ee19ef940 support skolem constant for extensional arrays in Z3 proofs
boehmes
parents: 33749
diff changeset
  1286
      ("simp+arith", by_tac' (simp_arith_tac ctxt thms)),
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1287
      ("full arith", by_tac' (Arith_Data.arith_tac ctxt))] (T.mk_prop ct))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1288
  end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1289
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1290
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1291
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1292
(* tracing and debugging *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1293
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1294
fun check idx r ct ((_, p), _) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1295
  let val thm = thm_of p |> tap (Thm.join_proofs o single)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1296
  in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1297
    if (Thm.cprop_of thm) aconvc (T.mk_prop ct) then ()
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1298
    else z3_exn ("proof step failed: " ^ quote (string_of_rule r) ^
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1299
      " (#" ^ string_of_int idx ^ ")")
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1300
  end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1301
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1302
local
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1303
  fun trace_before ctxt idx (r, ps, ct) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1304
    Pretty.string_of (
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1305
      Pretty.big_list ("#" ^ string_of_int idx ^ ": " ^ string_of_rule r) [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1306
        Pretty.big_list "assumptions:"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1307
          (map (Display.pretty_thm ctxt o thm_of o fst) ps),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1308
        Pretty.block [Pretty.str "goal: ",
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1309
          Syntax.pretty_term ctxt (Thm.term_of ct)]])
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1310
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1311
  fun trace_after ctxt ((_, p), _) = Pretty.string_of (Pretty.block
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1312
    [Pretty.str "result: ", Display.pretty_thm ctxt (thm_of p)])
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1313
in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1314
fun trace_rule ctxt idx prove r ps ct ptab =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1315
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1316
    val _ = SMT_Solver.trace_msg ctxt (trace_before ctxt idx) (r, ps, ct)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1317
    val result = prove r ps ct ptab
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1318
    val _ = SMT_Solver.trace_msg ctxt (trace_after ctxt) result
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1319
  in result end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1320
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1321
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1322
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1323
(* overall reconstruction procedure *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1324
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1325
fun not_supported r =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1326
  z3_exn ("proof rule not implemented: " ^ quote (string_of_rule r))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1327
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1328
fun prove ctxt assms =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1329
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1330
    val prems = Option.map (prepare_assms ctxt) assms
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1331
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1332
    fun step r ps ct ptab =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1333
      (case (r, ps) of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1334
        (* core rules *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1335
        (TrueAxiom, _) => (([], Thm true_thm), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1336
      | (Asserted, _) => (([], asserted ctxt prems ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1337
      | (Goal, _) => (([], asserted ctxt prems ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1338
      | (ModusPonens, [(p, _), (q, _)]) => (([], mp q (thm_of p)), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1339
      | (ModusPonensOeq, [(p, _), (q, _)]) => (([], mp q (thm_of p)), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1340
      | (AndElim, [(p, (_, i))]) => apfst (pair []) (and_elim (p, i) ct ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1341
      | (NotOrElim, [(p, (_, i))]) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1342
          apfst (pair []) (not_or_elim (p, i) ct ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1343
      | (Hypothesis, _) => (([], Thm (Thm.assume (T.mk_prop ct))), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1344
      | (Lemma, [(p, _)]) => (([], lemma (thm_of p) ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1345
      | (UnitResolution, (p, _) :: ps) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1346
          (([], unit_resolution (thm_of p) (map (thm_of o fst) ps) ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1347
      | (IffTrue, [(p, _)]) => (([], iff_true (thm_of p)), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1348
      | (IffFalse, [(p, _)]) => (([], iff_false (thm_of p)), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1349
      | (Distributivity, _) => (([], distributivity ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1350
      | (DefAxiom, _) => (([], def_axiom ctxt ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1351
      | (IntroDef, _) => (intro_def ct, ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1352
      | (ApplyDef, [(p, _)]) => (([], apply_def (thm_of p)), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1353
      | (IffOeq, [(p, _)]) => (([], p), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1354
      | (NnfPos, _) => (([], nnf ctxt ps ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1355
      | (NnfNeg, _) => (([], nnf ctxt ps ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1356
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1357
        (* equality rules *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1358
      | (Reflexivity, _) => (([], refl ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1359
      | (Symmetry, [(p, _)]) => (([], symm p), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1360
      | (Transitivity, [(p, _), (q, _)]) => (([], trans p q), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1361
      | (Monotonicity, _) => (([], monotonicity (map fst ps) ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1362
      | (Commutativity, _) => (([], commutativity ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1363
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1364
        (* quantifier rules *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1365
      | (QuantIntro, [p]) => (([], quant_intro ctxt p ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1366
      | (PullQuant, _) => (([], pull_quant ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1367
      | (PushQuant, _) => (([], push_quant ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1368
      | (ElimUnusedVars, _) => (([], elim_unused_vars ctxt ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1369
      | (DestEqRes, _) => (([], dest_eq_res ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1370
      | (QuantInst, _) => (([], quant_inst ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1371
      | (Skolemize, _) => (skolemize ctxt ct, ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1372
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1373
        (* theory rules *)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1374
      | (ThLemma, _) => (([], th_lemma ctxt (map (thm_of o fst) ps) ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1375
      | (Rewrite, _) => (([], rewrite ctxt [] ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1376
      | (RewriteStar, ps) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1377
          (([], rewrite ctxt (map (thm_of o fst) ps) ct), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1378
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1379
      | (NnfStar, _) => not_supported r
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1380
      | (CnfStar, _) => not_supported r
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1381
      | (TransitivityStar, _) => not_supported r
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1382
      | (PullQuantStar, _) => not_supported r
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1383
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1384
      | _ => z3_exn ("Proof rule " ^ quote (string_of_rule r) ^
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1385
         " has an unexpected number of arguments."))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1386
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1387
    fun eq_hyp (ct, cu) = Thm.dest_arg1 ct aconvc Thm.dest_arg1 cu
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1388
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1389
    fun conclude idx rule prop ((hypss, ps), ptab) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1390
      trace_rule ctxt idx step rule ps prop ptab
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1391
      |> Config.get ctxt SMT_Solver.trace ? tap (check idx rule prop)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1392
      |>> apfst (distinct eq_hyp o fold append hypss)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1393
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1394
    fun add_sequent idx vars (hyps, thm) ptab =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1395
      let val s = Sequent {hyps=hyps, vars=vars, thm=thm}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1396
      in ((hyps, (thm, vars)), Inttab.update (idx, s) ptab) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1397
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1398
    fun lookup idx ptab =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1399
      (case Inttab.lookup ptab idx of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1400
        SOME (Unproved {rule, subs, vars, prop}) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1401
          fold_map lookup subs ptab
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1402
          |>> split_list
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1403
          |>> apsnd (map2 (fn idx => fn (p, vs) => (p, (vs, idx))) subs)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1404
          |> conclude idx rule prop
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1405
          |-> add_sequent idx vars
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1406
      | SOME (Sequent {hyps, vars, thm}) => ((hyps, (thm, vars)), ptab)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1407
      | NONE => z3_exn ("unknown proof id: " ^ quote (string_of_int idx)))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1408
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1409
    fun result (hyps, (thm, _)) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1410
      fold SMT_Normalize.discharge_definition hyps (thm_of thm)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1411
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1412
  in (fn ptab => fn idx => result (fst (lookup idx ptab))) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1413
33749
8aab63a91053 optionally trace theorems used in proof reconstruction
boehmes
parents: 33664
diff changeset
  1414
val setup = trace_assms_setup #> Z3_Rewrite_Rules.setup
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1415
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
  1416
end