ProgTutorial/Recipes/Config.thy
changeset 189 069d525f8f1d
parent 168 009ca4807baa
child 191 0150cf5982ae
equal deleted inserted replaced
188:8939b8fd8603 189:069d525f8f1d
       
     1 theory Config
       
     2 imports "../Base"
       
     3 begin
       
     4 
       
     5 section {* Configuration Options\label{rec:config} *} 
       
     6 
       
     7 
       
     8 text {*
       
     9   {\bf Problem:} 
       
    10   You would like to enhance your tool with options that can be changed 
       
    11   by the user without having to resort to the ML-level.\smallskip
       
    12 
       
    13   {\bf Solution:} This can be achieved using configuration values.\smallskip
       
    14 
       
    15   Assume you want to control three values, say @{text bval} containing a
       
    16   boolean,  @{text ival} containing an integer and @{text sval} 
       
    17   containing a string. These values can be declared on the ML-level by
       
    18 *}
       
    19 
       
    20 ML{*val (bval, setup_bval) = Attrib.config_bool "bval" false
       
    21 val (ival, setup_ival) = Attrib.config_int "ival" 0
       
    22 val (sval, setup_sval) = Attrib.config_string "sval" "some string" *}
       
    23 
       
    24 text {* 
       
    25   where each value needs to be given a default. To enable these values, they need to 
       
    26   be set up with
       
    27 *}
       
    28 
       
    29 setup {* setup_bval *} 
       
    30 setup {* setup_ival *}
       
    31 
       
    32 text {* or on the ML-level *}
       
    33 
       
    34 ML{*setup_sval @{theory} *}
       
    35 
       
    36 text {*
       
    37   The user can now manipulate the values from within Isabelle with the command
       
    38 *}
       
    39 
       
    40 declare [[bval = true, ival = 3]]
       
    41 
       
    42 text {*
       
    43   On the ML-level these values can be retrieved using the 
       
    44   function @{ML Config.get}:
       
    45 
       
    46   @{ML_response [display,gray] "Config.get @{context} bval" "true"}
       
    47 
       
    48   @{ML_response [display,gray] "Config.get @{context} ival" "3"}
       
    49 
       
    50   The function @{ML Config.put} manipulates the values. For example
       
    51 
       
    52   @{ML_response [display,gray] "Config.put sval \"foo\" @{context}; Config.get @{context} sval" "foo"}
       
    53 
       
    54   The same can be achieved using the command \isacommand{setup}.
       
    55 *}
       
    56 
       
    57 setup {* Config.put_thy sval "bar" *}
       
    58 
       
    59 text {* 
       
    60   Now the retrival of this value yields:
       
    61 
       
    62   @{ML_response [display,gray] "Config.get @{context} sval" "\"bar\""}
       
    63 
       
    64   We can apply a function to a value using @{ML Config.map}. For example incrementing
       
    65   @{ML ival} can be done by:
       
    66 
       
    67   @{ML_response [display,gray] 
       
    68 "let 
       
    69   val ctxt = Config.map ival (fn i => i + 1) @{context}
       
    70 in 
       
    71   Config.get ctxt ival
       
    72 end" "4"}
       
    73 
       
    74   \begin{readmore}
       
    75   For more information see @{ML_file "Pure/Isar/attrib.ML"} and @{ML_file "Pure/config.ML"}.
       
    76   \end{readmore}
       
    77 
       
    78   There are many good reasons to control parameters in this way. One is
       
    79   that it avoid global references, which cause many headaches with the
       
    80   multithreaded execution of Isabelle.
       
    81   
       
    82   *}
       
    83 end