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(**)
|