src/HOL/Tools/SMT/z3_proof_methods.ML
author wenzelm
Sun, 30 Jan 2011 13:02:18 +0100
changeset 41648 6d736d983d5c
parent 41328 6792a5c92a58
child 41899 83dd157ec9ab
permissions -rw-r--r--
clarified example settings for Proof General;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
     1
(*  Title:      HOL/Tools/SMT/z3_proof_methods.ML
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
     2
    Author:     Sascha Boehme, TU Muenchen
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
     3
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
     4
Proof methods for Z3 proof reconstruction.
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
     5
*)
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
     6
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
     7
signature Z3_PROOF_METHODS =
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
     8
sig
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
     9
  val prove_injectivity: Proof.context -> cterm -> thm
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    10
end
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    11
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    12
structure Z3_Proof_Methods: Z3_PROOF_METHODS =
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    13
struct
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    14
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    15
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    16
fun apply tac st =
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    17
  (case Seq.pull (tac 1 st) of
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    18
    NONE => raise THM ("tactic failed", 1, [st])
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    19
  | SOME (st', _) => st')
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    20
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    21
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    22
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    23
(* injectivity *)
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    24
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    25
local
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    26
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    27
val B = @{typ bool}
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    28
fun mk_univ T = Const (@{const_name top}, T --> B)
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    29
fun mk_inj_on T U =
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    30
  Const (@{const_name inj_on}, (T --> U) --> (T --> B) --> B)
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    31
fun mk_inv_into T U =
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    32
  Const (@{const_name inv_into}, [T --> B, T --> U, U] ---> T)
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    33
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    34
fun mk_inv_of ctxt ct =
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    35
  let
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    36
    val (dT, rT) = Term.dest_funT (SMT_Utils.typ_of ct)
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    37
    val inv = SMT_Utils.certify ctxt (mk_inv_into dT rT)
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    38
    val univ = SMT_Utils.certify ctxt (mk_univ dT)
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    39
  in Thm.mk_binop inv univ ct end
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    40
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    41
fun mk_inj_prop ctxt ct =
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    42
  let
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    43
    val (dT, rT) = Term.dest_funT (SMT_Utils.typ_of ct)
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    44
    val inj = SMT_Utils.certify ctxt (mk_inj_on dT rT)
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    45
    val univ = SMT_Utils.certify ctxt (mk_univ dT)
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    46
  in SMT_Utils.mk_cprop (Thm.mk_binop inj ct univ) end
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    47
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    48
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    49
val disjE = @{lemma "~P | Q ==> P ==> Q" by fast}
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    50
40663
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
    51
fun prove_inj_prop ctxt def lhs =
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    52
  let
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    53
    val (ct, ctxt') = SMT_Utils.dest_all_cabs (Thm.rhs_of def) ctxt
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    54
    val rule = disjE OF [Object_Logic.rulify (Thm.assume lhs)]
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    55
  in
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    56
    Goal.init (mk_inj_prop ctxt' (Thm.dest_arg ct))
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    57
    |> apply (Tactic.rtac @{thm injI})
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    58
    |> apply (Tactic.solve_tac [rule, rule RS @{thm sym}])
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    59
    |> Goal.norm_result o Goal.finish ctxt'
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    60
    |> singleton (Variable.export ctxt' ctxt)
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    61
  end
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    62
40663
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
    63
fun prove_rhs ctxt def lhs =
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    64
  Z3_Proof_Tools.by_tac (
40663
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
    65
    CONVERSION (Conv.top_sweep_conv (K (Conv.rewr_conv def)) ctxt)
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
    66
    THEN' REPEAT_ALL_NEW (Tactic.match_tac @{thms allI})
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
    67
    THEN' Tactic.rtac (@{thm inv_f_f} OF [prove_inj_prop ctxt def lhs])) #>
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
    68
  Thm.elim_implies def
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    69
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    70
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    71
fun expand thm ct =
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    72
  let
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    73
    val cpat = Thm.dest_arg (Thm.rhs_of thm)
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    74
    val (cl, cr) = Thm.dest_binop (Thm.dest_arg (Thm.dest_arg1 ct))
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    75
    val thm1 = Thm.instantiate (Thm.match (cpat, cl)) thm
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    76
    val thm2 = Thm.instantiate (Thm.match (cpat, cr)) thm
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    77
  in Conv.arg_conv (Conv.binop_conv (Conv.rewrs_conv [thm1, thm2])) ct end
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    78
40663
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
    79
fun prove_lhs ctxt rhs =
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    80
  let
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    81
    val eq = Thm.symmetric (mk_meta_eq (Object_Logic.rulify (Thm.assume rhs)))
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    82
    val conv = SMT_Utils.binders_conv (K (expand eq)) ctxt
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    83
  in
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    84
    Z3_Proof_Tools.by_tac (
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    85
      CONVERSION (SMT_Utils.prop_conv conv)
40663
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
    86
      THEN' Simplifier.simp_tac HOL_ss)
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    87
  end
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    88
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    89
40663
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
    90
fun mk_inv_def ctxt rhs =
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    91
  let
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    92
    val (ct, ctxt') =
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    93
      SMT_Utils.dest_all_cbinders (SMT_Utils.dest_cprop rhs) ctxt
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    94
    val (cl, cv) = Thm.dest_binop ct
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    95
    val (cg, (cargs, cf)) = Drule.strip_comb cl ||> split_last
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    96
    val cu = fold_rev Thm.cabs cargs (mk_inv_of ctxt' (Thm.cabs cv cf))
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
    97
  in Thm.assume (SMT_Utils.mk_cequals cg cu) end
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    98
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
    99
fun prove_inj_eq ctxt ct =
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   100
  let
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
   101
    val (lhs, rhs) =
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
   102
      pairself SMT_Utils.mk_cprop (Thm.dest_binop (SMT_Utils.dest_cprop ct))
40663
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
   103
    val lhs_thm = prove_lhs ctxt rhs lhs
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
   104
    val rhs_thm = prove_rhs ctxt (mk_inv_def ctxt rhs) lhs rhs
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   105
  in lhs_thm COMP (rhs_thm COMP @{thm iffI}) end
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   106
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   107
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   108
val swap_eq_thm = mk_meta_eq @{thm eq_commute}
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   109
val swap_disj_thm = mk_meta_eq @{thm disj_commute}
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   110
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   111
fun swap_conv dest eq =
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
   112
  SMT_Utils.if_true_conv ((op <) o pairself Term.size_of_term o dest)
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   113
    (Conv.rewr_conv eq)
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   114
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   115
val swap_eq_conv = swap_conv HOLogic.dest_eq swap_eq_thm
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
   116
val swap_disj_conv = swap_conv SMT_Utils.dest_disj swap_disj_thm
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   117
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   118
fun norm_conv ctxt =
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   119
  swap_eq_conv then_conv
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
   120
  Conv.arg1_conv (SMT_Utils.binders_conv (K swap_disj_conv) ctxt) then_conv
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
   121
  Conv.arg_conv (SMT_Utils.binders_conv (K swap_eq_conv) ctxt)
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   122
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   123
in
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   124
40663
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
   125
fun prove_injectivity ctxt =
41328
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
   126
  Z3_Proof_Tools.by_tac (
6792a5c92a58 avoid ML structure aliases (especially single-letter abbreviations)
boehmes
parents: 40840
diff changeset
   127
    CONVERSION (SMT_Utils.prop_conv (norm_conv ctxt))
40663
e080c9e68752 share and use more utility functions;
boehmes
parents: 40662
diff changeset
   128
    THEN' CSUBGOAL (uncurry (Tactic.rtac o prove_inj_eq ctxt)))
40662
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   129
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   130
end
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   131
798aad2229c0 added prove reconstruction for injective functions;
boehmes
parents:
diff changeset
   132
end