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 |