Nominal/activities/tphols09/IDW/CU-Ex1.thy
author Christian Urban <christian dot urban at kcl dot ac dot uk>
Wed, 30 Mar 2016 17:27:34 +0100
changeset 415 f1be8028a4a9
permissions -rw-r--r--
updated
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
415
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     1
theory Ex
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     2
imports Main
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     3
begin
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     4
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     5
text {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     6
  An example of an apply-proof and the
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     7
  corresponding ML-code.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     8
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     9
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    10
lemma disj_swap: 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    11
  shows "P \<or> Q \<Longrightarrow> Q \<or> P"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    12
apply(erule disjE)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    13
apply(rule disjI2)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    14
apply(assumption)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    15
apply(rule disjI1)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    16
apply(assumption)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    17
done
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    18
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    19
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    20
let
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    21
  val ctxt  = @{context}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    22
  val goal  = @{prop "P \<or> Q \<Longrightarrow> Q \<or> P"}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    23
  val facts = []
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    24
  val schms  = ["P", "Q"]
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    25
in
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    26
  Goal.prove ctxt schms facts goal
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    27
   (fn _ =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    28
      etac @{thm disjE} 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    29
      THEN rtac @{thm disjI2} 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    30
      THEN atac 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    31
      THEN rtac @{thm disjI1} 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    32
      THEN atac 1)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    33
end
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    34
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    35
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    36
text {*  
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    37
  Tactics coded in ML can be applied / tried out in 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    38
  apply-scripts using "tactic". "THEN" is a tactic
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    39
  combinator that just strings tactics together.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    40
  Tactic combinators are also called tacticals.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    41
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    42
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    43
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    44
val foo_tac =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    45
      (etac @{thm disjE} 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    46
       THEN rtac @{thm disjI2} 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    47
       THEN atac 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    48
       THEN rtac @{thm disjI1} 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    49
       THEN atac 1)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    50
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    51
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    52
lemma 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    53
  shows "P \<or> Q \<Longrightarrow> Q \<or> P"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    54
apply(tactic {* foo_tac *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    55
done
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    56
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    57
text {* 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    58
  Coding tactics with explicit subgoal addressing
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    59
  is quite brittle and limits the usage of the tactics.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    60
  This can be avoided using the `primed' versions
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    61
  of the tactic comibinators.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    62
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    63
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    64
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    65
val foo_tac' =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    66
      (etac @{thm disjE}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    67
       THEN' rtac @{thm disjI2}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    68
       THEN' atac
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    69
       THEN' rtac @{thm disjI1}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    70
       THEN' atac)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    71
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    72
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    73
text {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    74
  Now the tactic can be used on any subgoal.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    75
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    76
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    77
lemma "P1 \<or> Q1 \<Longrightarrow> Q1 \<or> P1"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    78
  and "P2 \<or> Q2 \<Longrightarrow> Q2 \<or> P2"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    79
apply(tactic {* foo_tac' 2 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    80
apply(tactic {* foo_tac' 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    81
done
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    82
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    83
text {* 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    84
  The type of a tactic is from a theorem
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    85
  to a lazy sequence of (successor) theorems.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    86
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    87
  type tactic = thm -> thm Seq.seq 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    88
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    89
  The simplest tactics are no_tac (always
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    90
  fails) and all_tac (always succeds, but 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    91
  does not make any progress.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    92
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    93
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    94
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    95
ML {* fun no_tac thm = Seq.empty *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    96
ML {* fun all_tac thm = Seq.single thm *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    97
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    98
text {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    99
  The lazy sequence can be explored using
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   100
  "back".
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   101
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   102
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   103
lemma "\<lbrakk>P \<or> Q; P \<or> Q\<rbrakk> \<Longrightarrow> Q \<or> P"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   104
apply(tactic {* foo_tac' 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   105
back
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   106
done
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   107
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   108
text {* 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   109
  It might be surprising that a goalstate of
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   110
  an "unfinished" proof is a theorem. Below
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   111
  we show the internals.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   112
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   113
  In general a goalstate is of the form
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   114
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   115
  A1 \<dots> An \<Longrightarrow> #C
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   116
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   117
  where the Ai are the open subgoals and C
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   118
  is the theorem to be proved, protected by
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   119
  the constant prop. This constant is usually
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   120
  not visible.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   121
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   122
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   123
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   124
fun my_print_tac ctxt thm =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   125
let
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   126
   val _ = tracing (Syntax.string_of_term ctxt (prop_of thm))
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   127
in
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   128
   Seq.single thm
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   129
end
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   130
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   131
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   132
notation (output) "prop" ("#_" [1000] 1000)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   133
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   134
lemma shows "\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   135
apply(tactic {* my_print_tac @{context} *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   136
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   137
apply(rule conjI)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   138
apply(tactic {* my_print_tac @{context} *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   139
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   140
apply(assumption)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   141
apply(tactic {* my_print_tac @{context} *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   142
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   143
apply(assumption)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   144
apply(tactic {* my_print_tac @{context} *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   145
done
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   146
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   147
notation (output) "prop" ("_" [1000] 1000)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   148
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   149
text {* 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   150
  There are some simple tactics corresponding
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   151
  to rule, erule and drule (from apply scripts).
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   152
  The examples should be self-explanatory.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   153
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   154
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   155
lemma shows "P \<Longrightarrow> P"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   156
apply(tactic {* atac 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   157
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   158
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   159
lemma shows "P \<and> Q"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   160
apply(tactic {* resolve_tac [@{thm conjI}] 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   161
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   162
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   163
lemma shows "P \<and> Q \<Longrightarrow> False"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   164
apply(tactic {* eresolve_tac [@{thm conjE}] 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   165
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   166
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   167
lemma shows "False \<and> True \<Longrightarrow> False"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   168
apply(tactic {* dresolve_tac [@{thm conjunct2}] 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   169
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   170
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   171
text {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   172
  For all sorts of operations on the goalstate there
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   173
  is a corresponding tactic. The following corresponds
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   174
  to "insert".
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   175
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   176
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   177
lemma shows "True = False"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   178
apply(tactic {* cut_facts_tac [@{thm True_def}, @{thm False_def}] 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   179
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   180
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   181
text {* 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   182
  Because of schematic variables, theorems need often
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   183
  to be pre-instantiated.  
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   184
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   185
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   186
lemma shows "\<forall>x \<in> A. P x \<Longrightarrow> Q x"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   187
apply(tactic {* dresolve_tac [@{thm bspec}] 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   188
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   189
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   190
ML {* @{thm disjI1} RS @{thm conjI} *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   191
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   192
text {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   193
  Tactic combinators: every tactic (THEN),
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   194
  first applicable tactic (ORELSE).
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   195
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   196
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   197
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   198
val foo_tac' = 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   199
  EVERY' [etac @{thm disjE}, 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   200
          rtac @{thm disjI2},
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   201
          atac, 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   202
          rtac @{thm disjI1}, 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   203
          atac]
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   204
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   205
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   206
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   207
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   208
val select_tac = 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   209
  FIRST' [rtac @{thm conjI}, 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   210
          rtac @{thm impI},
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   211
          rtac @{thm notI}, 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   212
          rtac @{thm allI}, K all_tac]
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   213
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   214
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   215
text {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   216
  The most convenient order to apply tactics to subgoal
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   217
  is in reverse order. 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   218
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   219
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   220
lemma 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   221
  shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow> C" and " \<forall> x. D x" and "E \<Longrightarrow> F"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   222
apply(tactic {* select_tac 4 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   223
apply(tactic {* select_tac 3 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   224
apply(tactic {* select_tac 2 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   225
apply(tactic {* select_tac 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   226
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   227
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   228
text {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   229
  The tactic select_tac can also be written using the 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   230
  combinator TRY.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   231
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   232
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   233
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   234
val select_tac' = 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   235
  TRY o FIRST' [rtac @{thm conjI}, 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   236
                rtac @{thm impI},
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   237
                rtac @{thm notI}, 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   238
                rtac @{thm allI}]
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   239
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   240
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   241
text {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   242
  Repeated application of tactics. 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   243
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   244
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   245
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   246
val repeat_sel_tac = 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   247
  REPEAT o CHANGED o select_tac'
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   248
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   249
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   250
lemma 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   251
  shows "A \<and> (B \<and> C)" and "A \<longrightarrow> B \<longrightarrow> C" and " \<forall> x. D x" and "E \<Longrightarrow> F"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   252
apply(tactic {* repeat_sel_tac 4 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   253
apply(tactic {* repeat_sel_tac 3 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   254
apply(tactic {* repeat_sel_tac 2 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   255
apply(tactic {* repeat_sel_tac 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   256
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   257
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   258
text {*  
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   259
  Application of a tactics to all new subgoals.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   260
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   261
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   262
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   263
val repeat_all_new_sel_tac = 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   264
  TRY o REPEAT_ALL_NEW (CHANGED o select_tac')
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   265
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   266
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   267
lemma 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   268
  shows "A \<and> (B \<and> C)" and "A \<longrightarrow> B \<longrightarrow> C" and " \<forall> x. D x" and "E \<Longrightarrow> F"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   269
apply(tactic {* repeat_all_new_sel_tac 4 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   270
apply(tactic {* repeat_all_new_sel_tac 3 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   271
apply(tactic {* repeat_all_new_sel_tac 2 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   272
apply(tactic {* repeat_all_new_sel_tac 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   273
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   274
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   275
text {* 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   276
  The tactical DEPTH_SOLVED applies tactics in depth first
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   277
  search including backtracking.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   278
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   279
  This can be used to implement a decision procedure for 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   280
  propositional intuitionistic logic inspired by work of 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   281
  Roy Dyckhoff.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   282
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   283
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   284
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   285
lemma impE1:
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   286
  shows "\<lbrakk>A \<longrightarrow> B; A; \<lbrakk>A; B\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   287
by iprover
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   288
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   289
lemma impE2:
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   290
  shows "\<lbrakk>(C \<and> D) \<longrightarrow> B; C \<longrightarrow> (D \<longrightarrow>B) \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   291
by iprover
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   292
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   293
lemma impE3:
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   294
  shows "\<lbrakk>(C \<or> D) \<longrightarrow> B; \<lbrakk>C \<longrightarrow> B; D \<longrightarrow> B\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   295
by iprover
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   296
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   297
lemma impE4:
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   298
  shows "\<lbrakk>(C \<longrightarrow> D) \<longrightarrow> B; D \<longrightarrow> B \<Longrightarrow> C \<longrightarrow> D; B \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   299
by iprover
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   300
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   301
lemma impE5:
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   302
  shows "\<lbrakk>(C = D) \<longrightarrow> B; (C \<longrightarrow> D) \<longrightarrow> ((D \<longrightarrow> C) \<longrightarrow> B) \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   303
by iprover
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   304
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   305
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   306
val apply_tac =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   307
let
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   308
  val intros = [@{thm conjI}, @{thm disjI1}, @{thm disjI2}, @{thm impI}, @{thm iffI}]
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   309
  val elims  = [@{thm FalseE}, @{thm conjE}, @{thm disjE}, @{thm iffE},
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   310
                @{thm impE2}, @{thm impE3}, @{thm impE4}, @{thm impE5}, @{thm impE1}]
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   311
in
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   312
  atac 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   313
  ORELSE' resolve_tac intros
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   314
  ORELSE' eresolve_tac elims
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   315
end
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   316
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   317
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   318
lemma
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   319
  shows "((((P \<longrightarrow> Q) \<longrightarrow> P) \<longrightarrow> P) \<longrightarrow> Q) \<longrightarrow> Q"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   320
apply(tactic {* (DEPTH_SOLVE o apply_tac) 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   321
done
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   322
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   323
lemma 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   324
  shows "((A \<longrightarrow> B) \<longrightarrow> A) \<longrightarrow> A"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   325
apply(tactic {* (TRY o DEPTH_SOLVE o apply_tac) 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   326
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   327
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   328
lemma
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   329
  shows "(A \<and> B \<or> ((((A \<longrightarrow> False) \<longrightarrow> False) \<longrightarrow> Q) \<or> (B \<longrightarrow> Q)) \<longrightarrow> Q) \<longrightarrow> Q"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   330
apply(tactic {* (TRY o DEPTH_SOLVE o apply_tac) 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   331
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   332
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   333
text {* 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   334
  The SUBPROOF tactic gives you full access to
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   335
  all components of a goal state.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   336
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   337
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   338
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   339
fun subproof_tac {asms, concl, prems, params, context, schematics} =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   340
let
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   341
  fun out f xs = commas (map (Syntax.string_of_term context o f) xs)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   342
  val str_of_asms   = out term_of asms
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   343
  val str_of_concl  = out term_of [concl]
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   344
  val str_of_prems  = out prop_of prems
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   345
  val str_of_params = out term_of params
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   346
  val str_of_schms  = out term_of (snd schematics)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   347
  val s = ["params: "      ^ str_of_params,
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   348
           "schematics: "  ^ str_of_schms,
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   349
           "premises: "    ^ str_of_prems,
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   350
           "assumptions: " ^ str_of_asms,
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   351
           "conclusion: "  ^ str_of_concl]
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   352
in
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   353
   tracing (cat_lines s); no_tac
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   354
end
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   355
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   356
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   357
lemma shows "\<And>x y. A x y \<Longrightarrow> B y x \<longrightarrow> C (?z y) x"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   358
apply(tactic {* SUBPROOF subproof_tac @{context} 1 *})?
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   359
apply(rule impI)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   360
apply(tactic {* SUBPROOF subproof_tac @{context} 1 *})?
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   361
oops
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   362
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   363
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   364
val my_atac = SUBPROOF (fn {prems, ...} => resolve_tac prems 1)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   365
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   366
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   367
lemma shows "\<lbrakk>B x y; A x y; C x y \<rbrakk> \<Longrightarrow> A x y"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   368
apply(tactic {* my_atac @{context} 1 *})
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   369
done
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   370
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   371
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   372
text {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   373
  Setting up the goal state using the function 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   374
  Goal.prove. It expects the goal as a term, we
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   375
  have to construct manually.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   376
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   377
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   378
ML {* 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   379
open HOLogic
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   380
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   381
fun P n = @{term "P::nat \<Rightarrow> bool"} $ (mk_number @{typ "nat"} n) 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   382
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   383
fun rhs 1 = P 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   384
  | rhs n = mk_conj (P n, rhs (n - 1))
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   385
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   386
fun lhs 1 n = mk_imp (mk_eq (P 1, P n), rhs n)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   387
  | lhs m n =  mk_conj (mk_imp 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   388
                 (mk_eq (P (m - 1), P m), rhs n), lhs (m - 1) n)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   389
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   390
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   391
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   392
fun de_bruijn_test ctxt n =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   393
let 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   394
  val i = 2*n + 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   395
  val goal = mk_Trueprop (mk_imp (lhs i i, rhs i))
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   396
in
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   397
  Syntax.string_of_term ctxt goal
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   398
  |> writeln
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   399
end;
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   400
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   401
de_bruijn_test @{context} 1   
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   402
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   403
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   404
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   405
fun de_bruijn ctxt n =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   406
let 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   407
  val i = 2*n+1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   408
  val goal = mk_Trueprop (mk_imp (lhs i i, rhs i))
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   409
in
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   410
  Goal.prove ctxt ["P"] [] goal
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   411
   (fn _ => (DEPTH_SOLVE o apply_tac) 1)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   412
end 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   413
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   414
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   415
ML{* de_bruijn @{context} 1 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   416
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   417
text {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   418
  Below is the version which constructs the terms
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   419
  using fixed variables.
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   420
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   421
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   422
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   423
fun de_bruijn ctxt n = 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   424
let 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   425
  val i = 2*n+1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   426
  val bs = replicate (i+1) "b"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   427
  val (nbs, ctxt') = Variable.variant_fixes bs ctxt
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   428
  val fbs = map (fn z => Free (z, @{typ "bool"})) nbs
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   429
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   430
  fun P n = nth fbs n 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   431
  
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   432
  fun rhs 0 = @{term "True"}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   433
    | rhs 1 = P 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   434
    | rhs n = mk_conj (P n, rhs (n - 1))
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   435
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   436
  fun lhs 1 n = mk_imp (mk_eq (P 1, P n), rhs n)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   437
    | lhs m n =  mk_conj (mk_imp 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   438
                   (mk_eq (P (m - 1), P m), rhs n), lhs (m - 1) n)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   439
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   440
  val goal = mk_Trueprop (mk_imp (lhs i i, rhs i))
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   441
in
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   442
  Goal.prove ctxt' [] [] goal
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   443
   (fn _ => (DEPTH_SOLVE o apply_tac) 1)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   444
  (*|> singleton (ProofContext.export ctxt' ctxt)*)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   445
end
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   446
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   447
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   448
ML {* de_bruijn @{context} 1 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   449
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   450
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   451
end
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   452
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   453
 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   454
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   455
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   456
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   457
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   458
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   459
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   460
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   461