Nominal/activities/tphols09/IDW/FI-Ex.thy
author Christian Urban <christian.urban@kcl.ac.uk>
Tue, 07 Jan 2025 12:42:42 +0000
changeset 653 2807ec31d144
parent 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
section {* Sledgehammer *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     6
lemma "inj f ==> inj g ==> inj (f o g)"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     7
sledgehammer e
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     8
apply (metis comp_inj_on inj_on_inverseI inv_f_eq top_set_eq) done
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
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    11
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    12
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    13
section {* Threads in ML *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    14
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    15
text {* some helper functions *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    16
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    17
ML {* fun sleep time = OS.Process.sleep (Time.fromSeconds time) *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    18
ML {* sleep 5 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    19
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    20
ML {* val count = ref 0 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    21
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    22
fun slow_inc name time =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    23
  let
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    24
  val a = !count
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    25
  val _ = sleep time
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    26
  val result = a + 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    27
  val _ = count := result
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    28
  in
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    29
    priority (name ^ ": " ^ string_of_int result)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    30
  end
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    31
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    32
ML {* slow_inc "incremented" 10 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    33
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    34
ML {* SimpleThread.fork *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    35
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    36
SimpleThread.fork true (fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    37
  slow_inc "parallel counter" 10)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    38
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    39
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    40
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
section {* Synchronization *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    44
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    45
text{* Example: lost update *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    46
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    47
count := 0;
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    48
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    49
SimpleThread.fork true (fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    50
  slow_inc "counter1" 10);
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
SimpleThread.fork true (fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    53
  slow_inc "counter2" 10)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    54
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    55
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
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    58
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    59
subsection {* pthreads-primitives *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    60
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    61
text {* functions for mutexes *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    62
ML {* Mutex.mutex *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    63
ML {* Mutex.lock *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    64
ML {* Mutex.unlock *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    65
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    66
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    67
(* protecting count *)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    68
val mutex = Mutex.mutex()
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    69
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    70
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    71
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    72
fun fork_inc name time =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    73
  SimpleThread.fork true (fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    74
    let
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    75
      val _ = Mutex.lock mutex
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    76
      val _ = slow_inc name time
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    77
      val _ = Mutex.unlock mutex
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    78
    in () end);
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    79
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    80
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    81
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    82
fork_inc "A" 5;
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    83
fork_inc "B" 5;
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    84
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    85
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    86
text {* CAUTION: mutex stays locked after interrupt! *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    87
ML {* fork_inc "C" 10000 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    88
ML {* SimpleThread.interrupt it *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    89
ML {* fork_inc "D" 1 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    90
ML {* Mutex.unlock mutex (* actually undefined behaviour!! *) *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    91
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
text {* Condition Variables *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    96
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    97
val mutex = Mutex.mutex()
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    98
val cond = ConditionVar.conditionVar()
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    99
val state = ref 0
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   100
*}
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
text {* double state when signalled *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   103
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   104
SimpleThread.fork true (fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   105
  let 
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   106
  val _ = Mutex.lock mutex
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   107
  val _ = ConditionVar.wait (cond, mutex)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   108
  val _ = state := (!state) * 2
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   109
  val _ = sleep 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   110
  val _ = priority ("Changed to: " ^ string_of_int (!state))
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   111
  val _ = Mutex.unlock mutex
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   112
  in () end)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   113
*}
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
text {* change state and signal condition variable*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   116
ML {* Mutex.lock mutex *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   117
ML {* state := 21 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   118
ML {* ConditionVar.signal cond *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   119
ML {* Mutex.unlock mutex*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   120
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
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   124
subsection{* Isabelle/ML combinators*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   125
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   126
ML {* SimpleThread.synchronized *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   127
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   128
text {* protect count *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   129
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   130
fun fork_inc_safe name time =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   131
  SimpleThread.fork true (fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   132
    SimpleThread.synchronized name mutex (fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   133
      slow_inc name time))
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   134
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   135
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   136
ML {* val e = fork_inc_safe "E" 10000 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   137
ML {* SimpleThread.interrupt e *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   138
ML {* fork_inc_safe "F" 1 *}
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
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   141
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
subsection {* State Variables with synchronized access *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   144
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   145
ML {* Synchronized.var *}
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
ML {* val state = Synchronized.var "goods" 0 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   148
ML {* Synchronized.value state *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   149
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   150
text{* modifying state *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   151
ML {* Synchronized.change *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   152
ML {* Synchronized.change state (fn i => i + 1) *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   153
ML {* Synchronized.value state *}
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
text{* change with result *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   156
ML {* Synchronized.change;
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   157
      Synchronized.change_result *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   158
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   159
val previous_state_string =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   160
  Synchronized.change_result state (fn i =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   161
    (string_of_int i, i + 1))
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
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   164
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   165
text{* change (with result) when state meets some property *}
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
ML {* Synchronized.change_result;
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   168
      Synchronized.guarded_access *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   169
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{* example: producer consumer *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   172
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   173
ML {* Synchronized.change state (K 0) *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   174
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   175
ML {* fun produce k = Synchronized.change state (fn i => i + k) *}
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
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   178
fun consume () = Synchronized.guarded_access state (fn i =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   179
  if i <= 0
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   180
  then NONE
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   181
  else SOME(i - 1, i - 1));
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   182
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   183
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   184
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   185
fun consumer name = SimpleThread.fork true (fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   186
  while true do
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   187
    let
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   188
    val amount = consume ()
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   189
    val _ = sleep 1
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   190
    in priority (name ^ " consumed; " ^ string_of_int amount ^ " left") end)
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
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   193
ML {* val a = consumer "A" *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   194
ML {* produce 3 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   195
ML {* val b = consumer "B" *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   196
ML {* produce 4 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   197
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   198
ML {* map SimpleThread.interrupt [a,b] *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   199
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   200
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   201
text {* timeout while waiting on signal *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   202
ML {* Synchronized.guarded_access;
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   203
      Synchronized.timed_access*}
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
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   206
fun consume_t timeout =
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   207
  Synchronized.timed_access
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   208
    state
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   209
    (* absolute time! *)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   210
    (fn _ => SOME (Time.+ (Time.now (),Time.fromSeconds (timeout))))
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   211
    (fn i => if i <= 0 then NONE else SOME(i - 1, i - 1))
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   212
*}
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
ML {* produce 2 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   215
ML {* consume_t 3 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   216
ML {* consume_t 3 *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   217
ML {* consume_t 3 *}
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
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   221
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   222
section{* Thread Attributes *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   223
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   224
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   225
fun start_work () = SimpleThread.fork true (fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   226
  uninterruptible (fn restore_attributes => fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   227
    let
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   228
    val _ = sleep 5
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   229
    val _ = priority "... initialized"
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   230
    val _ = restore_attributes (fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   231
      (sleep 5; priority "done work")) ()
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   232
    in () end) ())
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   233
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   234
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   235
ML {* val thread = start_work () *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   236
ML {* SimpleThread.interrupt thread *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   237
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   238
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
section{* External processes *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   242
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   243
ML {* system_out *}
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 {* val bash_script = "sleep 10; echo woke up" *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   246
ML {* system_out bash_script *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   247
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   248
ML {* val bash_script = "while [ 0 ]; do x=$x; done" *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   249
ML {*
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   250
val thread = SimpleThread.fork true (fn () =>
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   251
  let val _ = system_out bash_script
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   252
  in () end)
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   253
*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   254
ML {*SimpleThread.interrupt thread*}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   255
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   256
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   257
ML {* val path_to_isabelle = Path.explode "~~/bin/isabelle" *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   258
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   259
text {* File in File.shell_path (spaces!) *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   260
ML {* val command = File.shell_path path_to_isabelle ^ " version" *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   261
ML {* system_out command *}
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   262
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   263
end
f1be8028a4a9 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   264