doc-src/IsarImplementation/Thy/ML.thy
changeset 33174 1f2051f41335
parent 32966 5b21661fe618
child 36134 c210a8fda4c5
equal deleted inserted replaced
33173:b8ca12f6681a 33174:1f2051f41335
   315   continued by an application of a function @{ML_text "g : foo -> bar"},
   315   continued by an application of a function @{ML_text "g : foo -> bar"},
   316   and so on.  As a canoncial example, take functions enriching
   316   and so on.  As a canoncial example, take functions enriching
   317   a theory by constant declararion and primitive definitions:
   317   a theory by constant declararion and primitive definitions:
   318 
   318 
   319   \smallskip\begin{mldecls}
   319   \smallskip\begin{mldecls}
   320   @{ML "Sign.declare_const: Properties.T -> (binding * typ) * mixfix
   320   @{ML "Sign.declare_const: (binding * typ) * mixfix
   321   -> theory -> term * theory"} \\
   321   -> theory -> term * theory"} \\
   322   @{ML "Thm.add_def: bool -> bool -> binding * term -> theory -> thm * theory"}
   322   @{ML "Thm.add_def: bool -> bool -> binding * term -> theory -> thm * theory"}
   323   \end{mldecls}
   323   \end{mldecls}
   324 
   324 
   325   \noindent Written with naive application, an addition of constant
   325   \noindent Written with naive application, an addition of constant
   327   a corresponding definition @{term "bar \<equiv> \<lambda>x. x"} would look like:
   327   a corresponding definition @{term "bar \<equiv> \<lambda>x. x"} would look like:
   328 
   328 
   329   \smallskip\begin{mldecls}
   329   \smallskip\begin{mldecls}
   330   @{ML "(fn (t, thy) => Thm.add_def false false
   330   @{ML "(fn (t, thy) => Thm.add_def false false
   331   (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})) thy)
   331   (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})) thy)
   332     (Sign.declare_const []
   332     (Sign.declare_const
   333       ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn) thy)"}
   333       ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn) thy)"}
   334   \end{mldecls}
   334   \end{mldecls}
   335 
   335 
   336   \noindent With increasing numbers of applications, this code gets quite
   336   \noindent With increasing numbers of applications, this code gets quite
   337   unreadable.  Further, it is unintuitive that things are
   337   unreadable.  Further, it is unintuitive that things are
   342   \noindent At this stage, Isabelle offers some combinators which allow
   342   \noindent At this stage, Isabelle offers some combinators which allow
   343   for more convenient notation, most notably reverse application:
   343   for more convenient notation, most notably reverse application:
   344 
   344 
   345   \smallskip\begin{mldecls}
   345   \smallskip\begin{mldecls}
   346 @{ML "thy
   346 @{ML "thy
   347 |> Sign.declare_const [] ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   347 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   348 |> (fn (t, thy) => thy
   348 |> (fn (t, thy) => thy
   349 |> Thm.add_def false false
   349 |> Thm.add_def false false
   350      (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})))"}
   350      (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})))"}
   351   \end{mldecls}
   351   \end{mldecls}
   352 *}
   352 *}
   366   set of combinators is at hand, most notably @{ML "op |->"}
   366   set of combinators is at hand, most notably @{ML "op |->"}
   367   which allows curried access to side results:
   367   which allows curried access to side results:
   368 
   368 
   369   \smallskip\begin{mldecls}
   369   \smallskip\begin{mldecls}
   370 @{ML "thy
   370 @{ML "thy
   371 |> Sign.declare_const [] ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   371 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   372 |-> (fn t => Thm.add_def false false
   372 |-> (fn t => Thm.add_def false false
   373       (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})))
   373       (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})))
   374 "}
   374 "}
   375   \end{mldecls}
   375   \end{mldecls}
   376 
   376 
   377   \noindent @{ML "op |>>"} allows for processing side results on their own:
   377   \noindent @{ML "op |>>"} allows for processing side results on their own:
   378 
   378 
   379   \smallskip\begin{mldecls}
   379   \smallskip\begin{mldecls}
   380 @{ML "thy
   380 @{ML "thy
   381 |> Sign.declare_const [] ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   381 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   382 |>> (fn t => Logic.mk_equals (t, @{term \"%x. x\"}))
   382 |>> (fn t => Logic.mk_equals (t, @{term \"%x. x\"}))
   383 |-> (fn def => Thm.add_def false false (Binding.name \"bar_def\", def))
   383 |-> (fn def => Thm.add_def false false (Binding.name \"bar_def\", def))
   384 "}
   384 "}
   385   \end{mldecls}
   385   \end{mldecls}
   386 
   386 
   387   \noindent Orthogonally, @{ML "op ||>"} applies a transformation
   387   \noindent Orthogonally, @{ML "op ||>"} applies a transformation
   388   in the presence of side results which are left unchanged:
   388   in the presence of side results which are left unchanged:
   389 
   389 
   390   \smallskip\begin{mldecls}
   390   \smallskip\begin{mldecls}
   391 @{ML "thy
   391 @{ML "thy
   392 |> Sign.declare_const [] ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   392 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   393 ||> Sign.add_path \"foobar\"
   393 ||> Sign.add_path \"foobar\"
   394 |-> (fn t => Thm.add_def false false
   394 |-> (fn t => Thm.add_def false false
   395       (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})))
   395       (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})))
   396 ||> Sign.restore_naming thy
   396 ||> Sign.restore_naming thy
   397 "}
   397 "}
   399 
   399 
   400   \noindent @{ML "op ||>>"} accumulates side results:
   400   \noindent @{ML "op ||>>"} accumulates side results:
   401 
   401 
   402   \smallskip\begin{mldecls}
   402   \smallskip\begin{mldecls}
   403 @{ML "thy
   403 @{ML "thy
   404 |> Sign.declare_const [] ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   404 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   405 ||>> Sign.declare_const [] ((Binding.name \"foobar\", @{typ \"foo => foo\"}), NoSyn)
   405 ||>> Sign.declare_const ((Binding.name \"foobar\", @{typ \"foo => foo\"}), NoSyn)
   406 |-> (fn (t1, t2) => Thm.add_def false false
   406 |-> (fn (t1, t2) => Thm.add_def false false
   407       (Binding.name \"bar_def\", Logic.mk_equals (t1, t2)))
   407       (Binding.name \"bar_def\", Logic.mk_equals (t1, t2)))
   408 "}
   408 "}
   409   \end{mldecls}
   409   \end{mldecls}
   410 *}
   410 *}
   445   \smallskip\begin{mldecls}
   445   \smallskip\begin{mldecls}
   446 @{ML "let
   446 @{ML "let
   447   val consts = [\"foo\", \"bar\"];
   447   val consts = [\"foo\", \"bar\"];
   448 in
   448 in
   449   thy
   449   thy
   450   |> fold_map (fn const => Sign.declare_const []
   450   |> fold_map (fn const => Sign.declare_const
   451        ((Binding.name const, @{typ \"foo => foo\"}), NoSyn)) consts
   451        ((Binding.name const, @{typ \"foo => foo\"}), NoSyn)) consts
   452   |>> map (fn t => Logic.mk_equals (t, @{term \"%x. x\"}))
   452   |>> map (fn t => Logic.mk_equals (t, @{term \"%x. x\"}))
   453   |-> (fn defs => fold_map (fn def =>
   453   |-> (fn defs => fold_map (fn def =>
   454        Thm.add_def false false (Binding.empty, def)) defs)
   454        Thm.add_def false false (Binding.empty, def)) defs)
   455 end"}
   455 end"}
   484   in a series of context transformations:
   484   in a series of context transformations:
   485 
   485 
   486   \smallskip\begin{mldecls}
   486   \smallskip\begin{mldecls}
   487 @{ML "thy
   487 @{ML "thy
   488 |> tap (fn _ => writeln \"now adding constant\")
   488 |> tap (fn _ => writeln \"now adding constant\")
   489 |> Sign.declare_const [] ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   489 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   490 ||>> `(fn thy => Sign.declared_const thy
   490 ||>> `(fn thy => Sign.declared_const thy
   491          (Sign.full_name thy (Binding.name \"foobar\")))
   491          (Sign.full_name thy (Binding.name \"foobar\")))
   492 |-> (fn (t, b) => if b then I
   492 |-> (fn (t, b) => if b then I
   493        else Sign.declare_const []
   493        else Sign.declare_const
   494          ((Binding.name \"foobar\", @{typ \"foo => foo\"}), NoSyn) #> snd)
   494          ((Binding.name \"foobar\", @{typ \"foo => foo\"}), NoSyn) #> snd)
   495 "}
   495 "}
   496   \end{mldecls}
   496   \end{mldecls}
   497 *}
   497 *}
   498 
   498