src/Tools/isac/MathEngBasic/problem.sml
author wneuper <Walther.Neuper@jku.at>
Thu, 04 Aug 2022 12:48:37 +0200
changeset 60509 2e0b7ca391dc
parent 60502 474a00f8b91e
child 60517 e1ca211459d1
permissions -rw-r--r--
polish naming in Rewrite_Order
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@60442
     9
  val empty: T
walther@59894
    10
walther@59972
    11
  type id = Probl_Def.id
walther@59972
    12
  type id_reverse
walther@59903
    13
  val id_empty: id
walther@59903
    14
  val id_to_string: id -> string
walther@59903
    15
Walther@60454
    16
  type input                          
walther@59973
    17
  type model_input
walther@59973
    18
  val split_did: term -> term * term
Walther@60487
    19
  val split_did_PIDE: term -> term * term
walther@59973
    20
  (* TODO: ---------- remove always empty --- vvvvvvvvvvv -- vvv*)
walther@59973
    21
  val prep_input : theory -> Check_Unique.id -> string list -> id -> input -> T * id                       
Walther@60487
    22
  val prep_input_PIDE : theory -> Check_Unique.id -> string list -> id -> input -> T * id                       
walther@59973
    23
wenzelm@60306
    24
  val set_data: Rule_Def.rule_set -> theory -> theory
wenzelm@60306
    25
  val the_data: theory -> Rule_Def.rule_set
wenzelm@60306
    26
wenzelm@60306
    27
  val parse_item: string parser -> 'a parser -> 'a parser
wenzelm@60314
    28
  val parse_item_name: string parser -> string -> string parser
wenzelm@60314
    29
  val parse_item_names: string parser -> string list parser
wenzelm@60306
    30
  val parse_model_input: model_input parser
wenzelm@60306
    31
  val parse_authors: string list parser
Walther@60434
    32
  val parse_cas: Token.T list -> string option * Token.T list
Walther@60434
    33
  val parse_methods: string list parser
Walther@60434
    34
  val ml: string -> ML_Lex.token Antiquote.antiquote list
wenzelm@60306
    35
walther@59970
    36
  val from_store: id -> T
walther@59894
    37
end
walther@59894
    38
walther@59894
    39
(**)
walther@59894
    40
structure Problem(**): PROBLEM(**) =
walther@59894
    41
struct
walther@59894
    42
(**)
walther@59894
    43
walther@59894
    44
type T = Probl_Def.T;
Walther@60442
    45
val empty = Probl_Def.empty
walther@59894
    46
walther@59970
    47
(*
walther@60154
    48
  elements if the id are in reverse order as compared to MethodC:
walther@59970
    49
  e.g. ["linear", "univariate", "equation"] has "equation" as parent node --
walther@59970
    50
  -- this makes the id readable.
walther@59970
    51
*)
walther@59903
    52
type id = Probl_Def.id;
walther@60154
    53
(* same order as for MethodC (used in Store )*)
walther@59972
    54
type id_reverse = Probl_Def.id;
walther@59970
    55
walther@59903
    56
val id_empty = Probl_Def.id_empty;
walther@59903
    57
val id_to_string = Probl_Def.id_to_string;
walther@59894
    58
walther@59973
    59
walther@59973
    60
(** prepare Problem for Store **)
walther@59973
    61
walther@60004
    62
type model_input =
walther@60004
    63
  (Model_Pattern.m_field *     (* "#Given", "#Find", "#Where", "#Relate" *)
walther@60004
    64
    TermC.as_string list)      (* list of items belonging to m_field     *)
walther@60004
    65
  list;                        (* list of "#Given" .. "#Relate"          *)
walther@59973
    66
type input =
walther@60004
    67
  id *                         (* the key into the problem hierarchy     *)
walther@60004
    68
  model_input *                (* e.g. ("#Given", ["unsorted u_u"]) list *)
walther@60004
    69
  Rule_Set.T *                 (* for evaluating "#Where"                *)
walther@60004
    70
  TermC.as_string option *     (* CAS_Cmd                                *)
walther@60004
    71
  Meth_Def.id list;            (* methods that can solve the problem     *)
walther@59973
    72
walther@59973
    73
(* split a term into description and (id | structured variable) for pbt, met.ppc *)
walther@59973
    74
fun split_did t =
walther@59973
    75
  let
walther@59973
    76
    val (hd, arg) = case strip_comb t of
walther@59973
    77
      (hd, [arg]) => (hd, arg)
walther@59973
    78
    | _ => raise ERROR ("split_did: doesn't match (hd,[arg]) for t = " ^ UnparseC.term t)
walther@59973
    79
  in (hd, arg) end
Walther@60487
    80
fun split_did_PIDE t =
Walther@60487
    81
  let
Walther@60487
    82
    val (hd, arg) = case strip_comb t of
Walther@60487
    83
      (hd, [arg]) => (hd, arg)
Walther@60487
    84
    | _ => raise ERROR ("split_did_PIDE: doesn't match (hd,[arg]) for t = xxxxx" (*^ UnparseC.term t*))
Walther@60487
    85
  in (hd, arg) end
walther@59973
    86
walther@59973
    87
(* prepare problem-types before storing in pbltypes; 
walther@59973
    88
   dont forget to "check_guh_unique" before ins   *)
wenzelm@60306
    89
fun prep_input thy guh maa init ((pblID, dsc_dats, ev, ca, metIDs): input) : T * id =
walther@59973
    90
    let
walther@59973
    91
      fun eq f (f', _) = f = f';
walther@59973
    92
      val gi = filter (eq "#Given") dsc_dats;
walther@59973
    93
      val gi = (case gi of
walther@59973
    94
		    [] => []
walther@60265
    95
		  | ((_, gi') :: []) =>
walther@60417
    96
        (case \<^try>\<open> map (split_did o (TermC.parseNEW'' thy)) gi'\<close> of
walther@60265
    97
          SOME x => x
walther@60265
    98
        | NONE => raise ERROR ("prep_input: syntax raise ERROR in '#Given' of " ^ strs2str pblID))
walther@59973
    99
		  | _ => raise ERROR ("prep_input: more than one '#Given' in " ^ strs2str pblID));
walther@59973
   100
		  val gi = map (pair "#Given") gi;
walther@59973
   101
walther@59973
   102
		  val fi = filter (eq "#Find") dsc_dats;
walther@59973
   103
		  val fi = (case fi of
walther@59973
   104
		    [] => []
walther@60265
   105
		  | ((_, fi') :: []) =>
walther@60417
   106
        (case \<^try>\<open> map (split_did o (TermC.parseNEW'' thy)) fi'\<close> of
walther@60265
   107
          SOME x => x
walther@60265
   108
        | NONE => raise ERROR ("prep_input: syntax raise ERROR in '#Find' of " ^ strs2str pblID))
walther@59973
   109
		  | _ => raise ERROR ("prep_input: more than one '#Find' in " ^ strs2str pblID));
walther@59973
   110
		  val fi = map (pair "#Find") fi;
walther@59973
   111
walther@59973
   112
		  val re = filter (eq "#Relate") dsc_dats;
walther@59973
   113
		  val re = (case re of
walther@59973
   114
		    [] => []
walther@60265
   115
		  | ((_, re') :: []) =>
walther@60417
   116
        (case \<^try>\<open> map (split_did o (TermC.parseNEW'' thy)) re'\<close> of
walther@60265
   117
          SOME x => x
walther@60265
   118
        | NONE => raise ERROR ("prep_input: syntax raise ERROR in '#Relate' of " ^ strs2str pblID))
walther@59973
   119
		  | _ => raise ERROR ("prep_input: more than one '#Relate' in " ^ strs2str pblID));
walther@59973
   120
		  val re = map (pair "#Relate") re;
walther@59973
   121
walther@59973
   122
		  val wh = filter (eq "#Where") dsc_dats;
walther@59973
   123
		  val wh = (case wh of
walther@59973
   124
		    [] => []
walther@60265
   125
		  | ((_, wh') :: []) =>
walther@60265
   126
        (case \<^try>\<open> map (TermC.parse_patt thy) wh'\<close> of
walther@60265
   127
          SOME x => x
walther@60265
   128
        | NONE => raise ERROR ("prep_input: syntax raise ERROR in '#Where' of " ^ strs2str pblID))
walther@59973
   129
		  | _ => raise ERROR ("prep_input: more than one '#Where' in " ^ strs2str pblID));
walther@59973
   130
    in
walther@59973
   131
      ({guh = guh, mathauthors = maa, init = init, thy = thy,
walther@60417
   132
        cas = Option.map (TermC.parseNEW'' thy) ca,
walther@59973
   133
			  prls = ev, where_ = wh, ppc = gi @ fi @ re, met = metIDs}, pblID)
walther@59973
   134
    end;
Walther@60487
   135
fun prep_input_PIDE thy guh maa init (pblID, dsc_dats, ev, ca, metIDs) =
Walther@60487
   136
    let
Walther@60487
   137
      fun eq f (f', _) = f = f';
Walther@60487
   138
val _ = writeln "#prep_input_PIDE 1";
Walther@60487
   139
      val gi = filter (eq "#Given") dsc_dats;
Walther@60487
   140
val _ = writeln "#prep_input_PIDE 1a";
Walther@60487
   141
      val gi = (case gi of
Walther@60487
   142
		    [] => []
Walther@60487
   143
		  | ((_, gi') :: []) =>
Walther@60487
   144
        (*(case \<^try>\<open> *)map (split_did_PIDE o (Syntax.read_term_global thy)) gi'(*\<close> of
Walther@60487
   145
          SOME x => x
Walther@60487
   146
        | NONE => raise ERROR ("prep_input_PIDE: syntax raise ERROR in '#Given' of " ^ strs2str pblID))*)
Walther@60487
   147
		  | _ => raise ERROR ("prep_input_PIDE: more than one '#Given' in xxxxx" (*^ strs2str pblID*)));
Walther@60487
   148
val _ = writeln "#prep_input_PIDE 1b";
Walther@60487
   149
		  val gi = map (pair "#Given") gi;
Walther@60487
   150
Walther@60487
   151
val _ = writeln "#prep_input_PIDE 2";
Walther@60487
   152
		  val fi = filter (eq "#Find") dsc_dats;
Walther@60487
   153
		  val fi = (case fi of
Walther@60487
   154
		    [] => []
Walther@60487
   155
		  | ((_, fi') :: []) =>
Walther@60487
   156
        (*(case \<^try>\<open> *)map (split_did_PIDE o (Syntax.read_term_global thy)) fi'(*\<close> of
Walther@60487
   157
          SOME x => x
Walther@60487
   158
        | NONE => raise ERROR ("prep_input_PIDE: syntax raise ERROR in '#Find' of " ^ strs2str pblID))*)
Walther@60487
   159
		  | _ => raise ERROR ("prep_input_PIDE: more than one '#Find' in xxxxx" (*^ strs2str pblID*)));
Walther@60487
   160
		  val fi = map (pair "#Find") fi;
Walther@60487
   161
Walther@60487
   162
val _ = writeln "#prep_input_PIDE 3";
Walther@60487
   163
		  val re = filter (eq "#Relate") dsc_dats;
Walther@60487
   164
		  val re = (case re of
Walther@60487
   165
		    [] => []
Walther@60487
   166
		  | ((_, re') :: []) =>
Walther@60487
   167
        (*(case \<^try>\<open> *)map (split_did_PIDE o (Syntax.read_term_global thy)) re'(*\<close> of
Walther@60487
   168
          SOME x => x
Walther@60487
   169
        | NONE => raise ERROR ("prep_input_PIDE: syntax raise ERROR in '#Relate' of " ^ strs2str pblID))*)
Walther@60487
   170
		  | _ => raise ERROR ("prep_input_PIDE: more than one '#Relate' in xxxxx" (*^ strs2str pblID*)));
Walther@60487
   171
		  val re = map (pair "#Relate") re;
Walther@60487
   172
Walther@60487
   173
val _ = writeln "#prep_input_PIDE 4";
Walther@60487
   174
		  val wh = filter (eq "#Where") dsc_dats;
Walther@60487
   175
		  val wh = (case wh of
Walther@60487
   176
		    [] => []
Walther@60487
   177
		  | ((_, wh') :: []) =>
Walther@60487
   178
        (*(case \<^try>\<open> *)map (TermC.parse_patt thy) wh'(*\<close> of
Walther@60487
   179
          SOME x => x
Walther@60487
   180
        | NONE => raise ERROR ("prep_input_PIDE: syntax raise ERROR in '#Where' of " ^ strs2str pblID))*)
Walther@60487
   181
		  | _ => raise ERROR ("prep_input_PIDE: more than one '#Where' in xxxxx" (*^ strs2str pblID*)));
Walther@60487
   182
    in
Walther@60487
   183
      ({guh = guh, mathauthors = maa, init = init, thy = thy,
Walther@60487
   184
        cas = Option.map (Syntax.read_term_global thy) ca,
Walther@60487
   185
			  prls = ev, where_ = wh, ppc = gi @ fi @ re, met = metIDs}, pblID)
Walther@60487
   186
    end;
walther@59973
   187
walther@59973
   188
wenzelm@60306
   189
(** Isar command **)
wenzelm@60306
   190
wenzelm@60306
   191
(* theory data *)
wenzelm@60306
   192
wenzelm@60306
   193
structure Data = Theory_Data
wenzelm@60306
   194
(
walther@60373
   195
  type T = Rule_Set.T option;
wenzelm@60306
   196
  val empty = NONE;
wenzelm@60306
   197
  val extend = I;
wenzelm@60306
   198
  fun merge _ = NONE;
wenzelm@60306
   199
);
wenzelm@60306
   200
wenzelm@60306
   201
val set_data = Data.put o SOME;
wenzelm@60306
   202
val the_data = the o Data.get;
wenzelm@60306
   203
wenzelm@60306
   204
wenzelm@60306
   205
(* auxiliary parsers *)
wenzelm@60306
   206
wenzelm@60306
   207
fun parse_item (keyword: string parser) (parse: 'a parser) =
wenzelm@60306
   208
  (keyword -- Args.colon) |-- Parse.!!! parse;
wenzelm@60306
   209
wenzelm@60314
   210
fun parse_item_name keyword =
wenzelm@60314
   211
  Scan.optional (parse_item keyword Parse.name);
wenzelm@60314
   212
wenzelm@60314
   213
fun parse_item_names (keyword: string parser) =
wenzelm@60314
   214
  Scan.optional (parse_item keyword (Scan.repeat1 Parse.name)) [];
wenzelm@60314
   215
wenzelm@60306
   216
fun parse_tagged_terms keyword (tag: string) =
wenzelm@60306
   217
  Scan.optional (parse_item keyword (Scan.repeat Parse.term) >> (fn ts => [(tag, ts)])) [];
wenzelm@60306
   218
wenzelm@60306
   219
val parse_model_input : model_input parser =
wenzelm@60306
   220
  parse_tagged_terms \<^keyword>\<open>Given\<close> "#Given" @@@
wenzelm@60306
   221
  parse_tagged_terms \<^keyword>\<open>Where\<close> "#Where" @@@
wenzelm@60306
   222
  parse_tagged_terms \<^keyword>\<open>Find\<close> "#Find" @@@
wenzelm@60306
   223
  parse_tagged_terms \<^keyword>\<open>Relate\<close> "#Relate";
wenzelm@60306
   224
wenzelm@60314
   225
val parse_authors = parse_item_names \<^keyword>\<open>Author\<close>;
Walther@60434
   226
val parse_cas = Scan.option (parse_item \<^keyword>\<open>CAS\<close> Parse.term);
Walther@60449
   227
val parse_methods = parse_item_names \<^keyword>\<open>Method_Ref\<close>;
Walther@60434
   228
val ml = ML_Lex.read;
wenzelm@60306
   229
wenzelm@60306
   230
wenzelm@60306
   231
(* command definition *)
wenzelm@60306
   232
wenzelm@60306
   233
local
wenzelm@60306
   234
wenzelm@60306
   235
val _ =
wenzelm@60306
   236
  Outer_Syntax.command \<^command_keyword>\<open>problem\<close>
wenzelm@60306
   237
    "prepare ISAC problem type and register it to Knowledge Store"
wenzelm@60306
   238
    (Parse.name -- Parse.!!! (\<^keyword>\<open>:\<close> |-- Parse.name --
wenzelm@60306
   239
      Parse.!!! (\<^keyword>\<open>=\<close> |-- Parse.ML_source -- parse_authors --
wenzelm@60306
   240
        parse_methods -- parse_cas -- parse_model_input)) >>
wenzelm@60306
   241
      (fn (name, (id, ((((source, maa), mets), cas), model_input))) =>
wenzelm@60306
   242
        Toplevel.theory (fn thy =>
wenzelm@60306
   243
          let
Walther@60487
   244
(*Ouptut from Biegelinie.problem pbl_bieg : "Biegelinien":*)
wenzelm@60306
   245
            val pblID = References_Def.explode_id id;
wenzelm@60306
   246
            val metIDs = map References_Def.explode_id mets;
Walther@60488
   247
(*val _ = writeln ("#problem source: " ^ @{make_string} source)*)
wenzelm@60314
   248
            val set_data =
wenzelm@60306
   249
              ML_Context.expression (Input.pos_of source)
wenzelm@60306
   250
                (ml "Theory.setup (Problem.set_data (" @ ML_Lex.read_source source @ ml "))")
wenzelm@60306
   251
              |> Context.theory_map;
Walther@60488
   252
(*val _ = writeln ("#problem set_data: " ^ @{make_string} set_data)*)
Walther@60487
   253
            (* Context.theory_map HAS STORED THE ml-source IN Theory_Data ALREADY,
Walther@60487
   254
               BUT prep_input_PIDE REQUIRES ml-source AGAIN ... *)
wenzelm@60314
   255
            val input = the_data (set_data thy);
Walther@60488
   256
(*val _ = writeln ("#problem input: " ^ @{make_string} input)*)
Walther@60487
   257
Walther@60488
   258
(*
Walther@60487
   259
val _ = writeln ("#problem model_input: " ^ @{make_string} model_input)
Walther@60487
   260
val (m1, m2) = case model_input of
Walther@60487
   261
  ("#Given", [m1, m2]) :: _ => (m1, m2) (*=("<markup>", "<markup>")*)
Walther@60487
   262
| _ => ("different case model_input", "different case model_input")
Walther@60487
   263
val _ = writeln ("#problem m1: " ^ m1)  (*= Traegerlaenge l_l*)
Walther@60487
   264
val _ = writeln ("#problem m2: " ^ m2)  (*= Streckenlast q_q *)
Walther@60488
   265
            ( * TODO: 
Walther@60487
   266
             * parse_model_input should preserve Position.T, Position.range, etc
Walther@60487
   267
             * ? preserve Position.T etc within ML_Lex.token Antiquote.antiquote list ?.. 
Walther@60487
   268
               ..in analogy to set_data ?!?
Walther@60487
   269
             * by Context.theory_map notify Isabelle/PIDE of errors from model_input at Position.T
Walther@60487
   270
             * in case there are no errors, do prep_input_PIDE (to be simplified)
Walther@60487
   271
             *)
Walther@60487
   272
            val arg = prep_input_PIDE thy name maa id_empty (pblID, model_input, input, cas, metIDs);
Walther@60502
   273
          in KEStore_Elems.add_pbls @{context} [arg] thy end)))
wenzelm@60306
   274
wenzelm@60306
   275
in end;
wenzelm@60306
   276
wenzelm@60306
   277
wenzelm@60306
   278
Walther@60488
   279
(** get Problem from Store **)
walther@59973
   280
Walther@60495
   281
fun from_store id = Store.get (get_pbls ()) id (rev id);
walther@59970
   282
walther@59894
   283
(**)end(**)