1 (* Title: Interpret/lucas-interpreter.sml
2 Author: Walther Neuper 2019
3 (c) due to copyright terms
6 signature LUCAS_INTERPRETER =
8 datatype input_tactic_result =
9 Safe_Step of Istate.T * Proof.context * Tactic.T
10 | Unsafe_Step of Istate.T * Proof.context * Tactic.T
11 | Not_Locatable of string
12 val locate_input_tactic : Rule.program -> Ctree.state -> Istate.T -> Proof.context -> Tactic.T
13 -> input_tactic_result
15 (*datatype input_formula_result = FStep of calcstate' | Not_Derivable *)
16 datatype input_formula_result =
17 Step of Ctree.state * Istate.T * Proof.context
18 | Not_Derivable of Chead.calcstate'
19 (*val locate_input_formula : Ctree.state -> term -> input_formula_result *)
20 val locate_input_formula : Rule.program -> Ctree.state -> Istate.T -> Proof.context -> term
21 -> input_formula_result
22 (*val begin_end_prog : ???*)
23 val begin_end_prog : Tactic.T -> Istate.T * Proof.context -> Ctree.state ->
24 (Tactic.input * Tactic.T * (Ctree.pos' * (Istate.T * Proof.context))) list * Ctree.pos' list * Ctree.state
25 (*val do_solve_step : Ctree.state -> Ctree.state ???*)
26 val do_solve_step : Ctree.state ->
27 (Tactic.input * Tactic.T * (Ctree.pos' * (Istate.T * Proof.context))) list * Ctree.pos' list * Ctree.state
29 datatype next_tactic_result =
30 NStep of Ctree.state * Istate.T * Proof.context * tactic
31 | Helpless | End_Program
32 (*val determine_next_tactic :
33 Rule.program -> Ctree.state -> Istate.T -> Proof.context -> next_tactic_result *)
34 val determine_next_tactic: Rule.theory' * 'a -> Ctree.state -> Rule.program -> Istate.T * 'b
35 -> Tactic.T * (Istate.T * Proof.context) * (term * Telem.safe)
37 (* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
39 Ackn_Tac1 of Istate.pstate * Proof.context * Tactic.T
40 | Reject_Tac1 of Istate.pstate * Proof.context * Tactic.T
42 val assoc2str : expr_val1 -> string
43 (*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
44 val go : Celem.path -> term -> term
45 val go_up: Celem.path -> term -> term
46 val check_Let_up : Istate.pstate -> term -> term * term
47 val check_Seq_up: Istate.pstate -> term -> term
48 val compare_step : Generate.taci list * Ctree.pos' list * (Ctree.state) -> term -> string * Chead.calcstate'
50 val scan_dn1: (Ctree.state * Proof.context * Tactic.T) -> Istate.pstate -> term -> expr_val1
51 val scan_up1: term * (Ctree.state * Proof.context * Tactic.T) -> Istate.pstate -> term -> expr_val1;
52 val go_scan_up1: term * (Ctree.state * Proof.context * Tactic.T) -> Istate.pstate -> expr_val1;
53 val scan_to_tactic1: term * (Ctree.state * Proof.context * Tactic.T) -> Istate.T -> expr_val1
55 datatype expr_val2 = Ackn_Tac2 of Tactic.T * Istate.pstate | Reject_Tac2 | Term_Val2 of term
56 val scan_dn2: Ctree.state * Rule.theory'(*Proof.context*) -> Istate.pstate -> term -> expr_val2
57 val scan_up2: term * (Ctree.state * Rule.theory') -> Istate.pstate -> term -> expr_val2
58 val go_scan_up2: term * (Ctree.state * Rule.theory') -> Istate.pstate -> expr_val2
59 val scan_to_tactic2: term * (Ctree.state * Rule.theory') -> Istate.T -> expr_val2
60 ( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
64 structure LucinNEW(**): LUCAS_INTERPRETER(**) = (*LucinNEW \<rightarrow> Lucin after code re-arrangement*)
72 (*** auxiliary functions ***)
74 (*go to a location in a program and fetch the resective sub-term*)
76 | go (D :: p) (Abs(_, _, body)) = go (p : Celem.path) body
77 | go (L :: p) (t1 $ _) = go p t1
78 | go (R :: p) (_ $ t2) = go p t2
79 | go l _ = error ("go: no " ^ Celem.path2str l);
81 if length l > 1 then go (drop_last l) t else raise ERROR ("go_up [] " ^ Rule.term2str t)
83 fun check_Let_up ({path, ...}: pstate) prog =
84 case go (drop_last path) prog of
85 Const ("HOL.Let",_) $ _ $ (Abs (i, T, body)) => (TermC.mk_Free (i, T), body)
86 | t => raise ERROR ("scan_up1..\"HOL.Let $ _\" with: \"" ^ Rule.term2str t ^ "\"")
87 fun check_Seq_up ({path, ...}: pstate) prog =
88 case go (drop_last path) prog of
89 Const ("Tactical.Chain",_) $ _ $ e2=> e2
90 | t => raise ERROR ("scan_up1..\"Tactical.Chain $ _\" with: \"" ^ Rule.term2str t ^ "\"")
93 (*** locate an input tactic within a program ***)
95 datatype input_tactic_result =
96 Safe_Step of Istate.T * Proof.context * Tactic.T
97 | Unsafe_Step of Istate.T * Proof.context * Tactic.T
98 | Not_Locatable of string
100 datatype expr_val1 = (* "ExprVal" in the sense of denotational semantics *)
101 Reject_Tac1 of (* tactic is found but NOT acknowledged, scan is continued *)
102 Istate.pstate * Proof.context * Tactic.T (*TODO: revise Pstate {or,...},no args as Reject_Tac2*)
103 | Ackn_Tac1 of (* tactic is found and acknowledged, scan is stalled *)
104 Istate.pstate * (* the current state, returned for resuming execution *)
105 Proof.context * (* updated according to evaluation of Prog_Tac *)
106 Tactic.T (* Prog_Tac is associated to Tactic.input *)
107 | Term_Val1 of (* Prog_Expr is found and evaluated, scan is continued *)
108 term (* value of Prog_Expr, for updating environment *)
109 fun assoc2str (Ackn_Tac1 _) = "Ackn_Tac1"
110 | assoc2str (Term_Val1 _) = "Term_Val1"
111 | assoc2str (Reject_Tac1 _) = "Reject_Tac1";
114 (** scan to a Prog_Tac **)
116 fun scan_dn1 cct ist (Const ("Tactical.Try"(*1*), _) $ e $ a) =
117 (case scan_dn1 cct (ist |> path_down_form ([L, R], a)) e of goback => goback)
118 | scan_dn1 cct ist (Const ("Tactical.Try"(*2*), _) $ e) =
119 (case scan_dn1 cct (ist |> path_down [R]) e of goback => goback)
121 | scan_dn1 cct ist (Const ("Tactical.Repeat"(*1*), _) $ e $ a) =
122 scan_dn1 cct (ist |> path_down_form ([L, R], a)) e
123 | scan_dn1 cct ist (Const ("Tactical.Repeat"(*2*), _) $ e) =
124 scan_dn1 cct (ist |> path_down [R]) e
126 | scan_dn1 (cct as (cstate, _, _)) ist (Const ("Tactical.Chain"(*1*), _) $ e1 $ e2 $ a) =
127 (case scan_dn1 cct (ist |> path_down_form ([L, L, R], a)) e1 of
128 Term_Val1 v => scan_dn1 cct (ist |> path_down [L, R] |> set_subst' (a, v)) e2
129 | Reject_Tac1 (ist', ctxt', tac') => scan_dn1 (cstate, ctxt', tac') (ist
130 |> path_down_form ([L, R], a) |> trans_env_act ist') e2
132 | scan_dn1 (cct as (cstate, _, _)) ist (Const ("Tactical.Chain"(*2*), _) $e1 $ e2) =
133 (case scan_dn1 cct (ist |> path_down [L, R]) e1 of
134 Term_Val1 v => scan_dn1 cct (ist |> path_down [R] |> set_act v) e2
135 | Reject_Tac1 (ist', ctxt', tac') =>
136 scan_dn1 (cstate, ctxt', tac') (ist |> path_down [R] |> trans_env_act ist') e2
139 | scan_dn1 cct ist (Const ("HOL.Let", _) $ e $ (Abs (id, T, b))) =
140 (case scan_dn1 cct (ist |> path_down [L, R]) e of
141 Reject_Tac1 (ist', _, _) =>
142 scan_dn1 cct (ist' |> path_down [R, D] |> upd_env (TermC.mk_Free (id, T)) |> trans_ass ist) b
144 scan_dn1 cct (ist |> path_down [R, D] |> upd_env'' (TermC.mk_Free (id, T), v)) b
147 | scan_dn1 cct (ist as {eval, act_arg, ...}) (Const ("Tactical.While"(*1*), _) $ c $ e $ a) =
148 if Rewrite.eval_true_ "Isac_Knowledge" eval
149 (subst_atomic (ist |> get_act_env |> Env.update' a) c)
150 then scan_dn1 cct (ist |> path_down_form ([L, R], a)) e
151 else Term_Val1 act_arg
152 | scan_dn1 cct (ist as {eval, act_arg, ...}) (Const ("Tactical.While"(*2*),_) $ c $ e) =
153 if Rewrite.eval_true_ "Isac_Knowledge" eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
154 then scan_dn1 cct (ist |> path_down [R]) e
155 else Term_Val1 act_arg
157 | scan_dn1 cct (ist as {or = Aundef, ...}) (Const ("Tactical.Or"(*1*), _) $e1 $ e2 $ a) =
158 (case scan_dn1 cct (ist |> path_down_form ([L, L, R], a) |> set_or AssOnly) e1 of
160 (case scan_dn1 cct (ist |> path_down [L, R] |> set_subst' (a, v) |> set_or AssOnly) e2 of
162 (case scan_dn1 cct (ist |> path_down [L, L, R] |> upd_env'' (a, v) |> set_or AssGen) e1 of
164 scan_dn1 cct (ist |> path_down [L, R] |> upd_env'' (a, v) |> set_or AssGen) e2
167 | Reject_Tac1 _ => raise ERROR ("scan_dn1 Tactical.Or(*1*): must not return Reject_Tac1")
169 | scan_dn1 cct ist (Const ("Tactical.Or"(*2*), _) $e1 $ e2) =
170 (case scan_dn1 cct (ist |> path_down [L, R]) e1 of
171 Term_Val1 v => scan_dn1 cct (ist |> path_down [R] |> set_act v) e2
174 | scan_dn1 cct (ist as {eval, ...}) (Const ("Tactical.If", _) $ c $ e1 $ e2) =
175 if Rewrite.eval_true_ "Isac_Knowledge" eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
176 then scan_dn1 cct (ist |> path_down [L, R]) e1
177 else scan_dn1 cct (ist |> path_down [R]) e2
179 | scan_dn1 ((pt, p), ctxt, tac) (ist as {eval, act_arg, or, ...}) t =
180 if Tactical.contained_in t then raise TERM ("scan_dn1 expects Prog_Tac or Prog_Expr", [t])
182 case Lucin.handle_leaf "locate" (Context.theory_name (Rule.Isac"")) eval (get_subst ist) t of
183 (a', Program.Expr _) =>
184 (*--------------------------- eval_Prog_Expr -----*)
185 Term_Val1 (Rewrite.eval_listexpr_ (Celem.assoc_thy "Isac_Knowledge") eval
186 (subst_atomic (Env.update_opt'' (get_act_env ist, a')) t))
187 | (a', Program.Tac stac) =>
188 (*/------------ interprete_Prog_Tac -----*)
189 case Lucin.associate pt ctxt (tac, stac) of
190 (* HERE ----------------vvvv ContextC.insert_assumptions asm ctxt DONE -- 2nd in gen//*)
191 Lucin.Ass (m, v', ctxt) => Ackn_Tac1 (ist |> set_subst_true (a', v'), ctxt, m)
192 | Lucin.Ass_Weak (m, v', ctxt) => Ackn_Tac1 (ist |> set_subst_false (a', v'), ctxt, m)
195 (case or of (* switch for Tactical.Or: 1st AssOnly, 2nd AssGen *)
196 AssOnly => Term_Val1 act_arg
198 case Applicable.applicable_in p pt (Lucin.stac2tac pt (Celem.assoc_thy "Isac_Knowledge") stac) of
199 Chead.Appl m' => Reject_Tac1 (ist |> set_subst_false (a', Lucin.tac_2res m'), ctxt, tac)
200 | Chead.Notappl _ => Term_Val1 act_arg)
201 (*------------- interprete_tactic ---//*)
204 fun scan_up1 pcct ist (Const ("Tactical.Try"(*1*), _) $ _ $ _) = go_scan_up1 pcct ist
205 | scan_up1 pcct ist (Const ("Tactical.Try"(*2*), _) $ _) = go_scan_up1 pcct ist
207 | scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (t as Const ("Tactical.Repeat"(*1*), _) $ e $ a) =
208 (case scan_dn1 cct (ist |> path_down_form ([L, R], a) |> set_or Aundef) e of
209 Term_Val1 v => go_scan_up1 pcct (ist |> set_act v |> set_form a)
210 | Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
212 | scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (t as Const ("Tactical.Repeat"(*2*), _) $ e) =
213 (case scan_dn1 cct (ist |> path_down [R] |> set_or Aundef) e of
214 Term_Val1 v' => go_scan_up1 pcct (ist |> set_act v')
215 | Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
218 (*all has been done in (*2*) below*)
219 | scan_up1 pcct ist (Const ("Tactical.Chain"(*1*), _) $ _ $ _ $ _) = go_scan_up1 pcct ist
220 | scan_up1 pcct ist (Const ("Tactical.Chain"(*2*), _) $ _ $ _) = go_scan_up1 pcct ist (*comes from e2*)
221 (*comes from e1, goes to e2*)
222 | scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (Const ("Tactical.Chain"(*3*), _) $ _ ) =
224 val e2 = check_Seq_up ist prog
226 case scan_dn1 cct (ist |> path_up_down [R] |> set_or Aundef) e2 of
227 Term_Val1 v => go_scan_up1 pcct (ist |> path_up |> set_act v)
228 | Reject_Tac1 (ist', ctxt', tac') => go_scan_up1 (prog, (cstate, ctxt', tac')) ist'
232 | scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (Const ("HOL.Let"(*1*), _) $ _) =
234 val (i, body) = check_Let_up ist prog
235 in case scan_dn1 cct (ist |> path_up_down [R, D] |> upd_env i |> set_or Aundef) body of
236 Ackn_Tac1 iss => Ackn_Tac1 iss
237 | Reject_Tac1 (ist', ctxt', tac') => go_scan_up1 (prog, (cstate, ctxt', tac')) ist'
238 | Term_Val1 v => go_scan_up1 pcct (ist |> path_up |> set_act v)
240 | scan_up1 pcct ist (Abs(*2*) _) = go_scan_up1 pcct ist
241 | scan_up1 pcct ist (Const ("HOL.Let"(*3*), _) $ _ $ (Abs _)) = go_scan_up1 pcct ist
243 | scan_up1 (pcct as (prog, cct as (cstate, _, _))) (ist as {eval, ...})
244 (t as Const ("Tactical.While"(*1*),_) $ c $ e $ a) =
245 if Rewrite.eval_true_ "Isac_Knowledge" eval (subst_atomic (Env.update' a (get_act_env ist)) c)
247 case scan_dn1 cct (ist |> path_down_form ([L, R], a) |> set_or Aundef) e of
248 Term_Val1 v => go_scan_up1 pcct (ist |> set_act v |> set_form a)
250 | Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
252 else go_scan_up1 pcct (ist |> set_form a)
253 | scan_up1 (pcct as (prog, cct as (cstate, _, _))) (ist as {eval, ...})
254 (t as Const ("Tactical.While"(*2*), _) $ c $ e) =
255 if Rewrite.eval_true_ "Isac_Knowledge" eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
257 case scan_dn1 cct (ist |> path_down [R] |> set_or Aundef) e of
258 Term_Val1 v => go_scan_up1 pcct (ist |> set_act v)
259 | Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
261 else go_scan_up1 pcct ist
263 | scan_up1 pcct ist (Const ("If", _) $ _ $ _ $ _) = go_scan_up1 pcct ist
265 | scan_up1 pcct ist (Const ("Tactical.Or"(*1*), _) $ _ $ _ $ _) = go_scan_up1 pcct ist
266 | scan_up1 pcct ist (Const ("Tactical.Or"(*2*), _) $ _ $ _) = go_scan_up1 pcct ist
267 | scan_up1 pcct ist (Const ("Tactical.Or"(*3*), _) $ _ ) = go_scan_up1 pcct (ist |> path_up)
269 | scan_up1 pcct ist (Const ("Tactical.If",_) $ _ $ _ $ _) = go_scan_up1 pcct ist
271 | scan_up1 _ _ t = error ("scan_up1 not impl for t= " ^ Rule.term2str t)
272 and go_scan_up1 (pcct as (prog, _)) (ist as {path, act_arg, ...}) =
274 then scan_up1 pcct (ist |> path_up) (go (path_up' path) prog)
275 else Term_Val1 act_arg
277 fun scan_to_tactic1 (prog, (cctt as ((_, p), _, _))) (Istate.Pstate (ist as {path, ...})) =
278 if path = [] orelse Pos.at_first_tactic(*RM prog path RM WITH determine_next_tactic IN solve*)p
279 then scan_dn1 cctt (ist |> set_path [R] |> set_or Aundef) (Program.body_of prog)
280 else go_scan_up1 (prog, cctt) ist
281 | scan_to_tactic1 _ _ = raise ERROR "scan_to_tactic1: uncovered pattern in fun.def"
283 (*locate an input tactic within a program*)
284 fun locate_input_tactic (Rule.Prog prog) cstate istate ctxt tac =
285 (case scan_to_tactic1 (prog, (cstate, ctxt, tac)) istate of
286 Ackn_Tac1 ((ist as {assoc, ...}), ctxt, tac') =>
288 then Safe_Step (Istate.Pstate ist, ctxt, tac')
289 else Unsafe_Step (Istate.Pstate ist, ctxt, tac')
290 | Reject_Tac1 _ => Not_Locatable (Tactic.tac_2str tac ^ " not locatable")
291 | err => raise ERROR ("not-found-in-script: NotLocatable from " ^ @{make_string} err))
292 | locate_input_tactic _ _ _ _ _ = raise ERROR "locate_input_tactic: uncovered case in definition"
295 (*** determine a next tactic by executing the program ***)
297 datatype next_tactic_result = NStep of Ctree.state * Istate.T * Proof.context * tactic
298 | Helpless | End_Program
300 (** scan to a Prog_Tac **)
302 datatype expr_val2 = (* "ExprVal" in the sense of denotational semantics *)
303 Reject_Tac2 (* tactic is found but NOT acknowledged, scan is continued *)
304 | Ackn_Tac2 of (* tactic is found and acknowledged, scan is stalled *)
305 Tactic.T * (* Prog_Tac is applicable_in cstate *)
306 Istate.pstate (* the current state, returned for resuming execution *)
307 | Term_Val2 of (* Prog_Expr is found and evaluated, scan is continued *)
308 term; (* value of Prog_Expr, for updating environment *)
311 scan_dn2, go_scan_up2, scan_up2 scan for determine_next_tactic.
312 (1) scan_dn2 is recursive descent;
313 (2) go_scan_up2 goes to the parent node and calls (3);
314 (3) scan_up2 resumes according to the interpreter-state.
315 Call of (2) means that there was an applicable Prog_Tac below
317 fun scan_dn2 cc (ist as {act_arg, ...}) (Const ("Tactical.Try"(*1*), _) $ e $ a) =
318 (case scan_dn2 cc (ist|> path_down_form ([L, R], a)) e of
319 Reject_Tac2 => Term_Val2 act_arg
321 | scan_dn2 cc (ist as {act_arg, ...}) (Const ("Tactical.Try"(*2*), _) $ e) =
322 (case scan_dn2 cc (ist |> path_down [R]) e of
323 Reject_Tac2 => Term_Val2 act_arg
326 | scan_dn2 cc ist (Const ("Tactical.Repeat"(*1*), _) $ e $ a) =
327 scan_dn2 cc (ist |> path_down_form ([L, R], a)) e
328 | scan_dn2 cc ist (Const ("Tactical.Repeat"(*2*), _) $ e) =
329 scan_dn2 cc (ist |> path_down [R]) e
331 | scan_dn2 cc ist (Const ("Tactical.Chain"(*1*), _) $ e1 $ e2 $ a) =
332 (case scan_dn2 cc (ist |> path_down_form ([L, L, R], a)) e1 of
333 Term_Val2 v => scan_dn2 cc (ist |> path_down_form ([L, R], a) |> set_act v) e2 (*UPD*)
335 | scan_dn2 cc ist (Const ("Tactical.Chain"(*2*), _) $ e1 $ e2) =
336 (case scan_dn2 cc (ist |> path_down [L, R]) e1 of
337 Term_Val2 v => scan_dn2 cc (ist |> path_down [R] |> set_act v) e2
340 | scan_dn2 cc ist (Const ("HOL.Let"(*1*), _) $ e $ (Abs (i, T, b))) =
341 (case scan_dn2 cc (ist |> path_down [L, R]) e of
342 Term_Val2 res => scan_dn2 cc (ist |> path_down [R, D] |> upd_env'' (Free (i, T), res)) b
345 | scan_dn2 (cc as (_, ctxt)) (ist as {eval, act_arg, ...}) (Const ("Tactical.While"(*1*), _) $ c $ e $ a) =
346 if Rewrite.eval_true_ ctxt eval (subst_atomic (ist |> get_act_env |> Env.update' a) c)
347 then scan_dn2 cc (ist |> path_down_form ([L, R], a)) e
348 else Term_Val2 act_arg
349 | scan_dn2 (cc as (_, ctxt)) (ist as {eval, act_arg, ...}) (Const ("Tactical.While"(*2*), _) $ c $ e) =
350 if Rewrite.eval_true_ ctxt eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
351 then scan_dn2 cc (ist |> path_down [R]) e
352 else Term_Val2 act_arg
354 |scan_dn2 cc ist (Const ("Tactical.Or"(*1*), _) $e1 $ e2 $ a) =
355 (case scan_dn2 cc (ist |> path_down_form ([L, L, R], a)) e1 of
356 Ackn_Tac2 lme => Ackn_Tac2 lme
357 | _ => scan_dn2 cc (ist |> path_down_form ([L, R], a)) e2)
358 | scan_dn2 cc ist (Const ("Tactical.Or"(*2*), _) $e1 $ e2) =
359 (case scan_dn2 cc (ist |> path_down [L, R]) e1 of
360 Ackn_Tac2 lme => Ackn_Tac2 lme
361 | _ => scan_dn2 cc (ist |> path_down [R]) e2)
363 | scan_dn2 (cc as (_, ctxt)) (ist as {eval, ...}) (Const ("Tactical.If"(*1*), _) $ c $ e1 $ e2) =
364 if Rewrite.eval_true_ ctxt eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
365 then scan_dn2 cc (ist |> path_down [L, R]) e1
366 else scan_dn2 cc (ist |> path_down [R]) e2
368 | scan_dn2 ((pt, p), ctxt) (ist as {eval, ...}) t =
369 if Tactical.contained_in t then raise TERM ("scan_dn2 expects Prog_Tac or Prog_Expr", [t])
371 case Lucin.handle_leaf "next " ctxt eval (get_subst ist) t of
372 (_, Program.Expr s) => Term_Val2 s
373 | (a', Program.Tac stac) =>
375 val (m, m') = Lucin.stac2tac_ pt (Celem.assoc_thy ctxt) stac
377 case m of (*TODO?: make applicable_in..Subproblem analogous to other tacs ?refine problem?*)
378 Tactic.Subproblem _ => Ackn_Tac2 (m', ist |> set_subst_reset (a', Lucin.tac_2res m'))
380 (case Applicable.applicable_in p pt m of
381 Chead.Appl m' => Ackn_Tac2 (m', ist |> set_subst_reset (a', Lucin.tac_2res m'))
385 (*makes Reject_Tac2 to Term_Val2*)
386 fun scan_up2 pcc ist (Const ("Tactical.Try"(*1*), _) $ _ $ _) = go_scan_up2 pcc (ist |> set_appy Skip_)
387 | scan_up2 pcc ist (Const ("Tactical.Try"(*2*), _) $ _) = go_scan_up2 pcc (ist |> set_appy Skip_)
389 | scan_up2 (pcc as (_, cc)) ist (Const ("Tactical.Repeat"(*1*), _) $ e $ _) =
390 (case scan_dn2 cc (ist |> path_down [L, R]) e of (* no appy_: there was already a stac below *)
391 Ackn_Tac2 lr => Ackn_Tac2 lr
392 | Reject_Tac2 => go_scan_up2 pcc (ist |> set_appy Skip_)
393 | Term_Val2 v => go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_))
394 (*no appy_: there was already a stac below*)
395 | scan_up2 (pcc as (_, cc)) ist (Const ("Tactical.Repeat"(*2*), _) $ e) =
396 (case scan_dn2 cc (ist |> path_down [R]) e of
397 Ackn_Tac2 lr => Ackn_Tac2 lr
398 | Reject_Tac2 => go_scan_up2 pcc (ist |> set_appy Skip_)
399 | Term_Val2 v => go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_))
401 | scan_up2 pcc ist (Const ("Tactical.Chain"(*1*), _) $ _ $ _ $ _) = go_scan_up2 pcc ist
402 | scan_up2 pcc ist (Const ("Tactical.Chain"(*2*), _) $ _ $ _) = go_scan_up2 pcc ist
403 | scan_up2 (pcc as (sc, cc)) (ist as {finish, ...}) (Const ("Tactical.Chain"(*3*), _) $ _) =
405 then go_scan_up2 pcc (ist |> path_up)
408 val e2 = check_Seq_up ist sc
410 case scan_dn2 cc (ist |> path_up_down [R]) e2 of
411 Ackn_Tac2 lr => Ackn_Tac2 lr
412 | Reject_Tac2 => go_scan_up2 pcc (ist |> path_up)
413 | Term_Val2 v => go_scan_up2 pcc (ist |> path_up |> set_act v |> set_appy Skip_)
416 | scan_up2 (pcc as (sc, cc)) (ist as {finish, ...}) (Const ("HOL.Let"(*1*), _) $ _) =
418 then go_scan_up2 pcc (ist |> path_up)
421 val (i, body) = check_Let_up ist sc
423 case scan_dn2 cc (ist |> path_up_down [R, D] |> upd_env i) body of
424 Ackn_Tac2 lre => Ackn_Tac2 lre
425 | Reject_Tac2 => go_scan_up2 pcc (ist |> path_up)
426 | Term_Val2 v => go_scan_up2 pcc (ist |> path_up |> set_act v |> set_appy Skip_)
428 | scan_up2 pcc ist (Abs _(*2*)) = go_scan_up2 pcc ist
429 | scan_up2 pcc ist (Const ("HOL.Let"(*3*),_) $ _ $ (Abs _)) =
432 (*no appy_: never causes Reject_Tac2 -> Helpless*)
433 | scan_up2 (pcc as (_, cc as (_, ctxt))) (ist as {eval, ...}) (Const ("Tactical.While"(*1*), _) $ c $ e $ _) =
434 if Rewrite.eval_true_ ctxt eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
436 case scan_dn2 cc (ist |> path_down [L, R]) e of
437 Ackn_Tac2 lr => Ackn_Tac2 lr
438 | Reject_Tac2 => go_scan_up2 pcc (ist |> set_appy Skip_)
439 | Term_Val2 v => go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_)
441 go_scan_up2 pcc (ist |> set_appy Skip_)
442 (*no appy_: never causes Reject_Tac2 - Helpless*)
443 | scan_up2 (pcc as (_, cc as (_, ctxt))) (ist as {eval, ...}) (Const ("Tactical.While"(*2*), _) $ c $ e) =
444 if Rewrite.eval_true_ ctxt eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
446 case scan_dn2 cc (ist |> path_down [R]) e of
447 Ackn_Tac2 lr => Ackn_Tac2 lr
448 | Reject_Tac2 => go_scan_up2 pcc (ist |> set_appy Skip_)
449 | Term_Val2 v => go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_)
451 go_scan_up2 pcc (ist |> set_appy Skip_)
453 | scan_up2 pcc ist (Const ("Tactical.Or"(*1*), _) $ _ $ _ $ _) = go_scan_up2 pcc ist
454 | scan_up2 pcc ist (Const ("Tactical.Or"(*2*), _) $ _ $ _) = go_scan_up2 pcc ist
455 | scan_up2 pcc ist (Const ("Tactical.Or"(*3*), _) $ _ ) = go_scan_up2 pcc ist
457 | scan_up2 pcc ist (Const ("Tactical.If"(*1*), _) $ _ $ _ $ _) = go_scan_up2 pcc ist
459 | scan_up2 _ _ t = error ("scan_up2 not impl for " ^ Rule.term2str t)
460 and go_scan_up2 (pcc as (sc, _)) (ist as {path, act_arg, finish, ...}) =
463 scan_up2 pcc (ist |> path_up) (go_up path sc)
464 else (*interpreted to end*)
465 if finish = Skip_ then Term_Val2 act_arg else Reject_Tac2
467 fun scan_to_tactic2 (prog, cc) (Istate.Pstate (ist as {path, ...})) =
469 then scan_dn2 cc (trans_scan_down2 ist) (Program.body_of prog)
470 else go_scan_up2 (prog, cc) (trans_scan_up2 ist |> set_appy Skip_)
471 | scan_to_tactic2 _ _ = raise ERROR "scan_to_tactic2: uncovered pattern";
473 (*decide for the next applicable Prog_Tac*)
474 fun determine_next_tactic (thy, _) (ptp as (pt, (p, _))) (Rule.Prog prog) (Istate.Pstate ist, _(*ctxt*)) =
475 (case scan_to_tactic2 (prog, (ptp, thy)) (Istate.Pstate ist) of
476 Term_Val2 v => (* program finished *)
477 (case par_pbl_det pt p of
480 val (_, pblID, _) = get_obj g_spec pt p';
482 (Tactic.Check_Postcond' (pblID, (v, [(*assigned in next step*)])),
483 (Istate.e_istate, ContextC.e_ctxt), (v, Telem.Safe))
486 (Tactic.End_Detail' (Rule.e_term,[])(*8.6.03*), (Istate.e_istate, ContextC.e_ctxt), (v, Telem.Safe)))
488 (Tactic.Empty_Tac_, (Istate.e_istate, ContextC.e_ctxt), (Rule.e_term, Telem.Helpless_))(* helpless *)
489 | Ackn_Tac2 (m', (ist as {act_arg, ...})) =>
490 (m', (Pstate ist, ContextC.e_ctxt), (act_arg, Telem.Safe))) (* found next tac *)
491 | determine_next_tactic _ _ _ (is, _) =
492 error ("determine_next_tactic: not impl for " ^ (Istate.istate2str is));
495 (*** locate an input formula in the program ***)
497 datatype input_formula_result =
498 Step of Ctree.state * Istate.T * Proof.context
499 | Not_Derivable of Chead.calcstate'
501 (* FIXME.WN050821 compare fun solve ... fun begin_end_prog
502 begin_end_prog (Apply_Method' vvv FIXME: get args in applicable_in *)
503 fun begin_end_prog (Tactic.Apply_Method' (mI, _, _, ctxt)) _ (pt, pos as (p, _)) =
505 val {ppc, ...} = Specify.get_met mI;
506 val (itms, oris, probl) = case get_obj I pt p of
507 PblObj {meth = itms, origin = (oris, _, _), probl, ...} => (itms, oris, probl)
508 | _ => error "begin_end_prog Apply_Method': uncovered case get_obj"
509 val itms = if itms <> [] then itms else Chead.complete_metitms oris probl [] ppc
510 val thy' = get_obj g_domID pt p;
511 val thy = Celem.assoc_thy thy';
512 val srls = Lucin.get_simplifier (pt, pos)
513 (*//----------- hack for funpack: generalise handling of meths which extend problem items -----\\*)
515 if mI = ["Biegelinien", "ausBelastung"]
517 [(4, [1], true, "#Given", Model.Cor ((Const ("Biegelinie.Biegelinie", Type ("fun", [Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]), Type ("Input_Descript.una", [])])),
518 [Free ("y", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]))]),
519 (Free ("id_fun", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])])),
520 [Free ("y", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]))] ))),
521 (5, [1], true, "#Given", Model.Cor ((Const ("Biegelinie.AbleitungBiegelinie", Type ("fun", [Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]), Type ("Input_Descript.una", [])])),
522 [Free ("dy", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]))]),
523 (Free ("id_abl", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])])),
524 [Free ("dy", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]))] )))]
526 (*\\----------- hack for funpack: generalise handling of meths which extend problem items -----//*)
527 val (is, env, ctxt, scr) = case Lucin.init_pstate srls ctxt itms mI of
528 (is as Istate.Pstate {env, ...}, ctxt, scr) => (is, env, ctxt, scr)
529 | _ => error "begin_end_prog Apply_Method': uncovered case init_pstate"
530 val ini = Lucin.init_form thy scr env;
535 val pos = ((lev_on o lev_dn) p, Frm)
536 val tac_ = Tactic.Apply_Method' (mI, SOME t, is, ctxt);
537 val (pos, c, _, pt) = Generate.generate1 thy tac_ (is, ctxt) pos pt (* implicit Take *)
539 ([(Tactic.Apply_Method mI, tac_, (pos, (is, ctxt)))], c, (pt, pos))
543 val pt = update_env pt (fst pos) (SOME (is, ctxt))
544 val (tacis, c, ptp) = do_solve_step (pt, pos)
545 in (tacis @ [(Tactic.Apply_Method mI,
546 Tactic.Apply_Method' (mI, NONE, Istate.e_istate, ctxt), (pos, (is, ctxt)))], c, ptp)
549 | begin_end_prog (Tactic.Check_Postcond' (pI, _)) _ (pt, (p, p_)) =
551 val pp = par_pblobj pt p
552 val asm = (case get_obj g_tac pt p of
553 Tactic.Check_elementwise _ => (snd o (get_obj g_result pt)) p (*collects and instantiates asms*)
554 | _ => get_assumptions_ pt (p, p_))
555 val metID = get_obj g_metID pt pp;
556 val {srls = srls, scr = sc, ...} = Specify.get_met metID;
557 val (loc, pst, ctxt) = case get_loc pt (p, p_) of
558 loc as (Istate.Pstate pst, ctxt) => (loc, pst, ctxt)
559 | _ => error "begin_end_prog Check_Postcond': uncovered case get_loc"
560 val thy' = get_obj g_domID pt pp;
561 val thy = Celem.assoc_thy thy';
562 val (_, _, (scval, _)) = determine_next_tactic (thy', srls) (pt, (p, p_)) sc loc;
567 val is = Istate.Pstate (pst |> Istate.set_act scval |> Istate.set_appy Istate.Skip_)
568 val tac_ = Tactic.Check_Postcond' (pI, (scval, asm))
569 (*extend Tactic.Check_Postcond' (pI, (scval, asm), scsaf) ^^^^^ *)
570 val ((p, p_), ps, _, pt) = Generate.generate1 thy tac_ (is, ctxt) (pp, Res) pt;
571 in ([(Tactic.Check_Postcond pI, tac_, ((pp, Res), (is, ctxt)))], ps, (pt, (p, p_))) end
573 let (*resume script of parent PblObj, transfer value of subpbl-script*)
574 val ppp = par_pblobj pt (lev_up p);
575 val thy' = get_obj g_domID pt ppp;
576 val thy = Celem.assoc_thy thy';
578 val (pst', ctxt') = case get_loc pt (pp, Frm) of
579 (Istate.Pstate pst', ctxt') => (pst', ctxt')
580 | _ => error "begin_end_prog Check_Postcond' script of parpbl: uncovered case get_loc"
581 val ctxt'' = ContextC.from_subpbl_to_caller ctxt scval ctxt'
582 val tac_ = Tactic.Check_Postcond' (pI, (scval, asm))
583 val is = Istate.Pstate (pst' |> Istate.set_act scval |> Istate.set_appy Istate.Skip_)
584 val ((p, p_), ps, _, pt) = Generate.generate1 thy tac_ (is, ctxt'') (pp, Res) pt;
585 in ([(Tactic.Check_Postcond pI, tac_, ((pp, Res), (is, ctxt'')))], ps, (pt, (p, p_))) end
587 | begin_end_prog (Tactic.End_Proof'') _ ptp = ([], [], ptp)
588 | begin_end_prog tac_ is (pt, pos) =
590 val pos = case pos of
591 (p, Met) => ((lev_on o lev_dn) p, Frm) (* begin script *)
592 | (p, Res) => (lev_on p, Res) (* somewhere in script *)
594 val (pos', c, _, pt) = Generate.generate1 (Celem.assoc_thy "Isac_Knowledge") tac_ is pos pt;
596 ([(Tactic.input_from_T tac_, tac_, (pos, is))], c, (pt, pos'))
598 (*find the next tac from the script, begin_end_prog will update the ctree*)
599 and do_solve_step (ptp as (pt, pos as (p, p_))) = (* WN1907: ?only for Begin_/End_Detail' DEL!!!*)
600 if Celem.e_metID = get_obj g_metID pt (par_pblobj pt p)
601 then ([], [], (pt, (p, p_)))
604 val thy' = get_obj g_domID pt (par_pblobj pt p);
605 val (srls, is, sc) = Lucin.from_pblobj_or_detail' thy' (p,p_) pt;
606 val (tac_, is, (t, _)) = determine_next_tactic (thy', srls) (pt, pos) sc is;
607 (* TODO here ^^^ return finished/helpless/ok ?*)
609 Tactic.End_Detail' _ =>
610 ([(Tactic.End_Detail, Tactic.End_Detail' (t, [(*FIXME.04*)]), (pos, is))], [], (pt, pos))
611 | _ => begin_end_prog tac_ is ptp
615 compare inform with ctree.form at current pos by nrls;
616 if found, embed the derivation generated during comparison
617 if not, let the mat-engine compute the next ctree.form.
619 Code's structure is copied from complete_solve
620 CAUTION: tacis in returned calcstate' do NOT construct resulting ptp --
621 all_modspec etc. has to be inserted at Subproblem'
623 fun compare_step ((tacis, c, ptp as (pt, pos as (p,p_))): Chead.calcstate') ifo =
627 Pos.Frm => Ctree.get_obj Ctree.g_form pt p
628 | Pos.Res => (fst o (Ctree.get_obj Ctree.g_result pt)) p
629 | _ => Rule.e_term (*on PblObj is fo <> ifo*);
630 val {nrls, ...} = Specify.get_met (Ctree.get_obj Ctree.g_metID pt (Ctree.par_pblobj pt p))
631 val {rew_ord, erls, rules, ...} = Rule.rep_rls nrls
632 val (found, der) = Inform.concat_deriv rew_ord erls rules fo ifo; (*<---------------*)
637 val tacis' = map (Inform.mk_tacis rew_ord erls) der;
638 val (c', ptp) = Generate.embed_deriv tacis' ptp;
639 in ("ok", (tacis (*@ tacis'?WN050408*), c @ c', ptp)) end
641 if pos = ([], Pos.Res) (*TODO: we should stop earlier with trying subproblems *)
642 then ("no derivation found", (tacis, c, ptp): Chead.calcstate')
645 val cs' as (tacis, c', ptp) = do_solve_step ptp; (*<---------------------*)
646 val (tacis, c'', ptp) = case tacis of
647 ((Tactic.Subproblem _, _, _)::_) =>
649 val ptp as (pt, (p,_)) = Chead.all_modspec ptp (*<--------------------*)
650 val mI = Ctree.get_obj Ctree.g_metID pt p
652 begin_end_prog (Tactic.Apply_Method' (mI, NONE, Istate.e_istate, ContextC.e_ctxt)) (Istate.e_istate, ContextC.e_ctxt) ptp
655 in compare_step (tacis, c @ c' @ c'', ptp) ifo end
659 handle a user-input formula, which may be a CAS-command, too.
660 * CAS-command: create a calchead, and do 1 step
661 * formula, which is no CAS-command:
662 compare iform with calc-tree.form at pos by equ_nrls and all subsequent pos;
663 collect all the Prog_Tac applied by the way; ...???TODO?
664 If "no derivation found" then check_error_patterns.
665 ALTERNATIVE: check_error_patterns _within_ compare_step: seems too expensive
667 (* vvvv vvvvvv vvvv NEW args for compare_step *)
668 fun locate_input_formula (Rule.Prog _) ((pt, pos) : Ctree.state) (_ : Istate.T) (_ : Proof.context) tm =
670 val pos_pred = Ctree.lev_back' pos (*f_pred ---"step pos cs"---> f_succ in appendFormula*)
671 val _(*f_pred*) = Ctree.get_curr_formula (pt, pos_pred)
673 (*TODO: use prog, istate, ctxt in compare_step ...*)
674 case compare_step ([], [], (pt, pos_pred)) tm of
675 ("no derivation found", calcstate') => Not_Derivable calcstate'
676 | ("ok", (_, _, cstate as (pt', pos'))) =>
677 Step (cstate, get_istate pt' pos', get_ctxt pt' pos')
678 | _ => raise ERROR "compare_step: uncovered case"
680 | locate_input_formula _ _ _ _ _ = error ""