src/HOL/Tools/SMT/z3_proof_reconstruction.ML
author boehmes
Wed, 12 May 2010 23:54:02 +0200
changeset 36898 8e55aa1306c5
child 36899 bcd6fce5bf06
permissions -rw-r--r--
integrated SMT into the HOL image
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36898
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
     1
(*  Title:      HOL/Tools/SMT/z3_proof_reconstruction.ML
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
     2
    Author:     Sascha Boehme, TU Muenchen
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
     3
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
     4
Proof reconstruction for proofs found by Z3.
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
     5
*)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
     6
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
     7
signature Z3_PROOF_RECONSTRUCTION =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
     8
sig
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
     9
  val trace_assms: bool Config.T
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    10
  val reconstruct: string list * SMT_Translate.recon -> Proof.context ->
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    11
    thm * Proof.context
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    12
  val setup: theory -> theory
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    13
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    14
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    15
structure Z3_Proof_Reconstruction: Z3_PROOF_RECONSTRUCTION =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    16
struct
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    17
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    18
structure P = Z3_Proof_Parser
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    19
structure T = Z3_Proof_Tools
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    20
structure L = Z3_Proof_Literals
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    21
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    22
fun z3_exn msg = raise SMT_Solver.SMT ("Z3 proof reconstruction: " ^ msg)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    23
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    24
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    25
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    26
(** net of schematic rules **)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    27
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    28
val z3_ruleN = "z3_rule"
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    29
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    30
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    31
  val description = "declaration of Z3 proof rules"
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    32
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    33
  val eq = Thm.eq_thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    34
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    35
  structure Z3_Rules = Generic_Data
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    36
  (
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    37
    type T = thm Net.net
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    38
    val empty = Net.empty
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    39
    val extend = I
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    40
    val merge = Net.merge eq
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    41
  )
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    42
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    43
  val prep = `Thm.prop_of o Simplifier.rewrite_rule [L.rewrite_true]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    44
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    45
  fun ins thm net = Net.insert_term eq (prep thm) net handle Net.INSERT => net
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    46
  fun del thm net = Net.delete_term eq (prep thm) net handle Net.DELETE => net
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    47
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    48
  val add = Thm.declaration_attribute (Z3_Rules.map o ins)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    49
  val del = Thm.declaration_attribute (Z3_Rules.map o del)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    50
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    51
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    52
fun get_schematic_rules ctxt = Net.content (Z3_Rules.get (Context.Proof ctxt))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    53
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    54
fun by_schematic_rule ctxt ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    55
  the (T.net_instance (Z3_Rules.get (Context.Proof ctxt)) ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    56
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    57
val z3_rules_setup =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    58
  Attrib.setup (Binding.name z3_ruleN) (Attrib.add_del add del) description #>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    59
  PureThy.add_thms_dynamic (Binding.name z3_ruleN, Net.content o Z3_Rules.get)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    60
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    61
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    62
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    63
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    64
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    65
(** proof tools **)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    66
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    67
fun named ctxt name prover ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    68
  let val _ = SMT_Solver.trace_msg ctxt I ("Z3: trying " ^ name ^ " ...")
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    69
  in prover ct end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    70
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    71
fun NAMED ctxt name tac i st =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    72
  let val _ = SMT_Solver.trace_msg ctxt I ("Z3: trying " ^ name ^ " ...")
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    73
  in tac i st end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    74
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    75
fun pretty_goal ctxt thms t =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    76
  [Pretty.block [Pretty.str "proposition: ", Syntax.pretty_term ctxt t]]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    77
  |> not (null thms) ? cons (Pretty.big_list "assumptions:"
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    78
       (map (Display.pretty_thm ctxt) thms))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    79
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    80
fun try_apply ctxt thms =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    81
  let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    82
    fun try_apply_err ct = Pretty.string_of (Pretty.chunks [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    83
      Pretty.big_list ("Z3 found a proof," ^
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    84
        " but proof reconstruction failed at the following subgoal:")
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    85
        (pretty_goal ctxt thms (Thm.term_of ct)),
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    86
      Pretty.str ("Adding a rule to the lemma group " ^ quote z3_ruleN ^
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    87
        " might solve this problem.")])
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    88
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    89
    fun apply [] ct = error (try_apply_err ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    90
      | apply (prover :: provers) ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    91
          (case try prover ct of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    92
            SOME thm => (SMT_Solver.trace_msg ctxt I "Z3: succeeded"; thm)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    93
          | NONE => apply provers ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    94
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    95
  in apply o cons (named ctxt "schematic rules" (by_schematic_rule ctxt)) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    96
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    97
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    98
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
    99
(** theorems and proofs **)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   100
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   101
(* theorem incarnations *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   102
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   103
datatype theorem =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   104
  Thm of thm | (* theorem without special features *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   105
  MetaEq of thm | (* meta equality "t == s" *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   106
  Literals of thm * L.littab
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   107
    (* "P1 & ... & Pn" and table of all literals P1, ..., Pn *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   108
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   109
fun thm_of (Thm thm) = thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   110
  | thm_of (MetaEq thm) = thm COMP @{thm meta_eq_to_obj_eq}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   111
  | thm_of (Literals (thm, _)) = thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   112
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   113
fun meta_eq_of (MetaEq thm) = thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   114
  | meta_eq_of p = mk_meta_eq (thm_of p)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   115
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   116
fun literals_of (Literals (_, lits)) = lits
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   117
  | literals_of p = L.make_littab [thm_of p]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   118
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   119
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   120
(* proof representation *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   121
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   122
datatype proof = Unproved of P.proof_step | Proved of theorem
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   123
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   124
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   125
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   126
(** core proof rules **)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   127
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   128
(* assumption *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   129
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   130
val (trace_assms, trace_assms_setup) =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   131
  Attrib.config_bool "z3_trace_assms" (K false)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   132
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   133
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   134
  val remove_trigger = @{lemma "trigger t p == p"
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   135
    by (rule eq_reflection, rule trigger_def)}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   136
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   137
  val prep_rules = [@{thm Let_def}, remove_trigger, L.rewrite_true]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   138
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   139
  fun rewrite_conv ctxt eqs = Simplifier.full_rewrite
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   140
    (Simplifier.context ctxt Simplifier.empty_ss addsimps eqs)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   141
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   142
  fun rewrites ctxt eqs = map (Conv.fconv_rule (rewrite_conv ctxt eqs))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   143
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   144
  fun trace ctxt thm =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   145
    if Config.get ctxt trace_assms
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   146
    then tracing (Display.string_of_thm ctxt thm)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   147
    else ()
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   148
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   149
  fun lookup_assm ctxt assms ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   150
    (case T.net_instance assms ct of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   151
      SOME thm => (trace ctxt thm; thm)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   152
    | _ => z3_exn ("not asserted: " ^
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   153
        quote (Syntax.string_of_term ctxt (Thm.term_of ct))))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   154
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   155
fun prepare_assms ctxt unfolds assms =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   156
  let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   157
    val unfolds' = rewrites ctxt [L.rewrite_true] unfolds
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   158
    val assms' = rewrites ctxt (union Thm.eq_thm unfolds' prep_rules) assms
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   159
  in (unfolds', T.thm_net_of assms') end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   160
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   161
fun asserted _ NONE ct = Thm (Thm.assume ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   162
  | asserted ctxt (SOME (unfolds, assms)) ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   163
      let val revert_conv = rewrite_conv ctxt unfolds
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   164
      in Thm (T.with_conv revert_conv (lookup_assm ctxt assms) ct) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   165
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   166
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   167
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   168
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   169
(* P = Q ==> P ==> Q   or   P --> Q ==> P ==> Q *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   170
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   171
  val meta_iffD1 = @{lemma "P == Q ==> P ==> (Q::bool)" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   172
  val meta_iffD1_c = T.precompose2 Thm.dest_binop meta_iffD1
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   173
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   174
  val iffD1_c = T.precompose2 (Thm.dest_binop o Thm.dest_arg) @{thm iffD1}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   175
  val mp_c = T.precompose2 (Thm.dest_binop o Thm.dest_arg) @{thm mp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   176
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   177
fun mp (MetaEq thm) p = Thm (Thm.implies_elim (T.compose meta_iffD1_c thm) p)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   178
  | mp p_q p = 
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   179
      let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   180
        val pq = thm_of p_q
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   181
        val thm = T.compose iffD1_c pq handle THM _ => T.compose mp_c pq
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   182
      in Thm (Thm.implies_elim thm p) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   183
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   184
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   185
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   186
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   187
(* and_elim:     P1 & ... & Pn ==> Pi *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   188
(* not_or_elim:  ~(P1 | ... | Pn) ==> ~Pi *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   189
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   190
  fun is_sublit conj t = L.exists_lit conj (fn u => u aconv t)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   191
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   192
  fun derive conj t lits idx ptab =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   193
    let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   194
      val lit = the (L.get_first_lit (is_sublit conj t) lits)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   195
      val ls = L.explode conj false false [t] lit
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   196
      val lits' = fold L.insert_lit ls (L.delete_lit lit lits)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   197
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   198
      fun upd (Proved thm) = Proved (Literals (thm_of thm, lits'))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   199
        | upd p = p
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   200
    in (the (L.lookup_lit lits' t), Inttab.map_entry idx upd ptab) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   201
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   202
  fun lit_elim conj (p, idx) ct ptab =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   203
    let val lits = literals_of p
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   204
    in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   205
      (case L.lookup_lit lits (T.term_of ct) of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   206
        SOME lit => (Thm lit, ptab)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   207
      | NONE => apfst Thm (derive conj (T.term_of ct) lits idx ptab))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   208
    end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   209
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   210
val and_elim = lit_elim true
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   211
val not_or_elim = lit_elim false
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   212
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   213
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   214
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   215
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   216
(* P1, ..., Pn |- False ==> |- ~P1 | ... | ~Pn *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   217
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   218
  fun step lit thm =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   219
    Thm.implies_elim (Thm.implies_intr (Thm.cprop_of lit) thm) lit
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   220
  val explode_disj = L.explode false false false
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   221
  fun intro hyps thm th = fold step (explode_disj hyps th) thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   222
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   223
  fun dest_ccontr ct = [Thm.dest_arg (Thm.dest_arg (Thm.dest_arg1 ct))]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   224
  val ccontr = T.precompose dest_ccontr @{thm ccontr}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   225
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   226
fun lemma thm ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   227
  let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   228
    val cu = Thm.capply @{cterm Not} (Thm.dest_arg ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   229
    val hyps = map_filter (try HOLogic.dest_Trueprop) (#hyps (Thm.rep_thm thm))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   230
  in Thm (T.compose ccontr (T.under_assumption (intro hyps thm) cu)) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   231
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   232
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   233
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   234
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   235
(* \/{P1, ..., Pn, Q1, ..., Qn}, ~P1, ..., ~Pn ==> \/{Q1, ..., Qn} *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   236
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   237
  val explode_disj = L.explode false true false
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   238
  val join_disj = L.join false
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   239
  fun unit thm thms th =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   240
    let val t = @{term Not} $ T.prop_of thm and ts = map T.prop_of thms
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   241
    in join_disj (L.make_littab (thms @ explode_disj ts th)) t end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   242
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   243
  fun dest_arg2 ct = Thm.dest_arg (Thm.dest_arg ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   244
  fun dest ct = pairself dest_arg2 (Thm.dest_binop ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   245
  val contrapos = T.precompose2 dest @{lemma "(~P ==> ~Q) ==> Q ==> P" by fast}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   246
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   247
fun unit_resolution thm thms ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   248
  Thm.capply @{cterm Not} (Thm.dest_arg ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   249
  |> T.under_assumption (unit thm thms)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   250
  |> Thm o T.discharge thm o T.compose contrapos
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   251
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   252
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   253
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   254
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   255
(* P ==> P == True   or   P ==> P == False *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   256
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   257
  val iff1 = @{lemma "P ==> P == (~ False)" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   258
  val iff2 = @{lemma "~P ==> P == False" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   259
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   260
fun iff_true thm = MetaEq (thm COMP iff1)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   261
fun iff_false thm = MetaEq (thm COMP iff2)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   262
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   263
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   264
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   265
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   266
(* distributivity of | over & *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   267
fun distributivity ctxt = Thm o try_apply ctxt [] [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   268
  named ctxt "fast" (T.by_tac (Classical.best_tac HOL_cs))]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   269
    (* FIXME: not very well tested *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   270
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   271
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   272
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   273
(* Tseitin-like axioms *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   274
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   275
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   276
  val disjI1 = @{lemma "(P ==> Q) ==> ~P | Q" by fast}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   277
  val disjI2 = @{lemma "(~P ==> Q) ==> P | Q" by fast}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   278
  val disjI3 = @{lemma "(~Q ==> P) ==> P | Q" by fast}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   279
  val disjI4 = @{lemma "(Q ==> P) ==> P | ~Q" by fast}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   280
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   281
  fun prove' conj1 conj2 ct2 thm =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   282
    let val lits = L.true_thm :: L.explode conj1 true (conj1 <> conj2) [] thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   283
    in L.join conj2 (L.make_littab lits) (Thm.term_of ct2) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   284
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   285
  fun prove rule (ct1, conj1) (ct2, conj2) =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   286
    T.under_assumption (prove' conj1 conj2 ct2) ct1 COMP rule
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   287
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   288
  fun prove_def_axiom ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   289
    let val (ct1, ct2) = Thm.dest_binop (Thm.dest_arg ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   290
    in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   291
      (case Thm.term_of ct1 of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   292
        @{term Not} $ (@{term "op &"} $ _ $ _) =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   293
          prove disjI1 (Thm.dest_arg ct1, true) (ct2, true)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   294
      | @{term "op &"} $ _ $ _ =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   295
          prove disjI3 (Thm.capply @{cterm Not} ct2, false) (ct1, true)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   296
      | @{term Not} $ (@{term "op |"} $ _ $ _) =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   297
          prove disjI3 (Thm.capply @{cterm Not} ct2, false) (ct1, false)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   298
      | @{term "op |"} $ _ $ _ =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   299
          prove disjI2 (Thm.capply @{cterm Not} ct1, false) (ct2, true)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   300
      | Const (@{const_name distinct}, _) $ _ =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   301
          let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   302
            fun dis_conv cv = Conv.arg_conv (Conv.arg1_conv cv)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   303
            fun prv cu =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   304
              let val (cu1, cu2) = Thm.dest_binop (Thm.dest_arg cu)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   305
              in prove disjI4 (Thm.dest_arg cu2, true) (cu1, true) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   306
          in T.with_conv (dis_conv T.unfold_distinct_conv) prv ct end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   307
      | @{term Not} $ (Const (@{const_name distinct}, _) $ _) =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   308
          let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   309
            fun dis_conv cv = Conv.arg_conv (Conv.arg1_conv (Conv.arg_conv cv))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   310
            fun prv cu =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   311
              let val (cu1, cu2) = Thm.dest_binop (Thm.dest_arg cu)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   312
              in prove disjI1 (Thm.dest_arg cu1, true) (cu2, true) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   313
          in T.with_conv (dis_conv T.unfold_distinct_conv) prv ct end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   314
      | _ => raise CTERM ("prove_def_axiom", [ct]))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   315
    end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   316
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   317
  val rewr_if =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   318
    @{lemma "(if P then Q1 else Q2) = ((P --> Q1) & (~P --> Q2))" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   319
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   320
fun def_axiom ctxt = Thm o try_apply ctxt [] [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   321
  named ctxt "conj/disj/distinct" prove_def_axiom,
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   322
  T.by_abstraction ctxt [] (fn ctxt' =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   323
    named ctxt' "simp+fast" (T.by_tac (
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   324
      Simplifier.simp_tac (HOL_ss addsimps [rewr_if])
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   325
      THEN_ALL_NEW Classical.best_tac HOL_cs)))]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   326
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   327
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   328
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   329
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   330
(* local definitions *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   331
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   332
  val intro_rules = [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   333
    @{lemma "n == P ==> (~n | P) & (n | ~P)" by simp},
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   334
    @{lemma "n == (if P then s else t) ==> (~P | n = s) & (P | n = t)"
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   335
      by simp},
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   336
    @{lemma "n == P ==> n = P" by (rule meta_eq_to_obj_eq)} ]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   337
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   338
  val apply_rules = [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   339
    @{lemma "(~n | P) & (n | ~P) ==> P == n" by (atomize(full)) fast},
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   340
    @{lemma "(~P | n = s) & (P | n = t) ==> (if P then s else t) == n"
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   341
      by (atomize(full)) fastsimp} ]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   342
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   343
  val inst_rule = T.match_instantiate Thm.dest_arg
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   344
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   345
  fun apply_rule ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   346
    (case get_first (try (inst_rule ct)) intro_rules of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   347
      SOME thm => thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   348
    | NONE => raise CTERM ("intro_def", [ct]))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   349
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   350
fun intro_def ct = T.make_hyp_def (apply_rule ct) #>> Thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   351
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   352
fun apply_def thm =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   353
  get_first (try (fn rule => MetaEq (thm COMP rule))) apply_rules
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   354
  |> the_default (Thm thm)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   355
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   356
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   357
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   358
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   359
(* negation normal form *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   360
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   361
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   362
  val quant_rules1 = ([
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   363
    @{lemma "(!!x. P x == Q) ==> ALL x. P x == Q" by simp},
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   364
    @{lemma "(!!x. P x == Q) ==> EX x. P x == Q" by simp}], [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   365
    @{lemma "(!!x. P x == Q x) ==> ALL x. P x == ALL x. Q x" by simp},
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   366
    @{lemma "(!!x. P x == Q x) ==> EX x. P x == EX x. Q x" by simp}])
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   367
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   368
  val quant_rules2 = ([
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   369
    @{lemma "(!!x. ~P x == Q) ==> ~(ALL x. P x) == Q" by simp},
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   370
    @{lemma "(!!x. ~P x == Q) ==> ~(EX x. P x) == Q" by simp}], [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   371
    @{lemma "(!!x. ~P x == Q x) ==> ~(ALL x. P x) == EX x. Q x" by simp},
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   372
    @{lemma "(!!x. ~P x == Q x) ==> ~(EX x. P x) == ALL x. Q x" by simp}])
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   373
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   374
  fun nnf_quant_tac thm (qs as (qs1, qs2)) i st = (
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   375
    Tactic.rtac thm ORELSE'
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   376
    (Tactic.match_tac qs1 THEN' nnf_quant_tac thm qs) ORELSE'
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   377
    (Tactic.match_tac qs2 THEN' nnf_quant_tac thm qs)) i st
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   378
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   379
  fun nnf_quant vars qs p ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   380
    T.as_meta_eq ct
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   381
    |> T.by_tac (nnf_quant_tac (T.varify vars (meta_eq_of p)) qs)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   382
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   383
  fun prove_nnf ctxt = try_apply ctxt [] [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   384
    named ctxt "conj/disj" L.prove_conj_disj_eq]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   385
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   386
fun nnf ctxt vars ps ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   387
  (case T.term_of ct of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   388
    _ $ (l as Const _ $ Abs _) $ (r as Const _ $ Abs _) =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   389
      if l aconv r
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   390
      then MetaEq (Thm.reflexive (Thm.dest_arg (Thm.dest_arg ct)))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   391
      else MetaEq (nnf_quant vars quant_rules1 (hd ps) ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   392
  | _ $ (@{term Not} $ (Const _ $ Abs _)) $ (Const _ $ Abs _) =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   393
      MetaEq (nnf_quant vars quant_rules2 (hd ps) ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   394
  | _ =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   395
      let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   396
        val nnf_rewr_conv = Conv.arg_conv (Conv.arg_conv
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   397
          (T.unfold_eqs ctxt (map (Thm.symmetric o meta_eq_of) ps)))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   398
      in Thm (T.with_conv nnf_rewr_conv (prove_nnf ctxt) ct) end)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   399
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   400
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   401
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   402
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   403
(** equality proof rules **)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   404
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   405
(* |- t = t *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   406
fun refl ct = MetaEq (Thm.reflexive (Thm.dest_arg (Thm.dest_arg ct)))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   407
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   408
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   409
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   410
(* s = t ==> t = s *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   411
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   412
  val symm_rule = @{lemma "s = t ==> t == s" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   413
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   414
fun symm (MetaEq thm) = MetaEq (Thm.symmetric thm)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   415
  | symm p = MetaEq (thm_of p COMP symm_rule)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   416
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   417
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   418
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   419
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   420
(* s = t ==> t = u ==> s = u *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   421
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   422
  val trans1 = @{lemma "s == t ==> t =  u ==> s == u" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   423
  val trans2 = @{lemma "s =  t ==> t == u ==> s == u" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   424
  val trans3 = @{lemma "s =  t ==> t =  u ==> s == u" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   425
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   426
fun trans (MetaEq thm1) (MetaEq thm2) = MetaEq (Thm.transitive thm1 thm2)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   427
  | trans (MetaEq thm) q = MetaEq (thm_of q COMP (thm COMP trans1))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   428
  | trans p (MetaEq thm) = MetaEq (thm COMP (thm_of p COMP trans2))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   429
  | trans p q = MetaEq (thm_of q COMP (thm_of p COMP trans3))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   430
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   431
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   432
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   433
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   434
(* t1 = s1 ==> ... ==> tn = sn ==> f t1 ... tn = f s1 .. sn
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   435
   (reflexive antecendents are droppped) *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   436
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   437
  exception MONO
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   438
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   439
  fun prove_refl (ct, _) = Thm.reflexive ct
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   440
  fun prove_comb f g cp =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   441
    let val ((ct1, ct2), (cu1, cu2)) = pairself Thm.dest_comb cp
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   442
    in Thm.combination (f (ct1, cu1)) (g (ct2, cu2)) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   443
  fun prove_arg f = prove_comb prove_refl f
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   444
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   445
  fun prove f cp = prove_comb (prove f) f cp handle CTERM _ => prove_refl cp
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   446
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   447
  fun prove_nary is_comb f =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   448
    let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   449
      fun prove (cp as (ct, _)) = f cp handle MONO =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   450
        if is_comb (Thm.term_of ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   451
        then prove_comb (prove_arg prove) prove cp
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   452
        else prove_refl cp
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   453
    in prove end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   454
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   455
  fun prove_list f n cp =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   456
    if n = 0 then prove_refl cp
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   457
    else prove_comb (prove_arg f) (prove_list f (n-1)) cp
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   458
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   459
  fun with_length f (cp as (cl, _)) =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   460
    f (length (HOLogic.dest_list (Thm.term_of cl))) cp
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   461
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   462
  fun prove_distinct f = prove_arg (with_length (prove_list f))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   463
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   464
  fun prove_eq exn lookup cp =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   465
    (case lookup (Logic.mk_equals (pairself Thm.term_of cp)) of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   466
      SOME eq => eq
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   467
    | NONE => if exn then raise MONO else prove_refl cp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   468
  
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   469
  val prove_eq_exn = prove_eq true
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   470
  and prove_eq_safe = prove_eq false
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   471
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   472
  fun mono f (cp as (cl, _)) =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   473
    (case Term.head_of (Thm.term_of cl) of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   474
      @{term "op &"} => prove_nary L.is_conj (prove_eq_exn f)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   475
    | @{term "op |"} => prove_nary L.is_disj (prove_eq_exn f)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   476
    | Const (@{const_name distinct}, _) => prove_distinct (prove_eq_safe f)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   477
    | _ => prove (prove_eq_safe f)) cp
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   478
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   479
fun monotonicity eqs ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   480
  let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   481
    val lookup = AList.lookup (op aconv) (map (`Thm.prop_of o meta_eq_of) eqs)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   482
    val cp = Thm.dest_binop (Thm.dest_arg ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   483
  in MetaEq (prove_eq_exn lookup cp handle MONO => mono lookup cp) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   484
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   485
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   486
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   487
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   488
(* |- f a b = f b a (where f is equality) *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   489
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   490
  val rule = @{lemma "a = b == b = a" by (atomize(full)) (rule eq_commute)}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   491
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   492
fun commutativity ct = MetaEq (T.match_instantiate I (T.as_meta_eq ct) rule)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   493
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   494
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   495
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   496
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   497
(** quantifier proof rules **)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   498
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   499
(* P ?x = Q ?x ==> (ALL x. P x) = (ALL x. Q x)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   500
   P ?x = Q ?x ==> (EX x. P x) = (EX x. Q x)    *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   501
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   502
  val rules = [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   503
    @{lemma "(!!x. P x == Q x) ==> (ALL x. P x) == (ALL x. Q x)" by simp},
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   504
    @{lemma "(!!x. P x == Q x) ==> (EX x. P x) == (EX x. Q x)" by simp}]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   505
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   506
fun quant_intro vars p ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   507
  let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   508
    val thm = meta_eq_of p
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   509
    val rules' = T.varify vars thm :: rules
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   510
    val cu = T.as_meta_eq ct
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   511
  in MetaEq (T.by_tac (REPEAT_ALL_NEW (Tactic.match_tac rules')) cu) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   512
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   513
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   514
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   515
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   516
(* |- ((ALL x. P x) | Q) = (ALL x. P x | Q) *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   517
fun pull_quant ctxt = Thm o try_apply ctxt [] [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   518
  named ctxt "fast" (T.by_tac (Classical.fast_tac HOL_cs))]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   519
    (* FIXME: not very well tested *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   520
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   521
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   522
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   523
(* |- (ALL x. P x & Q x) = ((ALL x. P x) & (ALL x. Q x)) *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   524
fun push_quant ctxt = Thm o try_apply ctxt [] [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   525
  named ctxt "fast" (T.by_tac (Classical.fast_tac HOL_cs))]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   526
    (* FIXME: not very well tested *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   527
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   528
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   529
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   530
(* |- (ALL x1 ... xn y1 ... yn. P x1 ... xn) = (ALL x1 ... xn. P x1 ... xn) *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   531
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   532
  val elim_all = @{lemma "(ALL x. P) == P" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   533
  val elim_ex = @{lemma "(EX x. P) == P" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   534
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   535
  fun elim_unused_conv ctxt =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   536
    Conv.params_conv ~1 (K (Conv.arg_conv (Conv.arg1_conv
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   537
      (More_Conv.rewrs_conv [elim_all, elim_ex])))) ctxt
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   538
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   539
  fun elim_unused_tac ctxt =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   540
    REPEAT_ALL_NEW (
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   541
      Tactic.match_tac [@{thm refl}, @{thm iff_allI}, @{thm iff_exI}]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   542
      ORELSE' CONVERSION (elim_unused_conv ctxt))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   543
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   544
fun elim_unused_vars ctxt = Thm o T.by_tac (elim_unused_tac ctxt)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   545
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   546
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   547
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   548
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   549
(* |- (ALL x1 ... xn. ~(x1 = t1 & ... xn = tn) | P x1 ... xn) = P t1 ... tn *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   550
fun dest_eq_res ctxt = Thm o try_apply ctxt [] [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   551
  named ctxt "fast" (T.by_tac (Classical.fast_tac HOL_cs))]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   552
    (* FIXME: not very well tested *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   553
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   554
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   555
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   556
(* |- ~(ALL x1...xn. P x1...xn) | P a1...an *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   557
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   558
  val rule = @{lemma "~ P x | Q ==> ~(ALL x. P x) | Q" by fast}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   559
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   560
val quant_inst = Thm o T.by_tac (
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   561
  REPEAT_ALL_NEW (Tactic.match_tac [rule])
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   562
  THEN' Tactic.rtac @{thm excluded_middle})
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   563
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   564
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   565
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   566
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   567
(* c = SOME x. P x |- (EX x. P x) = P c
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   568
   c = SOME x. ~ P x |- ~(ALL x. P x) = ~ P c *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   569
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   570
  val elim_ex = @{lemma "EX x. P == P" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   571
  val elim_all = @{lemma "~ (ALL x. P) == ~P" by simp}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   572
  val sk_ex = @{lemma "c == SOME x. P x ==> EX x. P x == P c"
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   573
    by simp (intro eq_reflection some_eq_ex[symmetric])}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   574
  val sk_all = @{lemma "c == SOME x. ~ P x ==> ~(ALL x. P x) == ~ P c"
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   575
    by (simp only: not_all) (intro eq_reflection some_eq_ex[symmetric])}
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   576
  val sk_ex_rule = ((sk_ex, I), elim_ex)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   577
  and sk_all_rule = ((sk_all, Thm.dest_arg), elim_all)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   578
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   579
  fun dest f sk_rule = 
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   580
    Thm.dest_comb (f (Thm.dest_arg (Thm.dest_arg (Thm.cprop_of sk_rule))))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   581
  fun type_of f sk_rule = Thm.ctyp_of_term (snd (dest f sk_rule))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   582
  fun pair2 (a, b) (c, d) = [(a, c), (b, d)]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   583
  fun inst_sk (sk_rule, f) p c =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   584
    Thm.instantiate ([(type_of f sk_rule, Thm.ctyp_of_term c)], []) sk_rule
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   585
    |> (fn sk' => Thm.instantiate ([], (pair2 (dest f sk') (p, c))) sk')
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   586
    |> Conv.fconv_rule (Thm.beta_conversion true)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   587
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   588
  fun kind (Const (@{const_name Ex}, _) $ _) = (sk_ex_rule, I, I)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   589
    | kind (@{term Not} $ (Const (@{const_name All}, _) $ _)) =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   590
        (sk_all_rule, Thm.dest_arg, Thm.capply @{cterm Not})
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   591
    | kind t = raise TERM ("skolemize", [t])
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   592
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   593
  fun dest_abs_type (Abs (_, T, _)) = T
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   594
    | dest_abs_type t = raise TERM ("dest_abs_type", [t])
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   595
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   596
  fun bodies_of thy lhs rhs =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   597
    let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   598
      val (rule, dest, make) = kind (Thm.term_of lhs)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   599
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   600
      fun dest_body idx cbs ct =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   601
        let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   602
          val cb = Thm.dest_arg (dest ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   603
          val T = dest_abs_type (Thm.term_of cb)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   604
          val cv = Thm.cterm_of thy (Var (("x", idx), T))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   605
          val cu = make (Drule.beta_conv cb cv)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   606
          val cbs' = (cv, cb) :: cbs
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   607
        in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   608
          (snd (Thm.first_order_match (cu, rhs)), rev cbs')
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   609
          handle Pattern.MATCH => dest_body (idx+1) cbs' cu
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   610
        end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   611
    in (rule, dest_body 1 [] lhs) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   612
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   613
  fun transitive f thm = Thm.transitive thm (f (Thm.rhs_of thm))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   614
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   615
  fun sk_step (rule, elim) (cv, mct, cb) ((is, thm), ctxt) =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   616
    (case mct of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   617
      SOME ct =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   618
        ctxt
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   619
        |> T.make_hyp_def (inst_sk rule (Thm.instantiate_cterm ([], is) cb) ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   620
        |>> pair ((cv, ct) :: is) o Thm.transitive thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   621
    | NONE => ((is, transitive (Conv.rewr_conv elim) thm), ctxt))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   622
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   623
fun skolemize ct ctxt =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   624
  let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   625
    val (lhs, rhs) = Thm.dest_binop (Thm.dest_arg ct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   626
    val (rule, (ctab, cbs)) = bodies_of (ProofContext.theory_of ctxt) lhs rhs
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   627
    fun lookup_var (cv, cb) = (cv, AList.lookup (op aconvc) ctab cv, cb)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   628
  in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   629
    (([], Thm.reflexive lhs), ctxt)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   630
    |> fold (sk_step rule) (map lookup_var cbs)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   631
    |>> MetaEq o snd
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   632
  end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   633
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   634
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   635
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   636
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   637
(** theory proof rules **)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   638
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   639
(* theory lemmas: linear arithmetic, arrays *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   640
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   641
fun th_lemma ctxt simpset thms = Thm o try_apply ctxt thms [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   642
  T.by_abstraction ctxt thms (fn ctxt' => T.by_tac (
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   643
    NAMED ctxt' "arith" (Arith_Data.arith_tac ctxt')
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   644
    ORELSE' NAMED ctxt' "simp+arith" (Simplifier.simp_tac simpset THEN_ALL_NEW
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   645
      Arith_Data.arith_tac ctxt')))]
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   646
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   647
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   648
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   649
(* rewriting: prove equalities:
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   650
     * ACI of conjunction/disjunction
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   651
     * contradiction, excluded middle
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   652
     * logical rewriting rules (for negation, implication, equivalence,
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   653
         distinct)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   654
     * normal forms for polynoms (integer/real arithmetic)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   655
     * quantifier elimination over linear arithmetic
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   656
     * ... ? **)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   657
structure Z3_Simps = Named_Thms
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   658
(
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   659
  val name = "z3_simp"
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   660
  val description = "simplification rules for Z3 proof reconstruction"
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   661
)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   662
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   663
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   664
  fun spec_meta_eq_of thm =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   665
    (case try (fn th => th RS @{thm spec}) thm of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   666
      SOME thm' => spec_meta_eq_of thm'
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   667
    | NONE => mk_meta_eq thm)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   668
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   669
  fun prep (Thm thm) = spec_meta_eq_of thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   670
    | prep (MetaEq thm) = thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   671
    | prep (Literals (thm, _)) = spec_meta_eq_of thm
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   672
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   673
  fun unfold_conv ctxt ths =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   674
    Conv.arg_conv (Conv.binop_conv (T.unfold_eqs ctxt (map prep ths)))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   675
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   676
  fun with_conv _ [] prv = prv
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   677
    | with_conv ctxt ths prv = T.with_conv (unfold_conv ctxt ths) prv
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   678
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   679
  val unfold_conv =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   680
    Conv.arg_conv (Conv.binop_conv (Conv.try_conv T.unfold_distinct_conv))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   681
  val prove_conj_disj_eq = T.with_conv unfold_conv L.prove_conj_disj_eq
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   682
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   683
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   684
fun rewrite ctxt simpset ths = Thm o with_conv ctxt ths (try_apply ctxt [] [
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   685
  named ctxt "conj/disj/distinct" prove_conj_disj_eq,
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   686
  T.by_abstraction ctxt [] (fn ctxt' => T.by_tac (
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   687
    NAMED ctxt' "simp" (Simplifier.simp_tac simpset)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   688
    THEN_ALL_NEW (
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   689
      NAMED ctxt' "fast" (Classical.fast_tac HOL_cs)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   690
      ORELSE' NAMED ctxt' "arith" (Arith_Data.arith_tac ctxt'))))])
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   691
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   692
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   693
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   694
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   695
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   696
(** proof reconstruction **)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   697
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   698
(* tracing and checking *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   699
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   700
local
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   701
  fun count_rules ptab =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   702
    let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   703
      fun count (_, Unproved _) (solved, total) = (solved, total + 1)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   704
        | count (_, Proved _) (solved, total) = (solved + 1, total + 1)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   705
    in Inttab.fold count ptab (0, 0) end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   706
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   707
  fun header idx r (solved, total) = 
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   708
    "Z3: #" ^ string_of_int idx ^ ": " ^ P.string_of_rule r ^ " (goal " ^
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   709
    string_of_int (solved + 1) ^ " of " ^ string_of_int total ^ ")"
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   710
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   711
  fun check ctxt idx r ps ct p =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   712
    let val thm = thm_of p |> tap (Thm.join_proofs o single)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   713
    in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   714
      if (Thm.cprop_of thm) aconvc ct then ()
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   715
      else z3_exn (Pretty.string_of (Pretty.big_list ("proof step failed: " ^
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   716
        quote (P.string_of_rule r) ^ " (#" ^ string_of_int idx ^ ")")
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   717
          (pretty_goal ctxt (map (thm_of o fst) ps) (Thm.prop_of thm) @
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   718
           [Pretty.block [Pretty.str "expected: ",
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   719
            Syntax.pretty_term ctxt (Thm.term_of ct)]])))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   720
    end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   721
in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   722
fun trace_rule idx prove r ps ct (cxp as (ctxt, ptab)) =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   723
  let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   724
    val _ = SMT_Solver.trace_msg ctxt (header idx r o count_rules) ptab
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   725
    val result as (p, cxp' as (ctxt', _)) = prove r ps ct cxp
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   726
    val _ = if not (Config.get ctxt' SMT_Solver.trace) then ()
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   727
      else check ctxt' idx r ps ct p
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   728
  in result end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   729
end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   730
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   731
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   732
(* overall reconstruction procedure *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   733
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   734
fun not_supported r =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   735
  raise Fail ("Z3: proof rule not implemented: " ^ quote (P.string_of_rule r))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   736
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   737
fun prove ctxt unfolds assms vars =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   738
  let
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   739
    val assms' = Option.map (prepare_assms ctxt unfolds) assms
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   740
    val simpset = T.make_simpset ctxt (Z3_Simps.get ctxt)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   741
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   742
    fun step r ps ct (cxp as (cx, ptab)) =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   743
      (case (r, ps) of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   744
        (* core rules *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   745
        (P.TrueAxiom, _) => (Thm L.true_thm, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   746
      | (P.Asserted, _) => (asserted cx assms' ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   747
      | (P.Goal, _) => (asserted cx assms' ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   748
      | (P.ModusPonens, [(p, _), (q, _)]) => (mp q (thm_of p), cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   749
      | (P.ModusPonensOeq, [(p, _), (q, _)]) => (mp q (thm_of p), cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   750
      | (P.AndElim, [(p, i)]) => and_elim (p, i) ct ptab ||> pair cx
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   751
      | (P.NotOrElim, [(p, i)]) => not_or_elim (p, i) ct ptab ||> pair cx
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   752
      | (P.Hypothesis, _) => (Thm (Thm.assume ct), cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   753
      | (P.Lemma, [(p, _)]) => (lemma (thm_of p) ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   754
      | (P.UnitResolution, (p, _) :: ps) =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   755
          (unit_resolution (thm_of p) (map (thm_of o fst) ps) ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   756
      | (P.IffTrue, [(p, _)]) => (iff_true (thm_of p), cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   757
      | (P.IffFalse, [(p, _)]) => (iff_false (thm_of p), cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   758
      | (P.Distributivity, _) => (distributivity cx ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   759
      | (P.DefAxiom, _) => (def_axiom cx ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   760
      | (P.IntroDef, _) => intro_def ct cx ||> rpair ptab
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   761
      | (P.ApplyDef, [(p, _)]) => (apply_def (thm_of p), cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   762
      | (P.IffOeq, [(p, _)]) => (p, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   763
      | (P.NnfPos, _) => (nnf cx vars (map fst ps) ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   764
      | (P.NnfNeg, _) => (nnf cx vars (map fst ps) ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   765
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   766
        (* equality rules *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   767
      | (P.Reflexivity, _) => (refl ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   768
      | (P.Symmetry, [(p, _)]) => (symm p, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   769
      | (P.Transitivity, [(p, _), (q, _)]) => (trans p q, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   770
      | (P.Monotonicity, _) => (monotonicity (map fst ps) ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   771
      | (P.Commutativity, _) => (commutativity ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   772
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   773
        (* quantifier rules *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   774
      | (P.QuantIntro, [(p, _)]) => (quant_intro vars p ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   775
      | (P.PullQuant, _) => (pull_quant cx ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   776
      | (P.PushQuant, _) => (push_quant cx ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   777
      | (P.ElimUnusedVars, _) => (elim_unused_vars cx ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   778
      | (P.DestEqRes, _) => (dest_eq_res cx ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   779
      | (P.QuantInst, _) => (quant_inst ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   780
      | (P.Skolemize, _) => skolemize ct cx ||> rpair ptab
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   781
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   782
        (* theory rules *)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   783
      | (P.ThLemma, _) =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   784
          (th_lemma cx simpset (map (thm_of o fst) ps) ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   785
      | (P.Rewrite, _) => (rewrite cx simpset [] ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   786
      | (P.RewriteStar, ps) =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   787
          (rewrite cx simpset (map fst ps) ct, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   788
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   789
      | (P.NnfStar, _) => not_supported r
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   790
      | (P.CnfStar, _) => not_supported r
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   791
      | (P.TransitivityStar, _) => not_supported r
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   792
      | (P.PullQuantStar, _) => not_supported r
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   793
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   794
      | _ => raise Fail ("Z3: proof rule " ^ quote (P.string_of_rule r) ^
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   795
         " has an unexpected number of arguments."))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   796
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   797
    fun conclude idx rule prop (ps, cxp) =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   798
      trace_rule idx step rule ps prop cxp
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   799
      |-> (fn p => apsnd (Inttab.update (idx, Proved p)) #> pair p)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   800
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   801
    fun lookup idx (cxp as (cx, ptab)) =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   802
      (case Inttab.lookup ptab idx of
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   803
        SOME (Unproved (P.Proof_Step {rule, prems, prop})) =>
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   804
          fold_map lookup prems cxp
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   805
          |>> map2 rpair prems
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   806
          |> conclude idx rule prop
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   807
      | SOME (Proved p) => (p, cxp)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   808
      | NONE => z3_exn ("unknown proof id: " ^ quote (string_of_int idx)))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   809
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   810
    fun result (p, (cx, _)) = (thm_of p, cx)
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   811
  in
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   812
    (fn (idx, ptab) => result (lookup idx (ctxt, Inttab.map Unproved ptab)))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   813
  end
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   814
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   815
fun reconstruct (output, {typs, terms, unfolds, assms}) ctxt =
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   816
  P.parse ctxt typs terms output
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   817
  |> (fn (idx, (ptab, vars, cx)) => prove cx unfolds assms vars (idx, ptab))
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   818
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   819
val setup = trace_assms_setup #> z3_rules_setup #> Z3_Simps.setup
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   820
8e55aa1306c5 integrated SMT into the HOL image
boehmes
parents:
diff changeset
   821
end