wneuper@59562
|
1 |
(* Title: Interpret/lucas-interpreter.sml
|
wneuper@59554
|
2 |
Author: Walther Neuper 2019
|
wneuper@59554
|
3 |
(c) due to copyright terms
|
wneuper@59554
|
4 |
*)
|
wneuper@59554
|
5 |
|
wneuper@59554
|
6 |
signature LUCAS_INTERPRETER =
|
wneuper@59554
|
7 |
sig
|
walther@59747
|
8 |
datatype input_tactic_result =
|
walther@59747
|
9 |
Safe_Step of Istate.T * Proof.context * Tactic.T
|
walther@59655
|
10 |
| Unsafe_Step of Istate.T * Proof.context * Tactic.T
|
wneuper@59569
|
11 |
| Not_Locatable of string
|
walther@59734
|
12 |
val locate_input_tactic: Rule.program -> Ctree.state -> Istate.T -> Proof.context -> Tactic.T
|
wneuper@59569
|
13 |
-> input_tactic_result
|
wneuper@59557
|
14 |
|
walther@59747
|
15 |
datatype next_tactic_result =
|
walther@59747
|
16 |
Next_Step of Istate.T * Proof.context * Tactic.T
|
walther@59734
|
17 |
| Helpless | End_Program of Istate.T * Tactic.T
|
walther@59743
|
18 |
val find_next_tactic: Rule.program -> Ctree.state -> Istate.T -> Proof.context
|
walther@59734
|
19 |
-> next_tactic_result
|
walther@59734
|
20 |
|
walther@59749
|
21 |
(*TODO input_formula_result = Found_Step of Ctree.state | Not_Derivable *)
|
wneuper@59562
|
22 |
datatype input_formula_result =
|
walther@59747
|
23 |
Found_Step of Ctree.state * Istate.T * Proof.context
|
wneuper@59562
|
24 |
| Not_Derivable of Chead.calcstate'
|
walther@59749
|
25 |
(*TODOlocate_input_formula: Ctree.state -> term -> input_formula_result *)
|
walther@59734
|
26 |
val locate_input_formula: Rule.program -> Ctree.state -> Istate.T -> Proof.context -> term
|
wneuper@59562
|
27 |
-> input_formula_result
|
walther@59749
|
28 |
|
walther@59749
|
29 |
(* must reside here:
|
walther@59751
|
30 |
find_next_tactic calls do_solve_step and is called by by_tactic;
|
walther@59751
|
31 |
by_tactic and do_solve_step are mutually recursive via by_tactic Apply_Method'
|
walther@59749
|
32 |
*)
|
walther@59751
|
33 |
val by_tactic: Tactic.T -> Istate.T * Proof.context -> Ctree.state -> Chead.calcstate'
|
walther@59734
|
34 |
val do_solve_step: Ctree.state -> Chead.calcstate'
|
wneuper@59569
|
35 |
|
wneuper@59557
|
36 |
(* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
|
walther@59712
|
37 |
datatype expr_val1 =
|
walther@59718
|
38 |
Accept_Tac1 of Istate.pstate * Proof.context * Tactic.T
|
walther@59712
|
39 |
| Reject_Tac1 of Istate.pstate * Proof.context * Tactic.T
|
walther@59713
|
40 |
| Term_Val1 of term;
|
walther@59734
|
41 |
val assoc2str: expr_val1 -> string
|
walther@59702
|
42 |
(*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
|
walther@59734
|
43 |
val go: Celem.path -> term -> term
|
walther@59687
|
44 |
val go_up: Celem.path -> term -> term
|
walther@59734
|
45 |
val check_Let_up: Istate.pstate -> term -> term * term
|
walther@59685
|
46 |
val check_Seq_up: Istate.pstate -> term -> term
|
walther@59734
|
47 |
val compare_step: Generate.taci list * Ctree.pos' list * (Ctree.state) -> term -> string * Chead.calcstate'
|
walther@59686
|
48 |
|
walther@59712
|
49 |
val scan_dn1: (Ctree.state * Proof.context * Tactic.T) -> Istate.pstate -> term -> expr_val1
|
walther@59712
|
50 |
val scan_up1: term * (Ctree.state * Proof.context * Tactic.T) -> Istate.pstate -> term -> expr_val1;
|
walther@59712
|
51 |
val go_scan_up1: term * (Ctree.state * Proof.context * Tactic.T) -> Istate.pstate -> expr_val1;
|
walther@59712
|
52 |
val scan_to_tactic1: term * (Ctree.state * Proof.context * Tactic.T) -> Istate.T -> expr_val1
|
walther@59718
|
53 |
val interpret_tac1: Ctree.state * Proof.context * Tactic.T -> Istate.pstate -> term option * term -> expr_val1
|
walther@59686
|
54 |
|
walther@59728
|
55 |
datatype expr_val2 = Accept_Tac2 of Tactic.T * Istate.pstate * Proof.context
|
walther@59728
|
56 |
| Reject_Tac2 | Term_Val2 of term
|
walther@59722
|
57 |
val scan_dn2: Ctree.state * Proof.context -> Istate.pstate -> term -> expr_val2
|
walther@59722
|
58 |
val scan_up2: term * (Ctree.state * Proof.context) -> Istate.pstate -> term -> expr_val2
|
walther@59722
|
59 |
val go_scan_up2: term * (Ctree.state * Proof.context) -> Istate.pstate -> expr_val2
|
walther@59722
|
60 |
val scan_to_tactic2: term * (Ctree.state * Proof.context) -> Istate.T -> expr_val2
|
walther@59702
|
61 |
( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
|
wneuper@59554
|
62 |
end
|
wneuper@59554
|
63 |
|
walther@59684
|
64 |
(**)
|
wneuper@59557
|
65 |
structure LucinNEW(**): LUCAS_INTERPRETER(**) = (*LucinNEW \<rightarrow> Lucin after code re-arrangement*)
|
wneuper@59554
|
66 |
struct
|
walther@59684
|
67 |
(**)
|
wneuper@59554
|
68 |
open Ctree
|
walther@59695
|
69 |
open Pos
|
walther@59659
|
70 |
open Celem
|
walther@59661
|
71 |
open Istate
|
wneuper@59554
|
72 |
|
walther@59701
|
73 |
(*** auxiliary functions ***)
|
wneuper@59567
|
74 |
|
walther@59701
|
75 |
(*go to a location in a program and fetch the resective sub-term*)
|
wneuper@59554
|
76 |
fun go [] t = t
|
walther@59692
|
77 |
| go (D :: p) (Abs(_, _, body)) = go (p : Celem.path) body
|
walther@59661
|
78 |
| go (L :: p) (t1 $ _) = go p t1
|
walther@59661
|
79 |
| go (R :: p) (_ $ t2) = go p t2
|
walther@59687
|
80 |
| go l _ = error ("go: no " ^ Celem.path2str l);
|
walther@59668
|
81 |
fun go_up l t =
|
walther@59668
|
82 |
if length l > 1 then go (drop_last l) t else raise ERROR ("go_up [] " ^ Rule.term2str t)
|
wneuper@59554
|
83 |
|
walther@59685
|
84 |
fun check_Let_up ({path, ...}: pstate) prog =
|
walther@59668
|
85 |
case go (drop_last path) prog of
|
walther@59664
|
86 |
Const ("HOL.Let",_) $ _ $ (Abs (i, T, body)) => (TermC.mk_Free (i, T), body)
|
walther@59691
|
87 |
| t => raise ERROR ("scan_up1..\"HOL.Let $ _\" with: \"" ^ Rule.term2str t ^ "\"")
|
walther@59685
|
88 |
fun check_Seq_up ({path, ...}: pstate) prog =
|
walther@59664
|
89 |
case go (drop_last path) prog of
|
walther@59688
|
90 |
Const ("Tactical.Chain",_) $ _ $ e2=> e2
|
walther@59691
|
91 |
| t => raise ERROR ("scan_up1..\"Tactical.Chain $ _\" with: \"" ^ Rule.term2str t ^ "\"")
|
walther@59691
|
92 |
|
walther@59701
|
93 |
|
walther@59701
|
94 |
(*** locate an input tactic within a program ***)
|
walther@59691
|
95 |
|
walther@59691
|
96 |
datatype input_tactic_result =
|
walther@59691
|
97 |
Safe_Step of Istate.T * Proof.context * Tactic.T
|
walther@59691
|
98 |
| Unsafe_Step of Istate.T * Proof.context * Tactic.T
|
walther@59691
|
99 |
| Not_Locatable of string
|
walther@59691
|
100 |
|
walther@59712
|
101 |
datatype expr_val1 = (* "ExprVal" in the sense of denotational semantics *)
|
walther@59712
|
102 |
Reject_Tac1 of (* tactic is found but NOT acknowledged, scan is continued *)
|
walther@59716
|
103 |
Istate.pstate * Proof.context * Tactic.T (*TODO: revise Pstate {or,...},no args as Reject_Tac2*)
|
walther@59718
|
104 |
| Accept_Tac1 of (* tactic is found and acknowledged, scan is stalled *)
|
walther@59712
|
105 |
Istate.pstate * (* the current state, returned for resuming execution *)
|
walther@59712
|
106 |
Proof.context * (* updated according to evaluation of Prog_Tac *)
|
walther@59712
|
107 |
Tactic.T (* Prog_Tac is associated to Tactic.input *)
|
walther@59712
|
108 |
| Term_Val1 of (* Prog_Expr is found and evaluated, scan is continued *)
|
walther@59712
|
109 |
term (* value of Prog_Expr, for updating environment *)
|
walther@59718
|
110 |
fun assoc2str (Accept_Tac1 _) = "Accept_Tac1"
|
walther@59712
|
111 |
| assoc2str (Term_Val1 _) = "Term_Val1"
|
walther@59712
|
112 |
| assoc2str (Reject_Tac1 _) = "Reject_Tac1";
|
walther@59691
|
113 |
|
walther@59701
|
114 |
|
walther@59718
|
115 |
(** interpret a Prog_Tac: is it associated to Tactic ? **)
|
walther@59718
|
116 |
|
walther@59718
|
117 |
fun interpret_tac1 ((pt, p), ctxt, tac) (ist as {act_arg, or, ...}) (form_arg, prog_tac) =
|
walther@59718
|
118 |
case Lucin.associate pt ctxt (tac, prog_tac) of
|
walther@59718
|
119 |
(* HERE ----------------vvvv ContextC.insert_assumptions asm ctxt DONE -- 2nd in gen//*)
|
walther@59718
|
120 |
Lucin.Ass (m, v', ctxt) => Accept_Tac1 (ist |> set_subst_true (form_arg, v'), ctxt, m)
|
walther@59718
|
121 |
| Lucin.Ass_Weak (m, v', ctxt) => Accept_Tac1 (ist |> set_subst_false (form_arg, v'), ctxt, m)
|
walther@59718
|
122 |
|
walther@59718
|
123 |
| Lucin.NotAss =>
|
walther@59718
|
124 |
(case or of (* switch for Tactical.Or: 1st AssOnly, 2nd AssGen *)
|
walther@59718
|
125 |
AssOnly => Term_Val1 act_arg
|
walther@59718
|
126 |
| _(*ORundef*) =>
|
walther@59718
|
127 |
case Applicable.applicable_in p pt (Lucin.stac2tac pt (Celem.assoc_thy "Isac_Knowledge") prog_tac) of
|
walther@59735
|
128 |
Applicable.Appl m' => Reject_Tac1 (ist |> set_subst_false (form_arg, Tactic.result m'), ctxt, tac)
|
walther@59735
|
129 |
| Applicable.Notappl _ => Term_Val1 act_arg)
|
walther@59718
|
130 |
|
walther@59701
|
131 |
(** scan to a Prog_Tac **)
|
walther@59701
|
132 |
|
walther@59700
|
133 |
fun scan_dn1 cct ist (Const ("Tactical.Try"(*1*), _) $ e $ a) =
|
walther@59701
|
134 |
(case scan_dn1 cct (ist |> path_down_form ([L, R], a)) e of goback => goback)
|
walther@59700
|
135 |
| scan_dn1 cct ist (Const ("Tactical.Try"(*2*), _) $ e) =
|
walther@59701
|
136 |
(case scan_dn1 cct (ist |> path_down [R]) e of goback => goback)
|
walther@59691
|
137 |
|
walther@59700
|
138 |
| scan_dn1 cct ist (Const ("Tactical.Repeat"(*1*), _) $ e $ a) =
|
walther@59701
|
139 |
scan_dn1 cct (ist |> path_down_form ([L, R], a)) e
|
walther@59700
|
140 |
| scan_dn1 cct ist (Const ("Tactical.Repeat"(*2*), _) $ e) =
|
walther@59700
|
141 |
scan_dn1 cct (ist |> path_down [R]) e
|
walther@59691
|
142 |
|
walther@59709
|
143 |
| scan_dn1 (cct as (cstate, _, _)) ist (Const ("Tactical.Chain"(*1*), _) $ e1 $ e2 $ a) =
|
walther@59700
|
144 |
(case scan_dn1 cct (ist |> path_down_form ([L, L, R], a)) e1 of
|
walther@59712
|
145 |
Term_Val1 v => scan_dn1 cct (ist |> path_down [L, R] |> set_subst' (a, v)) e2
|
walther@59712
|
146 |
| Reject_Tac1 (ist', ctxt', tac') => scan_dn1 (cstate, ctxt', tac') (ist
|
walther@59712
|
147 |
|> path_down_form ([L, R], a) |> trans_env_act ist') e2
|
walther@59701
|
148 |
| goback => goback)
|
walther@59709
|
149 |
| scan_dn1 (cct as (cstate, _, _)) ist (Const ("Tactical.Chain"(*2*), _) $e1 $ e2) =
|
walther@59700
|
150 |
(case scan_dn1 cct (ist |> path_down [L, R]) e1 of
|
walther@59712
|
151 |
Term_Val1 v => scan_dn1 cct (ist |> path_down [R] |> set_act v) e2
|
walther@59712
|
152 |
| Reject_Tac1 (ist', ctxt', tac') =>
|
walther@59712
|
153 |
scan_dn1 (cstate, ctxt', tac') (ist |> path_down [R] |> trans_env_act ist') e2
|
walther@59701
|
154 |
| goback => goback)
|
walther@59691
|
155 |
|
walther@59709
|
156 |
| scan_dn1 cct ist (Const ("HOL.Let", _) $ e $ (Abs (id, T, b))) =
|
walther@59700
|
157 |
(case scan_dn1 cct (ist |> path_down [L, R]) e of
|
walther@59712
|
158 |
Reject_Tac1 (ist', _, _) =>
|
walther@59700
|
159 |
scan_dn1 cct (ist' |> path_down [R, D] |> upd_env (TermC.mk_Free (id, T)) |> trans_ass ist) b
|
walther@59712
|
160 |
| Term_Val1 v =>
|
walther@59709
|
161 |
scan_dn1 cct (ist |> path_down [R, D] |> upd_env'' (TermC.mk_Free (id, T), v)) b
|
walther@59703
|
162 |
| goback => goback)
|
walther@59691
|
163 |
|
walther@59722
|
164 |
| scan_dn1 (cct as (_, ctxt, _)) (ist as {eval, act_arg, ...})
|
walther@59722
|
165 |
(Const ("Tactical.While"(*1*), _) $ c $ e $ a) =
|
walther@59722
|
166 |
if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval
|
walther@59697
|
167 |
(subst_atomic (ist |> get_act_env |> Env.update' a) c)
|
walther@59703
|
168 |
then scan_dn1 cct (ist |> path_down_form ([L, R], a)) e
|
walther@59712
|
169 |
else Term_Val1 act_arg
|
walther@59722
|
170 |
| scan_dn1 (cct as (_, ctxt, _)) (ist as {eval, act_arg, ...})
|
walther@59722
|
171 |
(Const ("Tactical.While"(*2*),_) $ c $ e) =
|
walther@59722
|
172 |
if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
|
walther@59700
|
173 |
then scan_dn1 cct (ist |> path_down [R]) e
|
walther@59712
|
174 |
else Term_Val1 act_arg
|
walther@59691
|
175 |
|
walther@59718
|
176 |
| scan_dn1 cct (ist as {or = ORundef, ...}) (Const ("Tactical.Or"(*1*), _) $e1 $ e2 $ a) =
|
walther@59700
|
177 |
(case scan_dn1 cct (ist |> path_down_form ([L, L, R], a) |> set_or AssOnly) e1 of
|
walther@59712
|
178 |
Term_Val1 v =>
|
walther@59709
|
179 |
(case scan_dn1 cct (ist |> path_down [L, R] |> set_subst' (a, v) |> set_or AssOnly) e2 of
|
walther@59712
|
180 |
Term_Val1 v =>
|
walther@59709
|
181 |
(case scan_dn1 cct (ist |> path_down [L, L, R] |> upd_env'' (a, v) |> set_or AssGen) e1 of
|
walther@59712
|
182 |
Term_Val1 v =>
|
walther@59709
|
183 |
scan_dn1 cct (ist |> path_down [L, R] |> upd_env'' (a, v) |> set_or AssGen) e2
|
walther@59703
|
184 |
| goback => goback)
|
walther@59703
|
185 |
| goback => goback)
|
walther@59712
|
186 |
| Reject_Tac1 _ => raise ERROR ("scan_dn1 Tactical.Or(*1*): must not return Reject_Tac1")
|
walther@59703
|
187 |
| goback => goback)
|
walther@59710
|
188 |
| scan_dn1 cct ist (Const ("Tactical.Or"(*2*), _) $e1 $ e2) =
|
walther@59700
|
189 |
(case scan_dn1 cct (ist |> path_down [L, R]) e1 of
|
walther@59712
|
190 |
Term_Val1 v => scan_dn1 cct (ist |> path_down [R] |> set_act v) e2
|
walther@59703
|
191 |
| goback => goback)
|
walther@59691
|
192 |
|
walther@59722
|
193 |
| scan_dn1 (cct as (_, ctxt, _)) (ist as {eval, ...}) (Const ("Tactical.If", _) $ c $ e1 $ e2) =
|
walther@59722
|
194 |
if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
|
walther@59700
|
195 |
then scan_dn1 cct (ist |> path_down [L, R]) e1
|
walther@59700
|
196 |
else scan_dn1 cct (ist |> path_down [R]) e2
|
walther@59691
|
197 |
|
walther@59719
|
198 |
| scan_dn1 (cct as (_, ctxt, _)) (ist as {eval, ...}) t =
|
walther@59716
|
199 |
if Tactical.contained_in t then raise TERM ("scan_dn1 expects Prog_Tac or Prog_Expr", [t])
|
walther@59717
|
200 |
else
|
walther@59722
|
201 |
case Lucin.interpret_leaf "locate" ctxt eval (get_subst ist) t of
|
walther@59731
|
202 |
(Program.Expr _, form_arg) =>
|
walther@59731
|
203 |
Term_Val1 (Rewrite.eval_prog_expr (Proof_Context.theory_of ctxt) eval
|
walther@59731
|
204 |
(subst_atomic (Env.update_opt'' (get_act_env ist, form_arg)) t))
|
walther@59731
|
205 |
| (Program.Tac prog_tac, form_arg) =>
|
walther@59731
|
206 |
interpret_tac1 cct ist (form_arg, prog_tac)
|
walther@59691
|
207 |
|
walther@59720
|
208 |
fun go_scan_up1 (pcct as (prog, _)) (ist as {path, act_arg, ...}) =
|
walther@59720
|
209 |
if 1 < length path
|
walther@59720
|
210 |
then scan_up1 pcct (ist |> path_up) (go (path_up' path) prog)
|
walther@59720
|
211 |
else Term_Val1 act_arg
|
walther@59720
|
212 |
and scan_up1 pcct ist (Const ("Tactical.Try"(*1*), _) $ _ $ _) = go_scan_up1 pcct ist
|
walther@59700
|
213 |
| scan_up1 pcct ist (Const ("Tactical.Try"(*2*), _) $ _) = go_scan_up1 pcct ist
|
walther@59691
|
214 |
|
walther@59709
|
215 |
| scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (t as Const ("Tactical.Repeat"(*1*), _) $ e $ a) =
|
walther@59718
|
216 |
(case scan_dn1 cct (ist |> path_down_form ([L, R], a) |> set_or ORundef) e of
|
walther@59712
|
217 |
Term_Val1 v => go_scan_up1 pcct (ist |> set_act v |> set_form a)
|
walther@59712
|
218 |
| Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
|
walther@59703
|
219 |
| goback => goback)
|
walther@59710
|
220 |
| scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (t as Const ("Tactical.Repeat"(*2*), _) $ e) =
|
walther@59718
|
221 |
(case scan_dn1 cct (ist |> path_down [R] |> set_or ORundef) e of
|
walther@59712
|
222 |
Term_Val1 v' => go_scan_up1 pcct (ist |> set_act v')
|
walther@59712
|
223 |
| Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
|
walther@59703
|
224 |
| goback => goback)
|
walther@59691
|
225 |
|
walther@59703
|
226 |
(*all has been done in (*2*) below*)
|
walther@59700
|
227 |
| scan_up1 pcct ist (Const ("Tactical.Chain"(*1*), _) $ _ $ _ $ _) = go_scan_up1 pcct ist
|
walther@59718
|
228 |
| scan_up1 pcct ist (Const ("Tactical.Chain"(*2*), _) $ _ $ _) = go_scan_up1 pcct ist (*comes from e2*)
|
walther@59709
|
229 |
| scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (Const ("Tactical.Chain"(*3*), _) $ _ ) =
|
walther@59691
|
230 |
let
|
walther@59718
|
231 |
val e2 = check_Seq_up ist prog (*comes from e1, goes to e2*)
|
walther@59691
|
232 |
in
|
walther@59718
|
233 |
case scan_dn1 cct (ist |> path_up_down [R] |> set_or ORundef) e2 of
|
walther@59712
|
234 |
Term_Val1 v => go_scan_up1 pcct (ist |> path_up |> set_act v)
|
walther@59712
|
235 |
| Reject_Tac1 (ist', ctxt', tac') => go_scan_up1 (prog, (cstate, ctxt', tac')) ist'
|
walther@59703
|
236 |
| goback => goback
|
walther@59691
|
237 |
end
|
walther@59691
|
238 |
|
walther@59709
|
239 |
| scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (Const ("HOL.Let"(*1*), _) $ _) =
|
walther@59691
|
240 |
let
|
walther@59692
|
241 |
val (i, body) = check_Let_up ist prog
|
walther@59718
|
242 |
in case scan_dn1 cct (ist |> path_up_down [R, D] |> upd_env i |> set_or ORundef) body of
|
walther@59718
|
243 |
Accept_Tac1 iss => Accept_Tac1 iss
|
walther@59712
|
244 |
| Reject_Tac1 (ist', ctxt', tac') => go_scan_up1 (prog, (cstate, ctxt', tac')) ist'
|
walther@59712
|
245 |
| Term_Val1 v => go_scan_up1 pcct (ist |> path_up |> set_act v)
|
walther@59691
|
246 |
end
|
walther@59700
|
247 |
| scan_up1 pcct ist (Abs(*2*) _) = go_scan_up1 pcct ist
|
walther@59700
|
248 |
| scan_up1 pcct ist (Const ("HOL.Let"(*3*), _) $ _ $ (Abs _)) = go_scan_up1 pcct ist
|
walther@59691
|
249 |
|
walther@59722
|
250 |
| scan_up1 (pcct as (prog, cct as (cstate, ctxt, _))) (ist as {eval, ...})
|
walther@59703
|
251 |
(t as Const ("Tactical.While"(*1*),_) $ c $ e $ a) =
|
walther@59722
|
252 |
if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update' a (get_act_env ist)) c)
|
walther@59691
|
253 |
then
|
walther@59718
|
254 |
case scan_dn1 cct (ist |> path_down_form ([L, R], a) |> set_or ORundef) e of
|
walther@59712
|
255 |
Term_Val1 v => go_scan_up1 pcct (ist |> set_act v |> set_form a)
|
walther@59691
|
256 |
|
walther@59712
|
257 |
| Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
|
walther@59703
|
258 |
| goback => goback
|
walther@59700
|
259 |
else go_scan_up1 pcct (ist |> set_form a)
|
walther@59722
|
260 |
| scan_up1 (pcct as (prog, cct as (cstate, ctxt, _))) (ist as {eval, ...})
|
walther@59703
|
261 |
(t as Const ("Tactical.While"(*2*), _) $ c $ e) =
|
walther@59722
|
262 |
if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
|
walther@59691
|
263 |
then
|
walther@59718
|
264 |
case scan_dn1 cct (ist |> path_down [R] |> set_or ORundef) e of
|
walther@59712
|
265 |
Term_Val1 v => go_scan_up1 pcct (ist |> set_act v)
|
walther@59712
|
266 |
| Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
|
walther@59703
|
267 |
| goback => goback
|
walther@59700
|
268 |
else go_scan_up1 pcct ist
|
walther@59691
|
269 |
|
walther@59700
|
270 |
| scan_up1 pcct ist (Const ("If", _) $ _ $ _ $ _) = go_scan_up1 pcct ist
|
walther@59691
|
271 |
|
walther@59700
|
272 |
| scan_up1 pcct ist (Const ("Tactical.Or"(*1*), _) $ _ $ _ $ _) = go_scan_up1 pcct ist
|
walther@59700
|
273 |
| scan_up1 pcct ist (Const ("Tactical.Or"(*2*), _) $ _ $ _) = go_scan_up1 pcct ist
|
walther@59700
|
274 |
| scan_up1 pcct ist (Const ("Tactical.Or"(*3*), _) $ _ ) = go_scan_up1 pcct (ist |> path_up)
|
walther@59691
|
275 |
|
walther@59700
|
276 |
| scan_up1 pcct ist (Const ("Tactical.If",_) $ _ $ _ $ _) = go_scan_up1 pcct ist
|
walther@59691
|
277 |
|
walther@59691
|
278 |
| scan_up1 _ _ t = error ("scan_up1 not impl for t= " ^ Rule.term2str t)
|
walther@59691
|
279 |
|
walther@59692
|
280 |
fun scan_to_tactic1 (prog, (cctt as ((_, p), _, _))) (Istate.Pstate (ist as {path, ...})) =
|
walther@59743
|
281 |
if path = [] orelse Pos.at_first_tactic(*RM prog path RM WITH find_next_tactic IN solve*)p
|
walther@59718
|
282 |
then scan_dn1 cctt (ist |> set_path [R] |> set_or ORundef) (Program.body_of prog)
|
walther@59692
|
283 |
else go_scan_up1 (prog, cctt) ist
|
walther@59691
|
284 |
| scan_to_tactic1 _ _ = raise ERROR "scan_to_tactic1: uncovered pattern in fun.def"
|
walther@59691
|
285 |
|
walther@59701
|
286 |
(*locate an input tactic within a program*)
|
walther@59699
|
287 |
fun locate_input_tactic (Rule.Prog prog) cstate istate ctxt tac =
|
walther@59699
|
288 |
(case scan_to_tactic1 (prog, (cstate, ctxt, tac)) istate of
|
walther@59718
|
289 |
Accept_Tac1 ((ist as {assoc, ...}), ctxt, tac') =>
|
walther@59691
|
290 |
if assoc
|
walther@59691
|
291 |
then Safe_Step (Istate.Pstate ist, ctxt, tac')
|
walther@59691
|
292 |
else Unsafe_Step (Istate.Pstate ist, ctxt, tac')
|
walther@59728
|
293 |
| Reject_Tac1 _ => Not_Locatable (Tactic.string_of tac ^ " not locatable")
|
walther@59691
|
294 |
| err => raise ERROR ("not-found-in-script: NotLocatable from " ^ @{make_string} err))
|
walther@59691
|
295 |
| locate_input_tactic _ _ _ _ _ = raise ERROR "locate_input_tactic: uncovered case in definition"
|
walther@59691
|
296 |
|
wneuper@59562
|
297 |
|
walther@59701
|
298 |
(*** determine a next tactic by executing the program ***)
|
wneuper@59554
|
299 |
|
walther@59729
|
300 |
datatype next_tactic_result = Next_Step of Istate.T * Proof.context * Tactic.T
|
walther@59734
|
301 |
| Helpless | End_Program of Istate.T * Tactic.T (*contains prog_result, without asms*)
|
wneuper@59566
|
302 |
|
walther@59712
|
303 |
(** scan to a Prog_Tac **)
|
walther@59712
|
304 |
|
walther@59728
|
305 |
datatype expr_val2 = (* "ExprVal" in the sense of denotational semantics *)
|
walther@59728
|
306 |
Reject_Tac2 (* tactic is found but NOT acknowledged, scan is continued *)
|
walther@59728
|
307 |
| Accept_Tac2 of (* tactic is found and acknowledged, scan is stalled *)
|
walther@59728
|
308 |
Tactic.T * (* Prog_Tac is applicable_in cstate *)
|
walther@59728
|
309 |
Istate.pstate * (* created by application of Tactic.T, for resuming execution *)
|
walther@59728
|
310 |
Proof.context (* created by application of Tactic.T *)
|
walther@59728
|
311 |
| Term_Val2 of (* Prog_Expr is found and evaluated, scan is continued *)
|
walther@59728
|
312 |
term; (* value of Prog_Expr, for updating environment *)
|
walther@59712
|
313 |
|
walther@59701
|
314 |
(*
|
walther@59743
|
315 |
scan_dn2, go_scan_up2, scan_up2 scan for find_next_tactic.
|
walther@59691
|
316 |
(1) scan_dn2 is recursive descent;
|
walther@59700
|
317 |
(2) go_scan_up2 goes to the parent node and calls (3);
|
walther@59700
|
318 |
(3) scan_up2 resumes according to the interpreter-state.
|
walther@59701
|
319 |
Call of (2) means that there was an applicable Prog_Tac below
|
wneuper@59554
|
320 |
*)
|
walther@59711
|
321 |
fun scan_dn2 cc (ist as {act_arg, ...}) (Const ("Tactical.Try"(*1*), _) $ e $ a) =
|
walther@59700
|
322 |
(case scan_dn2 cc (ist|> path_down_form ([L, R], a)) e of
|
walther@59712
|
323 |
Reject_Tac2 => Term_Val2 act_arg
|
walther@59722
|
324 |
| (*Accept_Tac2*) goback => goback)
|
walther@59711
|
325 |
| scan_dn2 cc (ist as {act_arg, ...}) (Const ("Tactical.Try"(*2*), _) $ e) =
|
walther@59700
|
326 |
(case scan_dn2 cc (ist |> path_down [R]) e of
|
walther@59712
|
327 |
Reject_Tac2 => Term_Val2 act_arg
|
walther@59722
|
328 |
| (*Accept_Tac2*) goback => goback)
|
walther@59689
|
329 |
|
walther@59700
|
330 |
| scan_dn2 cc ist (Const ("Tactical.Repeat"(*1*), _) $ e $ a) =
|
walther@59700
|
331 |
scan_dn2 cc (ist |> path_down_form ([L, R], a)) e
|
walther@59700
|
332 |
| scan_dn2 cc ist (Const ("Tactical.Repeat"(*2*), _) $ e) =
|
walther@59700
|
333 |
scan_dn2 cc (ist |> path_down [R]) e
|
walther@59689
|
334 |
|
walther@59711
|
335 |
| scan_dn2 cc ist (Const ("Tactical.Chain"(*1*), _) $ e1 $ e2 $ a) =
|
walther@59700
|
336 |
(case scan_dn2 cc (ist |> path_down_form ([L, L, R], a)) e1 of
|
walther@59712
|
337 |
Term_Val2 v => scan_dn2 cc (ist |> path_down_form ([L, R], a) |> set_act v) e2 (*UPD*)
|
walther@59722
|
338 |
| (*Accept_Tac2*) goback => goback)
|
walther@59711
|
339 |
| scan_dn2 cc ist (Const ("Tactical.Chain"(*2*), _) $ e1 $ e2) =
|
walther@59700
|
340 |
(case scan_dn2 cc (ist |> path_down [L, R]) e1 of
|
walther@59712
|
341 |
Term_Val2 v => scan_dn2 cc (ist |> path_down [R] |> set_act v) e2
|
walther@59722
|
342 |
| (*Accept_Tac2*) goback => goback)
|
walther@59689
|
343 |
|
walther@59711
|
344 |
| scan_dn2 cc ist (Const ("HOL.Let"(*1*), _) $ e $ (Abs (i, T, b))) =
|
walther@59700
|
345 |
(case scan_dn2 cc (ist |> path_down [L, R]) e of
|
walther@59712
|
346 |
Term_Val2 res => scan_dn2 cc (ist |> path_down [R, D] |> upd_env'' (Free (i, T), res)) b
|
walther@59722
|
347 |
| (*Accept_Tac2*) goback => goback)
|
walther@59678
|
348 |
|
walther@59711
|
349 |
| scan_dn2 (cc as (_, ctxt)) (ist as {eval, act_arg, ...}) (Const ("Tactical.While"(*1*), _) $ c $ e $ a) =
|
walther@59722
|
350 |
if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (ist |> get_act_env |> Env.update' a) c)
|
walther@59700
|
351 |
then scan_dn2 cc (ist |> path_down_form ([L, R], a)) e
|
walther@59712
|
352 |
else Term_Val2 act_arg
|
walther@59711
|
353 |
| scan_dn2 (cc as (_, ctxt)) (ist as {eval, act_arg, ...}) (Const ("Tactical.While"(*2*), _) $ c $ e) =
|
walther@59722
|
354 |
if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
|
walther@59700
|
355 |
then scan_dn2 cc (ist |> path_down [R]) e
|
walther@59712
|
356 |
else Term_Val2 act_arg
|
walther@59678
|
357 |
|
walther@59700
|
358 |
|scan_dn2 cc ist (Const ("Tactical.Or"(*1*), _) $e1 $ e2 $ a) =
|
walther@59700
|
359 |
(case scan_dn2 cc (ist |> path_down_form ([L, L, R], a)) e1 of
|
walther@59718
|
360 |
Accept_Tac2 lme => Accept_Tac2 lme
|
walther@59700
|
361 |
| _ => scan_dn2 cc (ist |> path_down_form ([L, R], a)) e2)
|
walther@59700
|
362 |
| scan_dn2 cc ist (Const ("Tactical.Or"(*2*), _) $e1 $ e2) =
|
walther@59700
|
363 |
(case scan_dn2 cc (ist |> path_down [L, R]) e1 of
|
walther@59718
|
364 |
Accept_Tac2 lme => Accept_Tac2 lme
|
walther@59700
|
365 |
| _ => scan_dn2 cc (ist |> path_down [R]) e2)
|
walther@59689
|
366 |
|
walther@59700
|
367 |
| scan_dn2 (cc as (_, ctxt)) (ist as {eval, ...}) (Const ("Tactical.If"(*1*), _) $ c $ e1 $ e2) =
|
walther@59722
|
368 |
if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
|
walther@59700
|
369 |
then scan_dn2 cc (ist |> path_down [L, R]) e1
|
walther@59700
|
370 |
else scan_dn2 cc (ist |> path_down [R]) e2
|
walther@59678
|
371 |
|
walther@59715
|
372 |
| scan_dn2 ((pt, p), ctxt) (ist as {eval, ...}) t =
|
walther@59716
|
373 |
if Tactical.contained_in t then raise TERM ("scan_dn2 expects Prog_Tac or Prog_Expr", [t])
|
walther@59716
|
374 |
else
|
walther@59718
|
375 |
case Lucin.interpret_leaf "next " ctxt eval (get_subst ist) t of
|
walther@59721
|
376 |
(Program.Expr s, _) => Term_Val2 s
|
walther@59721
|
377 |
| (Program.Tac stac, a') =>
|
walther@59716
|
378 |
let
|
walther@59722
|
379 |
val (m, m') = Lucin.stac2tac_ pt (Proof_Context.theory_of ctxt) stac
|
walther@59716
|
380 |
in
|
walther@59716
|
381 |
case m of (*TODO?: make applicable_in..Subproblem analogous to other tacs ?refine problem?*)
|
walther@59728
|
382 |
Tactic.Subproblem _ =>
|
walther@59728
|
383 |
Accept_Tac2 (m', ist |> set_subst_reset (a', Tactic.result m'), ctxt)
|
walther@59716
|
384 |
| _ =>
|
walther@59716
|
385 |
(case Applicable.applicable_in p pt m of
|
walther@59735
|
386 |
Applicable.Appl m' => Accept_Tac2 (m',
|
walther@59728
|
387 |
ist |> set_subst_reset (a', Tactic.result m'), Tactic.insert_assumptions m' ctxt)
|
walther@59716
|
388 |
| _ => Reject_Tac2)
|
walther@59716
|
389 |
end
|
wneuper@59554
|
390 |
|
walther@59712
|
391 |
(*makes Reject_Tac2 to Term_Val2*)
|
walther@59720
|
392 |
fun go_scan_up2 (pcc as (sc, _)) (ist as {path, act_arg, finish, ...}) =
|
walther@59720
|
393 |
if 1 < length path
|
walther@59720
|
394 |
then
|
walther@59720
|
395 |
scan_up2 pcc (ist |> path_up) (go_up path sc)
|
walther@59720
|
396 |
else (*interpreted to end*)
|
walther@59720
|
397 |
if finish = Skip_ then Term_Val2 act_arg else Reject_Tac2
|
walther@59720
|
398 |
and scan_up2 pcc ist (Const ("Tactical.Try"(*1*), _) $ _ $ _) = go_scan_up2 pcc (ist |> set_appy Skip_)
|
walther@59700
|
399 |
| scan_up2 pcc ist (Const ("Tactical.Try"(*2*), _) $ _) = go_scan_up2 pcc (ist |> set_appy Skip_)
|
walther@59689
|
400 |
|
walther@59711
|
401 |
| scan_up2 (pcc as (_, cc)) ist (Const ("Tactical.Repeat"(*1*), _) $ e $ _) =
|
walther@59700
|
402 |
(case scan_dn2 cc (ist |> path_down [L, R]) e of (* no appy_: there was already a stac below *)
|
walther@59718
|
403 |
Accept_Tac2 lr => Accept_Tac2 lr
|
walther@59712
|
404 |
| Reject_Tac2 => go_scan_up2 pcc (ist |> set_appy Skip_)
|
walther@59712
|
405 |
| Term_Val2 v => go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_))
|
walther@59701
|
406 |
(*no appy_: there was already a stac below*)
|
walther@59722
|
407 |
| scan_up2 (pcc as (_, cc)) ist (Const ("Tactical.Repeat"(*2*), _) $ e) =
|
walther@59700
|
408 |
(case scan_dn2 cc (ist |> path_down [R]) e of
|
walther@59718
|
409 |
Accept_Tac2 lr => Accept_Tac2 lr
|
walther@59712
|
410 |
| Reject_Tac2 => go_scan_up2 pcc (ist |> set_appy Skip_)
|
walther@59712
|
411 |
| Term_Val2 v => go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_))
|
walther@59689
|
412 |
|
walther@59700
|
413 |
| scan_up2 pcc ist (Const ("Tactical.Chain"(*1*), _) $ _ $ _ $ _) = go_scan_up2 pcc ist
|
walther@59700
|
414 |
| scan_up2 pcc ist (Const ("Tactical.Chain"(*2*), _) $ _ $ _) = go_scan_up2 pcc ist
|
walther@59711
|
415 |
| scan_up2 (pcc as (sc, cc)) (ist as {finish, ...}) (Const ("Tactical.Chain"(*3*), _) $ _) =
|
walther@59689
|
416 |
if finish = Napp_
|
walther@59700
|
417 |
then go_scan_up2 pcc (ist |> path_up)
|
walther@59689
|
418 |
else (*Skip_*)
|
walther@59689
|
419 |
let
|
walther@59689
|
420 |
val e2 = check_Seq_up ist sc
|
walther@59689
|
421 |
in
|
walther@59700
|
422 |
case scan_dn2 cc (ist |> path_up_down [R]) e2 of
|
walther@59718
|
423 |
Accept_Tac2 lr => Accept_Tac2 lr
|
walther@59712
|
424 |
| Reject_Tac2 => go_scan_up2 pcc (ist |> path_up)
|
walther@59712
|
425 |
| Term_Val2 v => go_scan_up2 pcc (ist |> path_up |> set_act v |> set_appy Skip_)
|
walther@59689
|
426 |
end
|
walther@59690
|
427 |
|
walther@59711
|
428 |
| scan_up2 (pcc as (sc, cc)) (ist as {finish, ...}) (Const ("HOL.Let"(*1*), _) $ _) =
|
walther@59685
|
429 |
if finish = Napp_
|
walther@59700
|
430 |
then go_scan_up2 pcc (ist |> path_up)
|
walther@59671
|
431 |
else (*Skip_*)
|
walther@59671
|
432 |
let
|
walther@59685
|
433 |
val (i, body) = check_Let_up ist sc
|
walther@59671
|
434 |
in
|
walther@59700
|
435 |
case scan_dn2 cc (ist |> path_up_down [R, D] |> upd_env i) body of
|
walther@59718
|
436 |
Accept_Tac2 lre => Accept_Tac2 lre
|
walther@59712
|
437 |
| Reject_Tac2 => go_scan_up2 pcc (ist |> path_up)
|
walther@59712
|
438 |
| Term_Val2 v => go_scan_up2 pcc (ist |> path_up |> set_act v |> set_appy Skip_)
|
walther@59671
|
439 |
end
|
walther@59700
|
440 |
| scan_up2 pcc ist (Abs _(*2*)) = go_scan_up2 pcc ist
|
walther@59700
|
441 |
| scan_up2 pcc ist (Const ("HOL.Let"(*3*),_) $ _ $ (Abs _)) =
|
walther@59700
|
442 |
go_scan_up2 pcc ist
|
walther@59678
|
443 |
|
walther@59712
|
444 |
(*no appy_: never causes Reject_Tac2 -> Helpless*)
|
walther@59711
|
445 |
| scan_up2 (pcc as (_, cc as (_, ctxt))) (ist as {eval, ...}) (Const ("Tactical.While"(*1*), _) $ c $ e $ _) =
|
walther@59722
|
446 |
if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
|
walther@59671
|
447 |
then
|
walther@59700
|
448 |
case scan_dn2 cc (ist |> path_down [L, R]) e of
|
walther@59718
|
449 |
Accept_Tac2 lr => Accept_Tac2 lr
|
walther@59712
|
450 |
| Reject_Tac2 => go_scan_up2 pcc (ist |> set_appy Skip_)
|
walther@59712
|
451 |
| Term_Val2 v => go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_)
|
walther@59671
|
452 |
else
|
walther@59700
|
453 |
go_scan_up2 pcc (ist |> set_appy Skip_)
|
walther@59712
|
454 |
(*no appy_: never causes Reject_Tac2 - Helpless*)
|
walther@59711
|
455 |
| scan_up2 (pcc as (_, cc as (_, ctxt))) (ist as {eval, ...}) (Const ("Tactical.While"(*2*), _) $ c $ e) =
|
walther@59722
|
456 |
if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
|
walther@59671
|
457 |
then
|
walther@59700
|
458 |
case scan_dn2 cc (ist |> path_down [R]) e of
|
walther@59718
|
459 |
Accept_Tac2 lr => Accept_Tac2 lr
|
walther@59712
|
460 |
| Reject_Tac2 => go_scan_up2 pcc (ist |> set_appy Skip_)
|
walther@59712
|
461 |
| Term_Val2 v => go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_)
|
walther@59671
|
462 |
else
|
walther@59700
|
463 |
go_scan_up2 pcc (ist |> set_appy Skip_)
|
walther@59678
|
464 |
|
walther@59700
|
465 |
| scan_up2 pcc ist (Const ("Tactical.Or"(*1*), _) $ _ $ _ $ _) = go_scan_up2 pcc ist
|
walther@59700
|
466 |
| scan_up2 pcc ist (Const ("Tactical.Or"(*2*), _) $ _ $ _) = go_scan_up2 pcc ist
|
walther@59700
|
467 |
| scan_up2 pcc ist (Const ("Tactical.Or"(*3*), _) $ _ ) = go_scan_up2 pcc ist
|
walther@59678
|
468 |
|
walther@59700
|
469 |
| scan_up2 pcc ist (Const ("Tactical.If"(*1*), _) $ _ $ _ $ _) = go_scan_up2 pcc ist
|
walther@59678
|
470 |
|
walther@59691
|
471 |
| scan_up2 _ _ t = error ("scan_up2 not impl for " ^ Rule.term2str t)
|
wneuper@59554
|
472 |
|
walther@59731
|
473 |
(* scan program until an applicable tactic is found *)
|
walther@59700
|
474 |
fun scan_to_tactic2 (prog, cc) (Istate.Pstate (ist as {path, ...})) =
|
walther@59699
|
475 |
if path = []
|
walther@59700
|
476 |
then scan_dn2 cc (trans_scan_down2 ist) (Program.body_of prog)
|
walther@59700
|
477 |
else go_scan_up2 (prog, cc) (trans_scan_up2 ist |> set_appy Skip_)
|
walther@59690
|
478 |
| scan_to_tactic2 _ _ = raise ERROR "scan_to_tactic2: uncovered pattern";
|
wneuper@59565
|
479 |
|
walther@59729
|
480 |
(* decide for the next applicable Prog_Tac *)
|
walther@59743
|
481 |
fun find_next_tactic (Rule.Prog prog) (ptp as(pt, (p, _))) (Istate.Pstate ist) ctxt =
|
walther@59722
|
482 |
(case scan_to_tactic2 (prog, (ptp, ctxt)) (Istate.Pstate ist) of
|
walther@59748
|
483 |
Accept_Tac2 (tac, ist, ctxt) =>
|
walther@59748
|
484 |
Next_Step (Istate.Pstate ist, Tactic.insert_assumptions tac ctxt, tac)
|
walther@59748
|
485 |
| Term_Val2 prog_result =>
|
walther@59675
|
486 |
(case par_pbl_det pt p of
|
walther@59748
|
487 |
(true, p', _) =>
|
walther@59748
|
488 |
let
|
walther@59748
|
489 |
val (_, pblID, _) = get_obj g_spec pt p';
|
walther@59748
|
490 |
in
|
walther@59748
|
491 |
End_Program (Istate.Pstate ist, Tactic.Check_Postcond' (pblID, (prog_result, [(*???*)])))
|
walther@59675
|
492 |
end
|
walther@59748
|
493 |
| _ => End_Program (Istate.Pstate ist, Tactic.End_Detail' (Rule.e_term,[])))
|
walther@59748
|
494 |
| Reject_Tac2 => Helpless)
|
walther@59743
|
495 |
| find_next_tactic _ _ is _ =
|
walther@59743
|
496 |
raise ERROR ("find_next_tactic: not impl for " ^ Istate.istate2str is);
|
wneuper@59554
|
497 |
|
walther@59701
|
498 |
|
walther@59701
|
499 |
(*** locate an input formula in the program ***)
|
wneuper@59569
|
500 |
|
wneuper@59562
|
501 |
datatype input_formula_result =
|
walther@59747
|
502 |
Found_Step of Ctree.state * Istate.T * Proof.context
|
wneuper@59562
|
503 |
| Not_Derivable of Chead.calcstate'
|
wneuper@59562
|
504 |
|
walther@59751
|
505 |
(* FIXME.WN050821 compare fun solve ... fun by_tactic *)
|
walther@59751
|
506 |
fun by_tactic (Tactic.Apply_Method' (mI, _, _, _)) (_, ctxt) (pt, pos as (p, _)) =
|
wneuper@59562
|
507 |
let
|
wneuper@59562
|
508 |
val {ppc, ...} = Specify.get_met mI;
|
wneuper@59562
|
509 |
val (itms, oris, probl) = case get_obj I pt p of
|
wneuper@59562
|
510 |
PblObj {meth = itms, origin = (oris, _, _), probl, ...} => (itms, oris, probl)
|
walther@59751
|
511 |
| _ => error "by_tactic Apply_Method': uncovered case get_obj"
|
wneuper@59562
|
512 |
val itms = if itms <> [] then itms else Chead.complete_metitms oris probl [] ppc
|
wneuper@59562
|
513 |
val thy' = get_obj g_domID pt p;
|
wneuper@59562
|
514 |
val thy = Celem.assoc_thy thy';
|
walther@59677
|
515 |
val srls = Lucin.get_simplifier (pt, pos)
|
walther@59742
|
516 |
val itms = Specify.hack_until_review_Specify_1 mI itms
|
walther@59742
|
517 |
val (is, env, ctxt, scr) = case Lucin.init_pstate srls ctxt itms mI of
|
walther@59742
|
518 |
(is as Istate.Pstate {env, ...}, ctxt, scr) => (is, env, ctxt, scr)
|
walther@59751
|
519 |
| _ => error "by_tactic Apply_Method': uncovered case init_pstate"
|
wneuper@59555
|
520 |
val ini = Lucin.init_form thy scr env;
|
wneuper@59555
|
521 |
in
|
wneuper@59555
|
522 |
case ini of
|
wneuper@59555
|
523 |
SOME t =>
|
wneuper@59555
|
524 |
let
|
wneuper@59555
|
525 |
val pos = ((lev_on o lev_dn) p, Frm)
|
wneuper@59571
|
526 |
val tac_ = Tactic.Apply_Method' (mI, SOME t, is, ctxt);
|
wneuper@59555
|
527 |
val (pos, c, _, pt) = Generate.generate1 thy tac_ (is, ctxt) pos pt (* implicit Take *)
|
wneuper@59555
|
528 |
in
|
wneuper@59571
|
529 |
([(Tactic.Apply_Method mI, tac_, (pos, (is, ctxt)))], c, (pt, pos))
|
wneuper@59555
|
530 |
end
|
wneuper@59555
|
531 |
| NONE =>
|
wneuper@59555
|
532 |
let
|
wneuper@59555
|
533 |
val pt = update_env pt (fst pos) (SOME (is, ctxt))
|
wneuper@59562
|
534 |
val (tacis, c, ptp) = do_solve_step (pt, pos)
|
walther@59658
|
535 |
in (tacis @ [(Tactic.Apply_Method mI,
|
walther@59658
|
536 |
Tactic.Apply_Method' (mI, NONE, Istate.e_istate, ctxt), (pos, (is, ctxt)))], c, ptp)
|
wneuper@59555
|
537 |
end
|
wneuper@59555
|
538 |
end
|
walther@59751
|
539 |
| by_tactic (Tactic.Check_Postcond' (pI, (prog_res, _))) _ (pt, (p, p_)) =
|
wneuper@59555
|
540 |
let
|
wneuper@59555
|
541 |
val pp = par_pblobj pt p
|
walther@59746
|
542 |
val thy = Celem.assoc_thy (get_obj g_domID pt pp);
|
walther@59723
|
543 |
val (pst, ctxt) = case get_loc pt (p, p_) of (Istate.Pstate pst, ctxt) => (pst, ctxt)
|
walther@59751
|
544 |
| _ => error "by_tactic Check_Postcond': uncovered case get_loc"
|
walther@59746
|
545 |
val asm = (case get_obj g_tac pt p of (*collects and instantiates asms*)
|
walther@59746
|
546 |
Tactic.Check_elementwise _ => (snd o (get_obj g_result pt)) p
|
walther@59746
|
547 |
| _ => get_assumptions_ pt (p, p_))
|
walther@59746
|
548 |
val tac = Tactic.Check_Postcond' (pI, (prog_res, asm))
|
wneuper@59555
|
549 |
in
|
walther@59746
|
550 |
if pp = []
|
wneuper@59555
|
551 |
then
|
wneuper@59555
|
552 |
let
|
walther@59732
|
553 |
val is = Istate.Pstate (pst |> Istate.set_act prog_res |> Istate.set_appy Istate.Skip_)
|
walther@59732
|
554 |
val ((p, p_), ps, _, pt) = Generate.generate1 thy tac (is, ctxt) (pp, Res) pt;
|
walther@59732
|
555 |
in ([(Tactic.Check_Postcond pI, tac, ((pp, Res), (is, ctxt)))], ps, (pt, (p, p_))) end
|
wneuper@59555
|
556 |
else
|
walther@59675
|
557 |
let (*resume script of parent PblObj, transfer value of subpbl-script*)
|
walther@59746
|
558 |
val thy = Celem.assoc_thy (get_obj g_domID pt (par_pblobj pt (lev_up p)));
|
walther@59676
|
559 |
|
walther@59676
|
560 |
val (pst', ctxt') = case get_loc pt (pp, Frm) of
|
walther@59676
|
561 |
(Istate.Pstate pst', ctxt') => (pst', ctxt')
|
walther@59751
|
562 |
| _ => error "by_tactic Check_Postcond' script of parpbl: uncovered case get_loc"
|
walther@59732
|
563 |
val ctxt'' = ContextC.from_subpbl_to_caller ctxt prog_res ctxt'
|
walther@59732
|
564 |
val is = Istate.Pstate (pst' |> Istate.set_act prog_res |> Istate.set_appy Istate.Skip_)
|
walther@59732
|
565 |
val ((p, p_), ps, _, pt) = Generate.generate1 thy tac (is, ctxt'') (pp, Res) pt;
|
walther@59732
|
566 |
in ([(Tactic.Check_Postcond pI, tac, ((pp, Res), (is, ctxt'')))], ps, (pt, (p, p_))) end
|
wneuper@59555
|
567 |
end
|
walther@59751
|
568 |
| by_tactic (Tactic.End_Proof'') _ ptp = ([], [], ptp)
|
walther@59751
|
569 |
| by_tactic tac_ is (pt, pos) =
|
wneuper@59555
|
570 |
let
|
wneuper@59555
|
571 |
val pos = case pos of
|
walther@59731
|
572 |
(p, Met) => ((lev_on o lev_dn) p, Frm) (* begin program *)
|
walther@59731
|
573 |
| (p, Res) => (lev_on p, Res) (* somewhere in program *)
|
wneuper@59555
|
574 |
| _ => pos
|
wneuper@59592
|
575 |
val (pos', c, _, pt) = Generate.generate1 (Celem.assoc_thy "Isac_Knowledge") tac_ is pos pt;
|
wneuper@59555
|
576 |
in
|
walther@59704
|
577 |
([(Tactic.input_from_T tac_, tac_, (pos, is))], c, (pt, pos'))
|
wneuper@59555
|
578 |
end
|
walther@59751
|
579 |
(*find_next_tactic from program, by_tactic will update the ctree*)
|
walther@59746
|
580 |
and do_solve_step (ptp as (pt, pos as (p, p_))) =
|
wneuper@59555
|
581 |
if Celem.e_metID = get_obj g_metID pt (par_pblobj pt p)
|
wneuper@59555
|
582 |
then ([], [], (pt, (p, p_)))
|
wneuper@59555
|
583 |
else
|
wneuper@59555
|
584 |
let
|
wneuper@59555
|
585 |
val thy' = get_obj g_domID pt (par_pblobj pt p);
|
walther@59723
|
586 |
val (_, (ist, ctxt), sc) = Lucin.from_pblobj_or_detail' thy' (p,p_) pt;
|
walther@59745
|
587 |
in
|
walther@59745
|
588 |
case find_next_tactic sc (pt, pos) ist ctxt of
|
walther@59745
|
589 |
Next_Step (ist, ctxt, tac) =>
|
walther@59751
|
590 |
by_tactic tac (ist, Tactic.insert_assumptions tac ctxt) ptp
|
walther@59745
|
591 |
| End_Program (ist, tac) =>
|
walther@59745
|
592 |
(case tac of
|
walther@59745
|
593 |
Tactic.End_Detail' res =>
|
walther@59745
|
594 |
([(Tactic.End_Detail,
|
walther@59745
|
595 |
Tactic.End_Detail' res, (pos, (ist, ctxt)))], [], ptp)
|
walther@59751
|
596 |
| _ => by_tactic tac (ist, ctxt) ptp)
|
walther@59745
|
597 |
| Helpless => Chead.e_calcstate'
|
walther@59745
|
598 |
end;
|
walther@59686
|
599 |
|
walther@59701
|
600 |
(*
|
walther@59701
|
601 |
compare inform with ctree.form at current pos by nrls;
|
walther@59701
|
602 |
if found, embed the derivation generated during comparison
|
walther@59701
|
603 |
if not, let the mat-engine compute the next ctree.form.
|
walther@59701
|
604 |
|
walther@59701
|
605 |
Code's structure is copied from complete_solve
|
walther@59701
|
606 |
CAUTION: tacis in returned calcstate' do NOT construct resulting ptp --
|
walther@59701
|
607 |
all_modspec etc. has to be inserted at Subproblem'
|
walther@59701
|
608 |
*)
|
wneuper@59555
|
609 |
fun compare_step ((tacis, c, ptp as (pt, pos as (p,p_))): Chead.calcstate') ifo =
|
wneuper@59555
|
610 |
let
|
wneuper@59555
|
611 |
val fo =
|
wneuper@59555
|
612 |
case p_ of
|
walther@59694
|
613 |
Pos.Frm => Ctree.get_obj Ctree.g_form pt p
|
walther@59694
|
614 |
| Pos.Res => (fst o (Ctree.get_obj Ctree.g_result pt)) p
|
wneuper@59555
|
615 |
| _ => Rule.e_term (*on PblObj is fo <> ifo*);
|
wneuper@59555
|
616 |
val {nrls, ...} = Specify.get_met (Ctree.get_obj Ctree.g_metID pt (Ctree.par_pblobj pt p))
|
wneuper@59555
|
617 |
val {rew_ord, erls, rules, ...} = Rule.rep_rls nrls
|
wneuper@59555
|
618 |
val (found, der) = Inform.concat_deriv rew_ord erls rules fo ifo; (*<---------------*)
|
wneuper@59555
|
619 |
in
|
wneuper@59555
|
620 |
if found
|
wneuper@59555
|
621 |
then
|
wneuper@59555
|
622 |
let
|
wneuper@59555
|
623 |
val tacis' = map (Inform.mk_tacis rew_ord erls) der;
|
wneuper@59555
|
624 |
val (c', ptp) = Generate.embed_deriv tacis' ptp;
|
wneuper@59555
|
625 |
in ("ok", (tacis (*@ tacis'?WN050408*), c @ c', ptp)) end
|
wneuper@59555
|
626 |
else
|
walther@59694
|
627 |
if pos = ([], Pos.Res) (*TODO: we should stop earlier with trying subproblems *)
|
wneuper@59555
|
628 |
then ("no derivation found", (tacis, c, ptp): Chead.calcstate')
|
wneuper@59555
|
629 |
else
|
wneuper@59555
|
630 |
let
|
wneuper@59562
|
631 |
val cs' as (tacis, c', ptp) = do_solve_step ptp; (*<---------------------*)
|
wneuper@59555
|
632 |
val (tacis, c'', ptp) = case tacis of
|
wneuper@59571
|
633 |
((Tactic.Subproblem _, _, _)::_) =>
|
wneuper@59555
|
634 |
let
|
wneuper@59555
|
635 |
val ptp as (pt, (p,_)) = Chead.all_modspec ptp (*<--------------------*)
|
wneuper@59555
|
636 |
val mI = Ctree.get_obj Ctree.g_metID pt p
|
wneuper@59555
|
637 |
in
|
walther@59751
|
638 |
by_tactic (Tactic.Apply_Method' (mI, NONE, Istate.e_istate, ContextC.e_ctxt)) (Istate.e_istate, ContextC.e_ctxt) ptp
|
wneuper@59555
|
639 |
end
|
wneuper@59555
|
640 |
| _ => cs';
|
wneuper@59555
|
641 |
in compare_step (tacis, c @ c' @ c'', ptp) ifo end
|
wneuper@59555
|
642 |
end
|
wneuper@59555
|
643 |
|
walther@59701
|
644 |
(*
|
walther@59701
|
645 |
handle a user-input formula, which may be a CAS-command, too.
|
walther@59701
|
646 |
* CAS-command: create a calchead, and do 1 step
|
walther@59701
|
647 |
* formula, which is no CAS-command:
|
wneuper@59556
|
648 |
compare iform with calc-tree.form at pos by equ_nrls and all subsequent pos;
|
walther@59701
|
649 |
collect all the Prog_Tac applied by the way; ...???TODO?
|
walther@59701
|
650 |
If "no derivation found" then check_error_patterns.
|
walther@59701
|
651 |
ALTERNATIVE: check_error_patterns _within_ compare_step: seems too expensive
|
walther@59701
|
652 |
*)
|
wneuper@59562
|
653 |
(* vvvv vvvvvv vvvv NEW args for compare_step *)
|
walther@59658
|
654 |
fun locate_input_formula (Rule.Prog _) ((pt, pos) : Ctree.state) (_ : Istate.T) (_ : Proof.context) tm =
|
walther@59658
|
655 |
let
|
walther@59658
|
656 |
val pos_pred = Ctree.lev_back' pos (*f_pred ---"step pos cs"---> f_succ in appendFormula*)
|
walther@59658
|
657 |
val _(*f_pred*) = Ctree.get_curr_formula (pt, pos_pred)
|
walther@59658
|
658 |
in
|
walther@59658
|
659 |
(*TODO: use prog, istate, ctxt in compare_step ...*)
|
walther@59658
|
660 |
case compare_step ([], [], (pt, pos_pred)) tm of
|
walther@59658
|
661 |
("no derivation found", calcstate') => Not_Derivable calcstate'
|
walther@59658
|
662 |
| ("ok", (_, _, cstate as (pt', pos'))) =>
|
walther@59747
|
663 |
Found_Step (cstate, get_istate pt' pos', get_ctxt pt' pos')
|
walther@59658
|
664 |
| _ => raise ERROR "compare_step: uncovered case"
|
walther@59658
|
665 |
end
|
walther@59658
|
666 |
| locate_input_formula _ _ _ _ _ = error ""
|
wneuper@59556
|
667 |
|
walther@59684
|
668 |
(**)end(**)
|