src/Tools/isac/BaseDefinitions/model-pattern.sml
author wneuper <Walther.Neuper@jku.at>
Sat, 04 Mar 2023 19:02:39 +0100
changeset 60699 dcaf63259e1d
parent 60698 f7795240462a
child 60700 376aebcaeeb5
permissions -rw-r--r--
PIDE turn 9a: handle empty input correct
     1 (* Title:  BaseDefinitions/model-pattern.sml
     2    Author: Walther Neuper
     3    (c) due to copyright terms
     4 
     5 A \<open>Model_Pattern\<close> defines a -> \<open>Problem\<close>-type: its \<open>variables\<close> are to be instantiated
     6 by the values for particular \<open>Problem\<close>s in a \<open>Formalise.model\<close>.
     7 The \<open>variables\<close> are used twice, in a model and as formal arguments in a \<open>Program\<close>.
     8 The \<open>descriptor\<close>s are unique identifiers within one \<open>Model_Pattern\<close>.
     9 *)
    10 signature MODEL_PATTERN =
    11 sig
    12   type T
    13   type single
    14   val to_string: Proof.context -> single list -> string
    15 
    16   type model_input_pos
    17   type empty_input
    18   val empty_input: empty_input list
    19   type pre_model
    20   type pre_model_TEST
    21   type pre_model_single
    22 
    23   type m_field = string
    24   type descriptor = term
    25   val parse_pos: Proof.context -> (m_field * (string * Position.T) list) list ->
    26     pre_model * (term * Position.T) list
    27   val parse_pos_TEST: Proof.context -> (m_field * (string * Position.T) list) list ->
    28     pre_model_TEST * (term * Position.T) list
    29 
    30   val variables: T -> term list
    31   val get_field: descriptor -> T -> m_field option
    32   datatype for = Problem | Method | Undef
    33 
    34   val adapt_to_type: Proof.context -> single -> single
    35 (*from isac_test for Minisubpbl*)
    36   val split_descriptor: Proof.context -> m_field * term * Position.T ->
    37     (m_field * (descriptor * term) * Position.T)
    38   val split_descriptor': string -> (*TermC.as_*)string * empty_input
    39   datatype pre_model_single_TEST =
    40       Empty of (m_field * (descriptor * empty_input) * Position.T)
    41     | Proper of (m_field * (descriptor * term) * Position.T)
    42   val parse_pattern: Proof.context -> 'a * (string * Position.T) -> 'a * term * Position.T
    43   val empty_for: typ -> string
    44   val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) ->
    45     m_field * term * Position.T
    46   val parse_term_TEST: Proof.context -> m_field * (string * Position.T) -> pre_model_single_TEST
    47 
    48 \<^isac_test>\<open>
    49   (**)
    50 \<close>
    51 end
    52 
    53 (**)
    54 structure Model_Pattern(**): MODEL_PATTERN(**) =
    55 struct
    56 (**)
    57 
    58 (* the pattern for an item of a problems model or a methods guard *)
    59 type m_field = string;
    60 type descriptor = term;
    61 type single =
    62   (m_field *      (* field Given, Find, Relate *)
    63 	  (descriptor * (* for snd term              *)
    64 	     term))     (* id | arbitrary term       *);
    65 (* does NOT contain pre-conditions, because these have no \<open>descriptor\<close> *)
    66 type T = single list;
    67 
    68 type model_input_pos =                       (* for internal use                       *)
    69   (m_field *                                 (* "#Given", "#Find", "#Where", "#Relate" *)
    70     ((*TermC.as_*)string * Position.T) list) (* list of items belonging to m_field     *)
    71   list;                                      (* list of "#Given" .. "#Relate"          *)
    72 type empty_input = string
    73 val empty_bool_list_input = "[__=__, __=__]"
    74 val empty_reallist_input = "[__, __]"
    75 val empty_bool_input = "(__=__)"
    76 val empty_item_input = "__"
    77 val empty_input = [empty_bool_list_input, empty_reallist_input, empty_bool_input, empty_item_input]
    78 fun empty_for (Type ("fun", [Type ("List.list", [Type ("HOL.bool", [])]), _])) = empty_bool_list_input
    79   | empty_for (Type ("fun", [Type ("List.list", [Type ("Real.real", [])]), _])) = empty_reallist_input
    80   | empty_for (Type ("HOL.bool", [])) = empty_bool_input
    81   | empty_for _ = empty_item_input
    82 type pre_model_single = (m_field * (descriptor * term) * Position.T)
    83 datatype pre_model_single_TEST =
    84     Empty of (m_field * (descriptor * empty_input) * Position.T)
    85   | Proper of (m_field * (descriptor * term) * Position.T)
    86 type pre_model = pre_model_single list
    87 type pre_model_TEST = pre_model_single_TEST list
    88 
    89 (*val split_descriptor: Proof.context -> m_field * term * Position.T ->
    90     m_field * (descriptor * term)(* * Position.T*)*)
    91 fun split_descriptor ctxt (m_field: string, dsc_tm, pos) = 
    92   let
    93     val (m_field, (hd, arg)) = case strip_comb dsc_tm of
    94       (hd, [arg]) => (m_field, (hd, arg))
    95     | _ => error ("Wrong descriptor " ^ quote (UnparseC.term ctxt dsc_tm) ^ Position.here pos)
    96   in (m_field, (hd, arg), pos) end
    97 
    98 fun is_undefined tm =
    99   if Term.exists_subterm (fn Const ("HOL.undefined", _) => true | _ => false) tm then true else false
   100 fun is_empty_input arg = member (op =) empty_input arg
   101 fun split_descriptor' str =
   102   let
   103     val chars = Symbol.explode str
   104     val end_descr = find_index (fn str => (if str = " " then true else false)) chars
   105       (*^^^ TODO find parser for identifier*)
   106   in
   107     (implode (take (end_descr, chars)), implode (drop (end_descr + 1, chars)))
   108     (* 1 blank inbetween descriptor and argument, I_Model.feedback_to_string_TEST *)
   109   end    
   110 
   111 (*val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) -> m_field * term*)
   112 fun parse_term ctxt (m_field, (str, pos)) =
   113   (m_field, ParseC.term_position ctxt (str, pos), pos)
   114 fun parse_term_TEST ctxt (m_field, (str, pos)) =
   115   let
   116     val (m_field, term, pos) = parse_term ctxt (m_field, (str, pos))
   117     val (m_field, (descr, arg), pos) = split_descriptor ctxt (m_field, term, pos)
   118   in
   119     if is_undefined arg
   120     then Empty (m_field, (descr, descr |> type_of |> empty_for), pos)
   121     else Proper (m_field, (descr, arg), pos)
   122   end 
   123 
   124 fun parse_pattern ctxt (m_field, (str, pos)) =
   125   (m_field, ParseC.pattern_position ctxt (str, pos), pos)
   126 
   127 fun parse_pos ctxt model_input =
   128   let
   129     val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
   130     val model = items 
   131       |> filter_out ((fn f => (fn (f', _) => f = f')) "#Where") 
   132       |> map (parse_term ctxt)
   133       |> map (split_descriptor ctxt)
   134     val where_ = items 
   135       |> filter ((fn f => (fn (f', _) => f = f')) "#Where") 
   136       |> map (parse_pattern ctxt)
   137       |> map (fn (_, a, b) => (a, b))
   138   in (model, where_) end
   139 fun parse_pos_TEST ctxt model_input =
   140   let
   141     val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
   142     val model = items 
   143       |> filter_out ((fn f => (fn (f', _) => f = f')) "#Where")
   144       |> map (parse_term_TEST ctxt)
   145     val where_ = items 
   146       |> filter ((fn f => (fn (f', _) => f = f')) "#Where") 
   147       |> map (parse_pattern ctxt)
   148       |> map (fn (_, a, b) => (a, b))
   149   in (model, where_) end
   150 
   151 fun pat2str ctxt (field, (dsc, id)) =
   152   pair2str (field, pair2str (UnparseC.term ctxt dsc, UnparseC.term ctxt id));
   153 fun to_string ctxt pats = (strs2str o (map (pat2str ctxt))) pats;
   154 
   155 \<^isac_test>\<open>
   156 (**)
   157 \<close>
   158 
   159 (* get the variables out of a pbl_; FIXME.WN.0311: is_copy_named ...obscure!!! *)
   160 fun variables pbl_ = 
   161   let
   162     fun var_of_pbl_ (_, (_, t)) = t: term
   163   in ((map var_of_pbl_)(* o (filter_out is_copy_named)*)) pbl_ end
   164 
   165 fun get_field descriptor m_patt = 
   166   (filter ((curry (fn (desc, (_, (desc', _))) => desc = desc')) descriptor) m_patt
   167     |> the_single
   168     |> (fn (a, _) => SOME a))
   169   handle List.Empty => NONE
   170   datatype for = Problem | Method | Undef
   171 
   172 
   173 (* adapt type of terms with most general type to a more specific one *)
   174 fun adapt_to_type ctxt (field, (descr, term_as_string)) =
   175   (field, (ParseC.adapt_term_to_type ctxt descr, ParseC.adapt_term_to_type ctxt term_as_string))
   176 
   177 (**)end(*struct*)