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