src/Tools/isac/BaseDefinitions/model-pattern.sml
author wneuper <Walther.Neuper@jku.at>
Fri, 14 Jul 2023 12:33:25 +0200
changeset 60721 1170b3685197
parent 60720 1eb6a480c1e1
child 60722 14ff64a7e3bd
permissions -rw-r--r--
prepare 6: repair I_Model.of_max_variant
     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   val pat2str: Proof.context -> single -> string
    16 
    17   type model_input_pos
    18   type empty_input
    19   type pre_model
    20   type pre_model'
    21 
    22   type m_field = string
    23   type descriptor = term
    24   val parse_pos: Proof.context -> (m_field * (string * Position.T) list) list ->
    25     pre_model * (term * Position.T) list
    26   val parse_pos_empty: Proof.context -> (m_field * (string * Position.T) list) list ->
    27     pre_model' * (term * Position.T) list
    28 
    29   val variables: T -> term list
    30   val get_field: descriptor -> T -> m_field option
    31   datatype for = Problem | Method | Undef
    32 
    33   val adapt_to_type: Proof.context -> single -> single
    34 (*from isac_test for Minisubpbl*)
    35   val split_descriptor: Proof.context -> m_field * term * Position.T ->
    36     (m_field * (descriptor * term) * Position.T)
    37   datatype pre_model_single' =
    38       Empty of (m_field * (descriptor * empty_input) * Position.T)
    39     | Proper of (m_field * (descriptor * term) * Position.T)
    40   val parse_pattern: Proof.context -> 'a * (string * Position.T) -> 'a * term * Position.T
    41 
    42   val typ_of_element: descriptor -> typ
    43   val is_list_descr: descriptor -> bool
    44   val empty_for: descriptor -> empty_input
    45   val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) ->
    46     m_field * term * Position.T
    47   val parse_empty_input: Proof.context -> m_field * (string * Position.T) -> pre_model_single'
    48   val is_undefined: term -> bool
    49 
    50 \<^isac_test>\<open>
    51   (**)
    52 \<close>
    53 end
    54 
    55 (**)
    56 structure Model_Pattern(**): MODEL_PATTERN(**) =
    57 struct
    58 (**)
    59 
    60 (* the pattern for an item of a problems model or a methods guard *)
    61 type m_field = string;
    62 type descriptor = term;
    63 type single =
    64   (m_field *      (* field Given, Find, Relate *)
    65 	  (descriptor * (* for snd term              *)
    66 	     term))     (* id | arbitrary term       *);
    67 (* does NOT contain pre-conditions, because these have no \<open>descriptor\<close> *)
    68 type T = single list;
    69 
    70 type model_input_pos =                       (* for internal use                       *)
    71   (m_field *                                 (* "#Given", "#Find", "#Where", "#Relate" *)
    72     ((*TermC.as_*)string * Position.T) list) (* list of items belonging to m_field     *)
    73   list;                                      (* list of "#Given" .. "#Relate"          *)
    74 type empty_input = string
    75 datatype descr_type = List of typ | Single of typ
    76 fun descr_type (Type ("fun", [Type ("List.list", [typ]), _])) = List typ
    77   | descr_type (Type ("fun", [typ, _])) = Single typ
    78   | descr_type typ = raise TYPE ("Model_Pattern.descr_type", [typ], [])
    79 fun typ_of_element descr =
    80   case descr_type (type_of descr) of
    81     List typ => typ
    82   | Single typ => typ
    83 fun is_list_descr descr =
    84   case descr_type (type_of descr) of List _ => true | _ => false
    85 fun empty_for descr =
    86   case descr_type (type_of descr) of
    87     List typ => if typ = HOLogic.boolT then "[__=__, __=__]" else "[__, __]"
    88   | Single typ => if typ = HOLogic.boolT then "(__=__)" else "__"
    89 
    90 type pre_model_single = (m_field * (descriptor * term) * Position.T)
    91 datatype pre_model_single' =
    92     Empty of (m_field * (descriptor * empty_input) * Position.T)
    93   | Proper of (m_field * (descriptor * term) * Position.T)
    94 type pre_model = pre_model_single list
    95 type pre_model' = pre_model_single' list
    96 
    97 (*val split_descriptor: Proof.context -> m_field * term * Position.T ->
    98     m_field * (descriptor * term)(* * Position.T*)*)
    99 fun split_descriptor ctxt (m_field: string, dsc_tm, pos) = 
   100   let
   101     val (m_field, (hd, arg)) = case strip_comb dsc_tm of
   102       (hd, [arg]) => (m_field, (hd, arg))
   103     | _ => error ("Wrong descriptor " ^ quote (UnparseC.term ctxt dsc_tm) ^ Position.here pos)
   104   in (m_field, (hd, arg), pos) end
   105 
   106 (*val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) -> m_field * term*)
   107 fun parse_term ctxt (m_field, (str, pos)) =
   108   (m_field, ParseC.term_position ctxt (str, pos), pos)
   109 
   110 fun is_undefined tm =
   111   if Term.exists_subterm (fn Const ("HOL.undefined", _) => true | _ => false) tm then true else false
   112 fun parse_empty_input ctxt (m_field, (str, pos)) =
   113   let
   114     val (m_field, term, pos) = parse_term ctxt (m_field, (str, pos))
   115     val (m_field, (descr, arg), pos) = split_descriptor ctxt (m_field, term, pos)
   116   in
   117     if is_undefined arg
   118     then Empty (m_field, (descr, descr |> empty_for), pos)
   119     else Proper (m_field, (descr, arg), pos)
   120   end 
   121 
   122 fun parse_pattern ctxt (m_field, (str, pos)) =
   123   (m_field, ParseC.pattern_position ctxt (str, pos), pos)
   124 
   125 fun parse_pos ctxt model_input =
   126   let
   127     val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
   128     val model = items 
   129       |> filter_out ((fn f => (fn (f', _) => f = f')) "#Where") 
   130       |> map (parse_term ctxt)
   131       |> map (split_descriptor ctxt)
   132     val where_ = items 
   133       |> filter ((fn f => (fn (f', _) => f = f')) "#Where") 
   134       |> map (parse_pattern ctxt)
   135       |> map (fn (_, a, b) => (a, b))
   136   in (model, where_) end
   137 fun parse_pos_empty ctxt model_input =
   138   let
   139     val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
   140     val model = items 
   141       |> filter_out ((fn f => (fn (f', _) => f = f')) "#Where")
   142       |> map (parse_empty_input ctxt)
   143     val where_ = items 
   144       |> filter ((fn f => (fn (f', _) => f = f')) "#Where") 
   145       |> map (parse_pattern ctxt)
   146       |> map (fn (_, a, b) => (a, b))
   147   in (model, where_) end
   148 
   149 fun pat2str ctxt (field, (dsc, id)) =
   150   pair2str (field, pair2str (UnparseC.term ctxt dsc, UnparseC.term ctxt id));
   151 fun to_string ctxt pats = (strs2str o (map (pat2str ctxt))) pats;
   152 
   153 \<^isac_test>\<open>
   154 (**)
   155 \<close>
   156 
   157 (* get the variables out of a pbl_; FIXME.WN.0311: is_copy_named ...obscure!!! *)
   158 fun variables pbl_ = 
   159   let
   160     fun var_of_pbl_ (_, (_, t)) = t: term
   161   in ((map var_of_pbl_)(* o (filter_out is_copy_named)*)) pbl_ end
   162 
   163 fun get_field descriptor m_patt = 
   164   (filter ((curry (fn (desc, (_, (desc', _))) => desc = desc')) descriptor) m_patt
   165     |> the_single
   166     |> (fn (a, _) => SOME a))
   167   handle List.Empty => NONE
   168   datatype for = Problem | Method | Undef
   169 
   170 
   171 (* adapt type of terms with most general type to a more specific one *)
   172 fun adapt_to_type ctxt (field, (descr, term_as_string)) =
   173   (field, (ParseC.adapt_term_to_type ctxt descr, ParseC.adapt_term_to_type ctxt term_as_string))
   174 
   175 (**)end(*struct*)