1 (* Title: src/Tools/isac/BridgeJEdit/Calculation.thy
2 Author: Walther Neuper, JKU Linz
4 Outer syntax for Isabelle/Isac's Calculation interactive via Isabelle/PIDE.
5 Second trial following Makarius' definition of "problem" already existing in this repository.
10 (**)"$ISABELLE_ISAC/Knowledge/Build_Thydata" (*remove after devel.of BridgeJEdit*)
11 (**)"$ISABELLE_ISAC/MathEngine/MathEngine"
12 keywords "Example" :: thy_decl
13 and "Specification" "Model" "References" "Solution"
18 ML_file "preliminary.sml"
20 section \<open>new code for Outer_Syntax Example ...\<close>
22 stepwise development starts at changeset
23 https://hg.risc.uni-linz.ac.at/wneuper/isa/rev/9d98791b4080
24 and can be inspected following the subsequent changesets..
30 structure Data = Theory_Data
32 type T = Ctree.ctree option;
38 val set_data = Data.put o SOME;
40 case Data.get thy of NONE => Ctree.EmptyPtree
41 | SOME ctree => ctree;
44 A provisional Example collection.
46 For notes from ISAC's discontinued Java front-end see
47 https://isac.miraheze.org/wiki/Extend_ISAC_Knowledge#Add_an_example_in_XML_format
50 val demo_example = ("The efficiency of an electrical coil depends on the mass of the kernel." ^
51 "Given is a kernel with cross-sectional area determined by two rectangles" ^
52 "of same shape as shown in the figure." ^
53 "Given a radius r = 7, determine the length u and width v of the rectangles" ^
54 "such that the cross-sectional area A (and thus the mass of the kernel) is a" ^
58 "Constants [r = (7::real)]", "Maximum A", "AdditionalValues [u, v]",
59 "Extremum (A = 2 * u * v - u \<up> 2)",
60 "SideConditions [((u::real) / 2) \<up> 2 + (2 / v) \<up> 2 = r \<up> 2]",
61 "SideConditions [((u::real) / 2) \<up> 2 + (2 / v) \<up> 2 = r \<up> 2]",
62 "SideConditions [(u::real) / 2 = r * sin \<alpha>, 2 / v = r * cos \<alpha>]",
64 "FunctionVariable a", "FunctionVariable b", "FunctionVariable \<alpha>",
67 "Domain {0 <..< \<pi> / 2}",
68 "ErrorBound (\<epsilon> = (0::real))"]: TermC.as_string list,
69 ("Diff_App", ["univariate_calculus", "Optimisation"],
70 ["Optimisation", "by_univariate_calculus"]): References.T)): Example.T
72 setup \<open>KEStore_Elems.add_expls [(demo_example, ["Diff_App-No.123a"])]\<close>
74 case Store.get (KEStore_Elems.get_expls @{theory}) ["Diff_App-No.123a"] ["Diff_App-No.123a"] of
75 (_, ("Constants [r = (7::real)]" :: "Maximum A" :: "AdditionalValues [u, v]" :: _,
76 ("Diff_App", ["univariate_calculus", "Optimisation"] ,["Optimisation", "by_univariate_calculus"])))
78 | _ => error "intermed. example_store CHANGED";
82 Implementation reasonable, as soo as
83 * clarified, how "empty" items in Model are represented
84 * parse_references_input works
85 * switching \<Odot>\<Otimes> i_model for probl and meth works.
87 fun check_input (*ctxt o-model ??*) (_: Problem.model_input) = []: I_Model.T (*TODO*)
90 (* at the first encounter of an Example create the following data and transfer them to ctree:
91 origin: eventually used by sub-problems, too
92 O_Model: for check of missing items
93 I_Model: for efficient check of user input
96 fun init_ctree example_id =
98 (* TODO vvvvvvvvvvvvvvv works only within Isac_Test_Base *)
99 val thy = (*ThyC.get_theory thy_id*)@{theory Diff_App}
100 val example_id' = References_Def.explode_id example_id
101 val (_, (fmz as (model, refs as (_(*thy_id*), probl_id, _)))) =
102 Store.get (KEStore_Elems.get_expls @{theory}) example_id' example_id'
103 val ctxt = ContextC.initialise' thy model;
105 val o_model = Problem.from_store ctxt probl_id |> #ppc |> O_Model.init thy model
107 Ctree.Nd (Ctree.PblObj {
108 fmz = fmz, origin = (o_model, refs, TermC.empty (*TODO handle CAS_Cmd*)),
109 spec = References.empty, probl = I_Model.empty, meth = I_Model.empty,
110 ctxt = ctxt, loc = (NONE, NONE),
111 branch = Ctree.NoBranch, ostate = Ctree.Incomplete, result = (TermC.empty, [])}, [])
116 * initialise ctree with origin from example_id
117 * add items already input ..TODO..TODO..TODO..TODO..TODO..TODO..TODO..TODO..TODO
120 fun update_state (example_id, (model, refs)) Ctree.EmptyPtree =
121 init_ctree example_id |> update_state (example_id, (model, refs))
122 | update_state (_, (model, (thy_id, probl_id, meth_id)))
123 (Ctree.Nd (Ctree.PblObj {fmz, origin, spec as (othy, opbl, omet), probl = _, meth, ctxt, loc, branch, ostate, result},
126 val _ = if thy_id <> othy then "re-parse all i_model" else "do nothing"
127 val _ = if probl_id <> opbl then "switch from meth? check_input of probl" else "do nothing"
128 val _ = if meth_id <> omet then "switch from probl check_input of meth" else "do nothing"
130 Ctree.Nd (Ctree.PblObj {
131 fmz = fmz, origin = origin, spec = References.select_input spec (thy_id, probl_id, meth_id),
132 probl = check_input model, meth = meth, (*TODO +switch Problem_Ref | Method_Ref*)
133 ctxt = ctxt, loc = loc,
134 branch = branch, ostate = ostate, result = result}, children)
136 | update_state _ _ = raise ERROR "update_state: uncovered case in fun.def"
139 update_state: string * (Problem.model_input * References.T) -> Ctree.ctree -> Ctree.ctree
141 type references_input = (string * (string * string))
143 val parse_references_input =
144 Parse.!!! ( \<^keyword>\<open>Theory_Ref\<close> -- \<^keyword>\<open>Theory_Ref\<close> |-- Parse.name --
145 Parse.!!! ( \<^keyword>\<open>Problem_Ref\<close> -- \<^keyword>\<open>Theory_Ref\<close> |-- Parse.name --
146 Parse.!!! ( \<^keyword>\<open>Method_Ref\<close> -- \<^keyword>\<open>Theory_Ref\<close> |-- Parse.name)))
148 parse_references_input: references_input parser (*TODO: does not yet work,
149 thus in Outer_Syntax.command \<^command_keyword>\<open>Example\<close> replacced by Problem.parse_cas*)
151 op -- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> ('b * 'd) * 'e;
152 op |-- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> 'd * 'e
156 (* but "<markup>" would be required as an argument *)
159 val strl = Symbol.explode str |> rev
161 take (2, strl) = ["_", " "] orelse take (3, strl) = ["]", "_", "["]
164 val m2 = "0 < r"; val m2' = Symbol.explode m2 |> rev;
165 val m3 = "Maximum _"; val m3' = Symbol.explode m3 |> rev;
166 val m4 = "AdditionalValues [_]"; val m4' = Symbol.explode m4 |> rev;
170 Outer_Syntax.command \<^command_keyword>\<open>Example\<close>
171 "prepare ISAC problem type and register it to Knowledge Store"
172 (Parse.name -- Parse.!!! ( \<^keyword>\<open>Specification\<close> -- \<^keyword>\<open>:\<close> --
173 \<^keyword>\<open>Model\<close> -- \<^keyword>\<open>:\<close> |-- Problem.parse_model_input --
174 Parse.!!! ( \<^keyword>\<open>References\<close> -- \<^keyword>\<open>:\<close> |-- (*parse_references_input*) Problem.parse_cas)) >>
175 (fn (example_id, (model_input, _(*references_input*))) =>
176 Toplevel.theory (fn thy =>
179 val _ = writeln ("#Example model_input: " ^ @{make_string} model_input)
180 (* #Example model_input:
181 [("#Given", ["<markup>"]), ("#Where", ["<markup>"]), ("#Find", ["<markup>", "<markup>"]), ("#Relate", ["<markup>", "<markup>"])]*)
182 val [("#Given", [m1]), ("#Where", [m2]), ("#Find", [m3, m4]), ("#Relate", [m5, m6])] =
183 model_input : Problem.model_input
184 val _ = writeln ("#Example m.: " ^ m1 ^ " " ^ m2 ^ " " ^ m3 ^ " " ^ m4 ^ " " ^ m4 ^ " " ^ m5 ^ " " ^ m6)
186 val m2' = Symbol.explode m2;
187 val _ = writeln ("#Example Symbol.explode m2: " ^ @{make_string} m2')
188 val _ = if (is_empty m2) then writeln "true" else writeln "false";
189 val _ = if (is_empty m3) then writeln "true" else writeln "false";
190 val _ = if (is_empty m4) then writeln "true" else writeln "false";
191 (* #Example m.: Constants [r = 7] 0 < r Maximum _ AdditionalValues [_] AdditionalValues [_] Extremum _ SideCondition [_]*)
193 val (thy_id, (probl_id, meth_id)) = (*references_input*)("Diff_App", ("univariate_calculus/Optimisation", "Optimisation/by_univariate_calculus"))
194 val input = update_state (example_id, (model_input,
195 (thy_id, References_Def.explode_id probl_id, References_Def.explode_id meth_id)))
197 in set_data input thy end)));
200 (*/----------------------------------------------------------------------------\*)
201 Parse.name -- Parse.!!! ( \<^keyword>\<open>Specification\<close> -- \<^keyword>\<open>:\<close> --
202 \<^keyword>\<open>Model\<close> -- \<^keyword>\<open>:\<close> |-- Problem.parse_model_input --
203 Parse.!!! ( \<^keyword>\<open>References\<close> -- \<^keyword>\<open>:\<close> |-- parse_references_input))
204 (*: (string * (Problem.model_input * references_input)) parser*)
205 (*\----------------------------------------------------------------------------/*)
207 (*/----------------------------------------------------------------------------\*)
208 (string * (Problem.model_input * references_input))
209 (*\----------------------------------------------------------------------------/*)
211 (*/----------------------------------------------------------------------------\* )
212 the type above is the type of the argument of \<open>(fn (_(*name*),..\<close>
213 ( *\----------------------------------------------------------------------------/*)
216 \<close> text \<open>
217 INVESTIGATE Problem.Outer_Syntax.command \ <^command_keyword>\<open>problem\<close>
218 on Biegelinie.problem pbl_bieg : "Biegelinien"
220 ML-source shows error-positions already perfectly: what types are involved?..
222 Rule_Set.append_rules "empty" Rule_Set.empty [] (* ORIGINAL source = ARGUMENT IN fn *)
224 Ouptut from Biegelinie.problem pbl_bieg : "Biegelinien":
225 #problem source: Source {delimited = true, range = ({offset=38, end_offset=87, id=-1652}, {offset=87, id=-1652}),
226 text = "\127Rule_Set.append_rules \"empty\" Rule_Set.empty []\127"}
229 val source = Input.empty;
230 val ml = ML_Lex.read;
232 (ml "Theory.setup (Problem.set_data (" @ ML_Lex.read_source source @ ml "))")
234 [Text (Token (({}, {}), (Long_Ident, "Theory.setup"))), Text (Token (({}, {}), (Space, " "))), Text (Token (({}, {}), (Keyword, "("))), Text (Token (({}, {}), (Long_Ident, "Problem.set_data"))),
235 Text (Token (({}, {}), (Space, " "))), Text (Token (({}, {}), (Keyword, "("))), Text (Token (({}, {}), (Space, " "))), Text (Token (({}, {}), (Keyword, ")"))), Text (Token (({}, {}), (Keyword, ")"))),
236 Text (Token (({}, {}), (Space, " ")))]
237 : ML_Lex.token Antiquote.antiquote list
238 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type of (1a)
241 ML_Context.expression (Input.pos_of source)
242 (ml "Theory.setup (Problem.set_data (" @ ML_Lex.read_source source @ ml "))")
243 : Context.generic -> Context.generic
245 ML_Context.expression (Input.pos_of source)
246 (ml "Theory.setup (Problem.set_data (" @ ML_Lex.read_source source @ ml "))")
247 |> Context.theory_map
250 Outer_Syntax.command: Outer_Syntax.command_keyword -> string ->
251 (Toplevel.transition -> Toplevel.transition) parser -> unit
253 \<close> text \<open>
254 ML-source shows error-positions already perfectly: types involved are above.
256 Input at Given does NOT show error-position,
257 but ISAC msg \<open>ME_Isa: thy "Isac_Knowledge" not in system\<close>
259 Thus compare ML-source/input with model_input ...
261 Problem.parse_model_input: Problem.model_input parser;
262 Problem.parse_model_input: Token.src -> Problem.model_input * Token.src;
263 Problem.parse_model_input: Token.T list -> Problem.model_input * (Token.T list)
265 []: Position.range list;
269 (* Given: "Traegerlaenge l_l" "Streckenlast q_q" *)
271 Ouptut from Biegelinie.problem pbl_bieg : "Biegelinien":
272 #problem model_input: [("#Given", ["<markup>", "<markup>"]), ("#Find", ["<markup>"]), ("#Relate", ["<markup>"])]
273 : Problem.model_input
274 type of (1b) --------^^^^^^^^^^^^^^^^^^^^^^> contains ? Markup.T ?..
276 #problem m1: Traegerlaenge l_l
277 #problem m2: Streckenlast q_q
278 I this -----^^^______________^^^ Markup.T ?
280 \<close> ML \<open> (** investigate parse_model_input **)
281 \<close> ML \<open> (* how get a Token.T list without Outer_Syntax.command ? *)
283 Parse.term: string parser;
284 Parse.term: Token.T list -> string * Token.T list;
286 \<close> ML \<open> (* relation Token.T -- Markup.T ??? *)
288 val ctxt = Proof_Context.init_global @{theory};
289 val given_1 = Syntax.read_term ctxt "Traegerlaenge l_l" (* as in parse_tagged_terms *)
290 (* ^^^^^^^ : term -- why then evaluates parse_model_input to markup ? *)
293 Markup.literal_fact "Traegerlaenge l_l" = ("literal_fact", [("name", "Traegerlaenge l_l")])