src/HOL/SPARK/Examples/Gcd/Greatest_Common_Divisor.thy
author Walther Neuper <walther.neuper@jku.at>
Thu, 17 Dec 2020 18:00:27 +0100
changeset 60138 209f8c177b5b
parent 60134 85ce6e27e130
child 60139 c3cb65678c47
permissions -rw-r--r--
step 4.4: call hierarchy up from Syntax.check_terms, partially
berghofe@41809
     1
(*  Title:      HOL/SPARK/Examples/Gcd/Greatest_Common_Divisor.thy
berghofe@41809
     2
    Author:     Stefan Berghofer
berghofe@41809
     3
    Copyright:  secunet Security Networks AG
berghofe@41809
     4
*)
berghofe@41809
     5
berghofe@41809
     6
theory Greatest_Common_Divisor
wneuper@59451
     7
imports "HOL-SPARK.SPARK"
berghofe@41809
     8
begin
berghofe@41809
     9
walther@60134
    10
section \<open>spark intro\<close>
berghofe@41809
    11
spark_proof_functions
berghofe@41809
    12
  gcd = "gcd :: int \<Rightarrow> int \<Rightarrow> int"
berghofe@41809
    13
walther@60102
    14
declare [[ML_print_depth = 3]](* 3 7 10 9999999*)
walther@60096
    15
walther@60094
    16
spark_open \<open>greatest_common_divisor/g_c_d\<close> (*..from 3 files
walther@60095
    17
  ./greatest_common_divisor/g_c_d.siv, *.fdl, *.rls open *.siv and
walther@60094
    18
  find the following 2 open verification conditions (VC): *)
berghofe@41809
    19
walther@60134
    20
section \<open>example 1\<close>
walther@60094
    21
spark_vc procedure_g_c_d_4 (*..select 1st VC for proof: *)
berghofe@41809
    22
proof -
wneuper@59324
    23
  from \<open>0 < d\<close> have "0 \<le> c mod d" by (rule pos_mod_sign)
wneuper@59324
    24
  with \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>c - c sdiv d * d \<noteq> 0\<close> show ?C1
wneuper@59324
    25
    by (simp add: sdiv_pos_pos minus_div_mult_eq_mod [symmetric])
berghofe@41809
    26
next
wneuper@59324
    27
  from \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>gcd c d = gcd m n\<close> show ?C2
wneuper@59324
    28
    by (simp add: sdiv_pos_pos minus_div_mult_eq_mod [symmetric] gcd_non_0_int)
berghofe@41809
    29
qed
walther@60138
    30
walther@60138
    31
subsection \<open>observing interaction on the proof\<close>
walther@60134
    32
text \<open>
walther@60138
    33
  :
walther@60134
    34
# Clicks on different positions give different traces.
walther@60134
    35
# There are blocks with equal traces (separated by \n or |)
walther@60134
    36
    proof
walther@60134
    37
      from \<open>0 < d\<close>     |     have "0 \<le> c mod d"     |     by (rule pos_mod_sign)
walther@60134
    38
      with \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>c - c sdiv d * d \<noteq> 0\<close>   |     show ?C1
walther@60134
    39
        by (simp add: sdiv_pos_pos minus_div_mult_eq_mod [symmetric])
walther@60134
    40
    next [ONLY ### Private_Output.report keyword1]
walther@60134
    41
      from \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>gcd c d = gcd m n\<close>      |      show ?C2
walther@60134
    42
        by (simp add: sdiv_pos_pos minus_div_mult_eq_mod [symmetric] gcd_non_0_int)
walther@60134
    43
    qed [NO TRACE]
walther@60134
    44
# Specific traces seem to be extended by the subsequent one, 
walther@60134
    45
  e.g.   from \<open>0 < d\<close>        extended by        have "0 \<le> c mod d"
walther@60134
    46
  but both NOT by ...                                      by (rule pos_mod_sign)
walther@60134
    47
# Private_Output.report seems to have "" as argument frequently
walther@60134
    48
# Output.report provided semantic annotations in Naproche;
walther@60138
    49
  thus ALL calls of Output.report (in src/Pure) are traced an show up at these elements:
walther@60134
    50
    proof                                        x  x  .  .  .  
walther@60134
    51
    from \<open>0 < d\<close>                                 x  .  x  x  x  
walther@60134
    52
    have "0 \<le> c mod d"                           x  .  x  x  .  
walther@60134
    53
    by (rule pos_mod_sign)                       x  x  .  .  .  
walther@60134
    54
    with \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>c - c sdiv d * d \<noteq> 0\<close> x  .  x  x  x  
walther@60134
    55
    show ?C1                                     x  .  x  x  .  
walther@60134
    56
    by (simp add: ...[symmetric])                x  x  .  .  .  
walther@60134
    57
    next                                         x  .  .  .  .  
walther@60134
    58
    from \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>gcd c d = gcd m n\<close>     x  .  x  x  x  
walther@60134
    59
    show ?C2                                     x  .  x  x  .  
walther@60134
    60
    by (simp add: ...[symmetric] gcd_non_0_int)  x  x  .  .  .  
walther@60134
    61
                                                 |  |  |  |  Context_Position.report_generic
walther@60134
    62
                                                 |  |  |  Syntax_Phases.check_terms
walther@60134
    63
                                                 |  |  Syntax_Phases.check_typs
walther@60134
    64
                                                 |  Token.syntax_generic
walther@60134
    65
                                                 Private_Output.report
walther@60134
    66
\<close>
berghofe@41809
    67
walther@60138
    68
subsection \<open>tracing calls of Output.report\<close>
walther@60134
    69
text \<open>
walther@60134
    70
(*--------- click on "proof -" --------
walther@60134
    71
### Private_Output.report keyword1
walther@60134
    72
### Private_Output.report language
walther@60134
    73
### Private_Output.report entityo
walther@60134
    74
### Private_Output.report operator
walther@60134
    75
### Token.syntax_generic, Scan.error
walther@60134
    76
### Private_Output.report 
walther@60134
    77
### Token.syntax_generic, Scan.error
walther@60134
    78
\<close>
walther@60138
    79
text \<open>
walther@60138
    80
(*--------- click on "from \<open>0 < d\<close>" --------
walther@60138
    81
### Private_Output.report keyword1
walther@60138
    82
### Private_Output.report cartouch
walther@60138
    83
### Private_Output.report delimite
walther@60138
    84
### Private_Output.report entityo
walther@60138
    85
### Syntax_Phases.check_typs
walther@60138
    86
### Private_Output.report 
walther@60138
    87
### Syntax_Phases.check_typs
walther@60138
    88
### Private_Output.report 
walther@60138
    89
### Syntax_Phases.check_terms
walther@60138
    90
### Private_Output.report typingo          =====
walther@60138
    91
### Context_Position.report_generic           //--- different to subsequent part below
walther@60138
    92
### Private_Output.report entityo
walther@60138
    93
\<close>
walther@60138
    94
text \<open>
walther@60138
    95
(*--------- click on "have "0 \<le> c mod d"" --------
walther@60138
    96
### Private_Output.report keyword1
walther@60138
    97
### Private_Output.report 
walther@60138
    98
### Private_Output.report cartouch
walther@60138
    99
### Private_Output.report delimite
walther@60138
   100
### Private_Output.report entityo
walther@60138
   101
### Syntax_Phases.check_typs
walther@60138
   102
### Private_Output.report 
walther@60138
   103
### Syntax_Phases.check_typs
walther@60138
   104
### Private_Output.report 
walther@60138
   105
### Syntax_Phases.check_terms
walther@60138
   106
### Private_Output.report typingo          =====
walther@60138
   107
### Syntax_Phases.check_typs                  //--- different to previous part above
walther@60138
   108
### Private_Output.report 
walther@60138
   109
### Syntax_Phases.check_terms
walther@60138
   110
### Private_Output.report 
walther@60138
   111
\<close>
walther@60138
   112
walther@60138
   113
subsection \<open>signatures of the traced callers of Private_Output.report\<close>
walther@60138
   114
ML \<open>
walther@60138
   115
\<close> ML \<open>
walther@60138
   116
Private_Output.report          : string(*= markup*) list                   -> unit; 
walther@60138
   117
Context_Position.report_generic: Context.generic -> Position.T -> Markup.T -> unit;
walther@60138
   118
Token.syntax_generic           : 'a Token.context_parser -> Token.src -> Context.generic ->
walther@60138
   119
                                   'a * Context.generic;
walther@60138
   120
(*Syntax_Phases.check_typs     : Proof.context -> typ list -> typ list;    ..local*)
walther@60138
   121
(*Syntax_Phases.check_terms    : Proof.context -> term list -> term list;  ..local*)
walther@60138
   122
\<close> ML \<open>
walther@60138
   123
\<close>
walther@60138
   124
walther@60138
   125
subsection \<open>lookup calls of Syntax_Phases.check_terms\<close>
walther@60138
   126
text \<open>
walther@60138
   127
  focus are    "from \<open>0 < d\<close>"   and   have "0 \<le> c mod d".
walther@60138
   128
walther@60138
   129
  encapsulation?:
walther@60138
   130
    Syntax_Phases.check_terms NOwhere in src/Pure,
walther@60138
   131
    check_terms occurs in Theory.setup (Syntax.install_operations {..check_terms = check_terms..}
walther@60138
   132
    and nowhere else (except fun check_props)
walther@60138
   133
  so the calls are Syntax.check_terms ? -- NO: calls.1..4 --vv pop up in NONE of the 3 traces above.
walther@60138
   134
                                           ^^^^^^^^^^^^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
walther@60138
   135
  but they seem to be identical:
walther@60138
   136
    Syntax_Phases.check_terms: Proof.context -> term list -> term list;
walther@60138
   137
           Syntax.check_terms: Proof.context -> term list -> term list;
walther@60138
   138
    ?! there are 3-times structure Syntax:
walther@60138
   139
      Pure/Syntax/lexicon.ML                      /NO check_terms/
walther@60138
   140
        signature LEXICON = sig structure Syntax: sig val const: string -> term ..
walther@60138
   141
      Pure/Syntax/syntax.ML 
walther@60138
   142
        type operations = {..., ..., check_terms: Proof.context -> term list -> term list, ..
walther@60138
   143
        val check_terms = operation #check_terms;
walther@60138
   144
      Pure/Syntax/syntax_trans.ML                 /NO check_terms/
walther@60138
   145
        
walther@60138
   146
  the ASSUMED callers of Syntax.check_terms:
walther@60138
   147
//  Pure/Isar/expression.ML
walther@60138
   148
//    1,val inst_morphism: (string * typ) list -> (string * bool) * term list -> Proof.context ->
walther@60138
   149
//        morphism * Proof.context
walther@60138
   150
//    2.val check_autofix:
walther@60138
   151
//        ('a * ('b * term list)) list ->
walther@60138
   152
//          ('c * term) list list ->
walther@60138
   153
//            (typ, term, 'd) ctxt list ->
walther@60138
   154
//              ('e * (term * term list) list) list -> Proof.context ->
walther@60138
   155
//        (('a * ('b * term list)) list * ('c * term) list list * (typ, term, 'd) ctxt list *
walther@60138
   156
//          ('e * (term * term list) list) list) * Proof.context
walther@60138
   157
//        val check: (term * term list) list -> Proof.context ->
walther@60138
   158
//          (term * term list) list * Proof.context
walther@60138
   159
//  Pure/Isar/obtain.ML
walther@60138
   160
//    3.val Obtain.read_obtains: Proof.context -> term -> Element.obtains -> (binding * term) list 
walther@60138
   161
//  Pure/Isar/proof.ML
walther@60138
   162
//    4.val let_bind: (term list * term) list -> state -> state
walther@60138
   163
//    5.val let_bind_cmd: (string list * string) list -> state -> state
walther@60138
   164
//        val read_terms: context -> typ -> string list -> term list
walther@60138
   165
//  Pure/Isar/proof_context.ML
walther@60138
   166
//    6.val infer_type: Proof.context -> string * typ -> typ
walther@60138
   167
//  Pure/simplifier.ML
walther@60138
   168
//    7.val Simplifier.define_simproc: binding -> term Simplifier.simproc_spec ->
walther@60138
   169
//        local_theory -> local_theory
walther@60138
   170
//  Pure/Tools/rule_insts.ML
walther@60138
   171
//    8.val Rule_Insts.read_term: string -> Proof.context -> term * Proof.context
walther@60138
   172
//    :
walther@60138
   173
//    1.. looked up in the sequel
walther@60138
   174
\<close>
walther@60138
   175
subsection \<open>lookup Syntax.check_terms -> *1..4\<close>
walther@60138
   176
text \<open>\<close>
walther@60138
   177
walther@60138
   178
subsubsection \<open>lookup 1* -> Expression.inst_morphism\<close>
walther@60138
   179
text \<open>\<close>
walther@60138
   180
walther@60138
   181
subsubsection \<open>lookup 2* -> Expression.check_autofix\<close>
walther@60138
   182
text \<open>
walther@60138
   183
\<close> 
walther@60138
   184
subsubsection \<open>lookup 3* -> Obtain.read_obtains\<close>
walther@60138
   185
text \<open>\<close>
walther@60138
   186
walther@60138
   187
subsubsection \<open>lookup 4* -> Proof.let_bind\<close>
walther@60138
   188
text \<open>\<close>
walther@60138
   189
walther@60138
   190
subsubsection \<open>lookup 5* -> Proof.let_bind_cmd\<close>
walther@60138
   191
text \<open>\<close>
walther@60138
   192
walther@60138
   193
subsubsection \<open>lookup 6* -> Proof_Context.infer_type\<close>
walther@60138
   194
text \<open>\<close>
walther@60138
   195
walther@60138
   196
subsubsection \<open>lookup 7* -> Simplifier.define_simproc\<close>
walther@60138
   197
text \<open>\<close>
walther@60138
   198
walther@60138
   199
subsubsection \<open>lookup 8* -> Rule_Insts.read_term\<close>
walther@60138
   200
text \<open>\<close>
walther@60138
   201
walther@60134
   202
walther@60134
   203
section \<open>example 2\<close>
walther@60138
   204
walther@60094
   205
spark_vc procedure_g_c_d_11 (*..select 2nd VC for proof: *)
berghofe@41809
   206
proof -
wneuper@59324
   207
  from \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>c - c sdiv d * d = 0\<close>
berghofe@41809
   208
  have "d dvd c"
haftmann@58856
   209
    by (auto simp add: sdiv_pos_pos dvd_def ac_simps)
wneuper@59324
   210
  with \<open>0 < d\<close> \<open>gcd c d = gcd m n\<close> show ?C1
berghofe@41809
   211
    by simp
berghofe@41809
   212
qed
berghofe@41809
   213
berghofe@41809
   214
spark_end
berghofe@41809
   215
berghofe@41809
   216
end