src/HOL/Examples/ML.thy
author wenzelm
Mon, 08 Jun 2020 21:38:41 +0200
changeset 71925 bf085daea304
child 71929 73ff22f99d38
permissions -rw-r--r--
clarified sessions: "Notable Examples in Isabelle/HOL";
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
71925
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
     1
(*  Title:      HOL/Examples/ML.thy
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
     3
*)
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
     4
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
     5
section \<open>Isabelle/ML basics\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
     6
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
     7
theory "ML"
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
     8
imports Main
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
     9
begin
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    10
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    11
section \<open>ML expressions\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    12
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    13
text \<open>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    14
  The Isabelle command \<^theory_text>\<open>ML\<close> allows to embed Isabelle/ML source into the
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    15
  formal text. It is type-checked, compiled, and run within that environment.
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    16
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    17
  Note that side-effects should be avoided, unless the intention is to change
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    18
  global parameters of the run-time environment (rare).
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    19
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    20
  ML top-level bindings are managed within the theory context.
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    21
\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    22
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    23
ML \<open>1 + 1\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    24
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    25
ML \<open>val a = 1\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    26
ML \<open>val b = 1\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    27
ML \<open>val c = a + b\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    28
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    29
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    30
section \<open>Antiquotations\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    31
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    32
text \<open>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    33
  There are some language extensions (via antiquotations), as explained in the
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    34
  ``Isabelle/Isar implementation manual'', chapter 0.
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    35
\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    36
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    37
ML \<open>length []\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    38
ML \<open>\<^assert> (length [] = 0)\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    39
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    40
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    41
text \<open>Formal entities from the surrounding context may be referenced as
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    42
  follows:\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    43
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    44
term "1 + 1"   \<comment> \<open>term within theory source\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    45
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    46
ML \<open>\<^term>\<open>1 + 1\<close>   (* term as symbolic ML datatype value *)\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    47
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    48
ML \<open>\<^term>\<open>1 + (1::int)\<close>\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    49
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    50
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    51
ML \<open>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    52
  (* formal source with position information *)
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    53
  val s = \<open>1 + 1\<close>;
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    54
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    55
  (* read term via old-style string interface *)
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    56
  val t = Syntax.read_term \<^context> (Syntax.implode_input s);
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    57
\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    58
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    59
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    60
section \<open>Recursive ML evaluation\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    61
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    62
ML \<open>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    63
  ML \<open>ML \<open>val a = @{thm refl}\<close>\<close>;
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    64
  ML \<open>val b = @{thm sym}\<close>;
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    65
  val c = @{thm trans}
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    66
  val thms = [a, b, c];
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    67
\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    68
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    69
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    70
section \<open>IDE support\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    71
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    72
text \<open>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    73
  ML embedded into the Isabelle environment is connected to the Prover IDE.
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    74
  Poly/ML provides:
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    75
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    76
    \<^item> precise positions for warnings / errors
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    77
    \<^item> markup for defining positions of identifiers
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    78
    \<^item> markup for inferred types of sub-expressions
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    79
    \<^item> pretty-printing of ML values with markup
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    80
    \<^item> completion of ML names
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    81
    \<^item> source-level debugger
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    82
\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    83
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    84
ML \<open>fn i => fn list => length list + i\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    85
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    86
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    87
section \<open>Example: factorial and ackermann function in Isabelle/ML\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    88
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    89
ML \<open>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    90
  fun factorial 0 = 1
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    91
    | factorial n = n * factorial (n - 1)
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    92
\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    93
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    94
ML \<open>factorial 42\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    95
ML \<open>factorial 10000 div factorial 9999\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    96
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    97
text \<open>See \<^url>\<open>http://mathworld.wolfram.com/AckermannFunction.html\<close>.\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    98
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
    99
ML \<open>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   100
  fun ackermann 0 n = n + 1
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   101
    | ackermann m 0 = ackermann (m - 1) 1
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   102
    | ackermann m n = ackermann (m - 1) (ackermann m (n - 1))
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   103
\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   104
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   105
ML \<open>timeit (fn () => ackermann 3 10)\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   106
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   107
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   108
section \<open>Parallel Isabelle/ML\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   109
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   110
text \<open>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   111
  Future.fork/join/cancel manage parallel evaluation.
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   112
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   113
  Note that within Isabelle theory documents, the top-level command boundary
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   114
  may not be transgressed without special precautions. This is normally
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   115
  managed by the system when performing parallel proof checking.
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   116
\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   117
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   118
ML \<open>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   119
  val x = Future.fork (fn () => ackermann 3 10);
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   120
  val y = Future.fork (fn () => ackermann 3 10);
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   121
  val z = Future.join x + Future.join y
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   122
\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   123
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   124
text \<open>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   125
  The \<^ML_structure>\<open>Par_List\<close> module provides high-level combinators for
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   126
  parallel list operations.
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   127
\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   128
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   129
ML \<open>timeit (fn () => map (fn n => ackermann 3 n) (1 upto 10))\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   130
ML \<open>timeit (fn () => Par_List.map (fn n => ackermann 3 n) (1 upto 10))\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   131
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   132
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   133
section \<open>Function specifications in Isabelle/HOL\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   134
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   135
fun factorial :: "nat \<Rightarrow> nat"
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   136
where
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   137
  "factorial 0 = 1"
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   138
| "factorial (Suc n) = Suc n * factorial n"
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   139
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   140
term "factorial 4"  \<comment> \<open>symbolic term\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   141
value "factorial 4"  \<comment> \<open>evaluation via ML code generation in the background\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   142
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   143
declare [[ML_source_trace]]
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   144
ML \<open>\<^term>\<open>factorial 4\<close>\<close>  \<comment> \<open>symbolic term in ML\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   145
ML \<open>@{code "factorial"}\<close>  \<comment> \<open>ML code from function specification\<close>
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   146
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   147
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   148
fun ackermann :: "nat \<Rightarrow> nat \<Rightarrow> nat"
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   149
where
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   150
  "ackermann 0 n = n + 1"
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   151
| "ackermann (Suc m) 0 = ackermann m 1"
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   152
| "ackermann (Suc m) (Suc n) = ackermann m (ackermann (Suc m) n)"
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   153
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   154
value "ackermann 3 5"
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   155
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   156
end
bf085daea304 clarified sessions: "Notable Examples in Isabelle/HOL";
wenzelm
parents:
diff changeset
   157