src/Tools/isac/MathEngBasic/problem.sml
author wneuper <walther.neuper@jku.at>
Tue, 20 Jul 2021 14:37:56 +0200
changeset 60339 0d22a6bf1fc6
parent 60314 1cf9c607fa6a
child 60340 0ee698b0a703
permissions -rw-r--r--
//reduce the number of TermC.parse*; "//"means: tests broken .

broken tests are outcommented with "reduce the number of TermC.parse*"
walther@59894
     1
(* Title:  MathEngBasic/problem.sml
walther@59894
     2
   Author: Walther Neuper 2019
walther@59894
     3
   (c) due to copyright terms
walther@59894
     4
*)
walther@59894
     5
walther@59894
     6
signature PROBLEM =
walther@59894
     7
sig
walther@59894
     8
  type T = Probl_Def.T
walther@59894
     9
walther@59972
    10
  type id = Probl_Def.id
walther@59972
    11
  type id_reverse
walther@59903
    12
  val id_empty: id
walther@59903
    13
  val id_to_string: id -> string
walther@59903
    14
walther@59973
    15
  type input
walther@59973
    16
  type model_input
walther@59973
    17
  val split_did: term -> term * term
walther@59973
    18
  (* TODO: ---------- remove always empty --- vvvvvvvvvvv -- vvv*)
walther@59973
    19
  val prep_input : theory -> Check_Unique.id -> string list -> id -> input -> T * id                       
walther@59973
    20
wenzelm@60306
    21
  val set_data: Rule_Def.rule_set -> theory -> theory
wenzelm@60306
    22
  val the_data: theory -> Rule_Def.rule_set
wenzelm@60306
    23
wenzelm@60306
    24
  val parse_item: string parser -> 'a parser -> 'a parser
wenzelm@60314
    25
  val parse_item_name: string parser -> string -> string parser
wenzelm@60314
    26
  val parse_item_names: string parser -> string list parser
wenzelm@60306
    27
  val parse_model_input: model_input parser
wenzelm@60306
    28
  val parse_authors: string list parser
wenzelm@60306
    29
walther@59970
    30
  val from_store: id -> T
walther@59894
    31
end
walther@59894
    32
walther@59894
    33
(**)
walther@59894
    34
structure Problem(**): PROBLEM(**) =
walther@59894
    35
struct
walther@59894
    36
(**)
walther@59894
    37
walther@59894
    38
type T = Probl_Def.T;
walther@59894
    39
walther@59970
    40
(*
walther@60154
    41
  elements if the id are in reverse order as compared to MethodC:
walther@59970
    42
  e.g. ["linear", "univariate", "equation"] has "equation" as parent node --
walther@59970
    43
  -- this makes the id readable.
walther@59970
    44
*)
walther@59903
    45
type id = Probl_Def.id;
walther@60154
    46
(* same order as for MethodC (used in Store )*)
walther@59972
    47
type id_reverse = Probl_Def.id;
walther@59970
    48
walther@59903
    49
val id_empty = Probl_Def.id_empty;
walther@59903
    50
val id_to_string = Probl_Def.id_to_string;
walther@59894
    51
walther@59973
    52
walther@59973
    53
(** prepare Problem for Store **)
walther@59973
    54
walther@60004
    55
type model_input =
walther@60004
    56
  (Model_Pattern.m_field *     (* "#Given", "#Find", "#Where", "#Relate" *)
walther@60004
    57
    TermC.as_string list)      (* list of items belonging to m_field     *)
walther@60004
    58
  list;                        (* list of "#Given" .. "#Relate"          *)
walther@59973
    59
type input =
walther@60004
    60
  id *                         (* the key into the problem hierarchy     *)
walther@60004
    61
  model_input *                (* e.g. ("#Given", ["unsorted u_u"]) list *)
walther@60004
    62
  Rule_Set.T *                 (* for evaluating "#Where"                *)
walther@60004
    63
  TermC.as_string option *     (* CAS_Cmd                                *)
walther@60004
    64
  Meth_Def.id list;            (* methods that can solve the problem     *)
walther@59973
    65
walther@59973
    66
(* split a term into description and (id | structured variable) for pbt, met.ppc *)
walther@59973
    67
fun split_did t =
walther@59973
    68
  let
walther@59973
    69
    val (hd, arg) = case strip_comb t of
walther@59973
    70
      (hd, [arg]) => (hd, arg)
walther@59973
    71
    | _ => raise ERROR ("split_did: doesn't match (hd,[arg]) for t = " ^ UnparseC.term t)
walther@59973
    72
  in (hd, arg) end
walther@59973
    73
walther@59973
    74
(* prepare problem-types before storing in pbltypes; 
walther@59973
    75
   dont forget to "check_guh_unique" before ins   *)
wenzelm@60306
    76
fun prep_input thy guh maa init ((pblID, dsc_dats, ev, ca, metIDs): input) : T * id =
walther@59973
    77
    let
walther@59973
    78
      fun eq f (f', _) = f = f';
walther@59973
    79
      val gi = filter (eq "#Given") dsc_dats;
walther@59973
    80
      val gi = (case gi of
walther@59973
    81
		    [] => []
walther@60265
    82
		  | ((_, gi') :: []) =>
walther@60339
    83
        (case \<^try>\<open> map (split_did o (TermC.parseNEW'' thy)) gi'\<close> of
walther@60265
    84
          SOME x => x
walther@60265
    85
        | NONE => raise ERROR ("prep_input: syntax raise ERROR in '#Given' of " ^ strs2str pblID))
walther@59973
    86
		  | _ => raise ERROR ("prep_input: more than one '#Given' in " ^ strs2str pblID));
walther@59973
    87
		  val gi = map (pair "#Given") gi;
walther@59973
    88
walther@59973
    89
		  val fi = filter (eq "#Find") dsc_dats;
walther@59973
    90
		  val fi = (case fi of
walther@59973
    91
		    [] => []
walther@60265
    92
		  | ((_, fi') :: []) =>
walther@60339
    93
        (case \<^try>\<open> map (split_did o (TermC.parseNEW'' thy)) fi'\<close> of
walther@60265
    94
          SOME x => x
walther@60265
    95
        | NONE => raise ERROR ("prep_input: syntax raise ERROR in '#Find' of " ^ strs2str pblID))
walther@59973
    96
		  | _ => raise ERROR ("prep_input: more than one '#Find' in " ^ strs2str pblID));
walther@59973
    97
		  val fi = map (pair "#Find") fi;
walther@59973
    98
walther@59973
    99
		  val re = filter (eq "#Relate") dsc_dats;
walther@59973
   100
		  val re = (case re of
walther@59973
   101
		    [] => []
walther@60265
   102
		  | ((_, re') :: []) =>
walther@60339
   103
        (case \<^try>\<open> map (split_did o (TermC.parseNEW'' thy)) re'\<close> of
walther@60265
   104
          SOME x => x
walther@60265
   105
        | NONE => raise ERROR ("prep_input: syntax raise ERROR in '#Relate' of " ^ strs2str pblID))
walther@59973
   106
		  | _ => raise ERROR ("prep_input: more than one '#Relate' in " ^ strs2str pblID));
walther@59973
   107
		  val re = map (pair "#Relate") re;
walther@59973
   108
walther@59973
   109
		  val wh = filter (eq "#Where") dsc_dats;
walther@59973
   110
		  val wh = (case wh of
walther@59973
   111
		    [] => []
walther@60265
   112
		  | ((_, wh') :: []) =>
walther@60265
   113
        (case \<^try>\<open> map (TermC.parse_patt thy) wh'\<close> of
walther@60265
   114
          SOME x => x
walther@60265
   115
        | NONE => raise ERROR ("prep_input: syntax raise ERROR in '#Where' of " ^ strs2str pblID))
walther@59973
   116
		  | _ => raise ERROR ("prep_input: more than one '#Where' in " ^ strs2str pblID));
walther@59973
   117
    in
walther@59973
   118
      ({guh = guh, mathauthors = maa, init = init, thy = thy,
walther@60339
   119
        cas = Option.map (TermC.parseNEW'' thy) ca,
walther@59973
   120
			  prls = ev, where_ = wh, ppc = gi @ fi @ re, met = metIDs}, pblID)
walther@59973
   121
    end;
walther@59973
   122
walther@59973
   123
wenzelm@60306
   124
(** Isar command **)
wenzelm@60306
   125
wenzelm@60306
   126
(* theory data *)
wenzelm@60306
   127
wenzelm@60306
   128
structure Data = Theory_Data
wenzelm@60306
   129
(
wenzelm@60306
   130
  type T = Rule_Def.rule_set option;
wenzelm@60306
   131
  val empty = NONE;
wenzelm@60306
   132
  val extend = I;
wenzelm@60306
   133
  fun merge _ = NONE;
wenzelm@60306
   134
);
wenzelm@60306
   135
wenzelm@60306
   136
val set_data = Data.put o SOME;
wenzelm@60306
   137
val the_data = the o Data.get;
wenzelm@60306
   138
wenzelm@60306
   139
wenzelm@60306
   140
(* auxiliary parsers *)
wenzelm@60306
   141
wenzelm@60306
   142
fun parse_item (keyword: string parser) (parse: 'a parser) =
wenzelm@60306
   143
  (keyword -- Args.colon) |-- Parse.!!! parse;
wenzelm@60306
   144
wenzelm@60314
   145
fun parse_item_name keyword =
wenzelm@60314
   146
  Scan.optional (parse_item keyword Parse.name);
wenzelm@60314
   147
wenzelm@60314
   148
fun parse_item_names (keyword: string parser) =
wenzelm@60314
   149
  Scan.optional (parse_item keyword (Scan.repeat1 Parse.name)) [];
wenzelm@60314
   150
wenzelm@60306
   151
fun parse_tagged_terms keyword (tag: string) =
wenzelm@60306
   152
  Scan.optional (parse_item keyword (Scan.repeat Parse.term) >> (fn ts => [(tag, ts)])) [];
wenzelm@60306
   153
wenzelm@60306
   154
val parse_model_input : model_input parser =
wenzelm@60306
   155
  parse_tagged_terms \<^keyword>\<open>Given\<close> "#Given" @@@
wenzelm@60306
   156
  parse_tagged_terms \<^keyword>\<open>Where\<close> "#Where" @@@
wenzelm@60306
   157
  parse_tagged_terms \<^keyword>\<open>Find\<close> "#Find" @@@
wenzelm@60306
   158
  parse_tagged_terms \<^keyword>\<open>Relate\<close> "#Relate";
wenzelm@60306
   159
wenzelm@60314
   160
val parse_authors = parse_item_names \<^keyword>\<open>Author\<close>;
wenzelm@60306
   161
wenzelm@60306
   162
wenzelm@60306
   163
(* command definition *)
wenzelm@60306
   164
wenzelm@60306
   165
local
wenzelm@60306
   166
wenzelm@60314
   167
val parse_methods = parse_item_names \<^keyword>\<open>Method\<close>;
wenzelm@60306
   168
val parse_cas = Scan.option (parse_item \<^keyword>\<open>CAS\<close> Parse.term);
wenzelm@60306
   169
wenzelm@60306
   170
val ml = ML_Lex.read;
wenzelm@60306
   171
wenzelm@60306
   172
val _ =
wenzelm@60306
   173
  Outer_Syntax.command \<^command_keyword>\<open>problem\<close>
wenzelm@60306
   174
    "prepare ISAC problem type and register it to Knowledge Store"
wenzelm@60306
   175
    (Parse.name -- Parse.!!! (\<^keyword>\<open>:\<close> |-- Parse.name --
wenzelm@60306
   176
      Parse.!!! (\<^keyword>\<open>=\<close> |-- Parse.ML_source -- parse_authors --
wenzelm@60306
   177
        parse_methods -- parse_cas -- parse_model_input)) >>
wenzelm@60306
   178
      (fn (name, (id, ((((source, maa), mets), cas), model_input))) =>
wenzelm@60306
   179
        Toplevel.theory (fn thy =>
wenzelm@60306
   180
          let
wenzelm@60306
   181
            val pblID = References_Def.explode_id id;
wenzelm@60306
   182
            val metIDs = map References_Def.explode_id mets;
wenzelm@60314
   183
            val set_data =
wenzelm@60306
   184
              ML_Context.expression (Input.pos_of source)
wenzelm@60306
   185
                (ml "Theory.setup (Problem.set_data (" @ ML_Lex.read_source source @ ml "))")
wenzelm@60306
   186
              |> Context.theory_map;
wenzelm@60314
   187
            val input = the_data (set_data thy);
wenzelm@60306
   188
            val arg = prep_input thy name maa id_empty (pblID, model_input, input, cas, metIDs);
wenzelm@60306
   189
          in KEStore_Elems.add_pbts [arg] thy end)))
wenzelm@60306
   190
wenzelm@60306
   191
in end;
wenzelm@60306
   192
wenzelm@60306
   193
wenzelm@60306
   194
walther@60154
   195
(** get MethodC from Store **)
walther@59973
   196
walther@59973
   197
fun from_store id = Store.get (get_ptyps ()) id (rev id);
walther@59970
   198
walther@59894
   199
(**)end(**)