wneuper@59601
|
1 |
(* Title: tactics, tacticals etc. for scripts
|
wneuper@59601
|
2 |
Author: Walther Neuper 000224
|
wneuper@59601
|
3 |
(c) due to copyright terms
|
walther@60335
|
4 |
|
walther@60400
|
5 |
TODO: rearrange thy dependency such that "Tactical.Chain" etc are known const_name
|
wneuper@59601
|
6 |
*)
|
wneuper@59601
|
7 |
|
walther@59603
|
8 |
theory Prog_Tac
|
walther@59717
|
9 |
imports Program
|
walther@59603
|
10 |
begin
|
wneuper@59601
|
11 |
|
walther@59619
|
12 |
text \<open>Abstract:
|
walther@59619
|
13 |
Specific constants for tactics in programs, which each create a step in a calculation
|
walther@59619
|
14 |
as a side effect.
|
walther@59619
|
15 |
These program-tactics are related to Tactic.input for use in calculations and
|
walther@59619
|
16 |
Tactic.T for internal use by lucas-interpretation.
|
walther@59619
|
17 |
\<close>
|
walther@59619
|
18 |
|
wneuper@59601
|
19 |
subsection \<open>arguments of tactic SubProblem\<close>
|
wneuper@59601
|
20 |
|
wneuper@59601
|
21 |
typedecl
|
wneuper@59601
|
22 |
arg
|
wneuper@59601
|
23 |
|
wneuper@59601
|
24 |
consts
|
wneuper@59601
|
25 |
REAL :: "real => arg"
|
wneuper@59601
|
26 |
REAL_LIST :: "(real list) => arg"
|
wneuper@59601
|
27 |
REAL_SET :: "(real set) => arg"
|
wneuper@59601
|
28 |
BOOL :: "bool => arg"
|
wneuper@59601
|
29 |
BOOL_LIST :: "(bool list) => arg"
|
wneuper@59601
|
30 |
REAL_REAL :: "(real => real) => arg"
|
wneuper@59601
|
31 |
STRING :: "(char list) => arg"
|
wneuper@59601
|
32 |
STRING_LIST :: "(char list list) => arg"
|
wneuper@59601
|
33 |
|
wneuper@59601
|
34 |
subsection \<open>tactics in programs\<close>
|
wneuper@59601
|
35 |
text \<open>
|
wneuper@59601
|
36 |
Note: the items below MUST ALL be recorded in xxx TODO
|
wneuper@59601
|
37 |
\<close>
|
wneuper@59601
|
38 |
consts
|
walther@59634
|
39 |
Calculate :: "[char list, 'a] => 'a"
|
walther@59635
|
40 |
Rewrite :: "[char list, 'a] => 'a"
|
walther@60278
|
41 |
Rewrite_Inst:: "[(char list * 'b) list, char list, 'a] => 'a"
|
walther@59637
|
42 |
("(Rewrite'_Inst (_ _))" 11) (*without last argument ^^ for #>*)
|
walther@60278
|
43 |
Rewrite_Set :: "[char list, 'a] => 'a" ("(Rewrite'_Set (_))" 11)
|
walther@60278
|
44 |
Rewrite_Set_Inst
|
walther@59636
|
45 |
:: "[((char list) * 'b) list, char list, 'a] => 'a"
|
walther@59637
|
46 |
("(Rewrite'_Set'_Inst (_ _))" 11) (*without last argument ^^ for #>*)
|
walther@60278
|
47 |
Or_to_List :: "bool => 'a list" ("Or'_to'_List (_)" 11)
|
walther@59634
|
48 |
SubProblem :: "[char list * char list list * char list list, arg list] => 'a"
|
walther@59634
|
49 |
Substitute :: "[bool list, 'a] => 'a"
|
walther@59634
|
50 |
Take :: "'a => 'a"
|
walther@59634
|
51 |
|
walther@59635
|
52 |
(* legacy.. *)
|
walther@60278
|
53 |
Check_elementwise :: (* TODO: is idle, retained for test purposes in Minisubpbl *)
|
wneuper@59601
|
54 |
"['a list, 'b set] => 'a list" ("Check'_elementwise (_ _)" 11)
|
wneuper@59601
|
55 |
Assumptions :: bool (* TODO: remove with making ^^^ idle *)
|
walther@59634
|
56 |
|
wneuper@59601
|
57 |
|
walther@59716
|
58 |
subsection \<open>ML code for Prog_Tac\<close>
|
wneuper@59601
|
59 |
ML \<open>
|
wneuper@59601
|
60 |
signature PROGAM_TACTIC =
|
wneuper@59601
|
61 |
sig
|
walther@59985
|
62 |
val dest_spec : term -> References_Def.T
|
walther@59848
|
63 |
val get_first_argument : term -> term option (*TODO rename get_first_argument*)
|
walther@59800
|
64 |
val eval_leaf: Env.T -> term option -> term -> term -> Program.leaf * term option
|
walther@59716
|
65 |
val is: term -> bool
|
Walther@60567
|
66 |
|
Walther@60567
|
67 |
val Substitute_adapt_to_type: theory -> term -> Subst.as_string_eqs
|
Walther@60567
|
68 |
(**)val Rewrite_Inst_adapt_to_type: theory -> term -> TermC.as_string list(**)
|
Walther@60567
|
69 |
(**)val Take_adapt_to_type: Proof.context -> TermC.as_string -> term(**)
|
Walther@60567
|
70 |
end
|
wneuper@59601
|
71 |
\<close> ML \<open>
|
wneuper@59601
|
72 |
(**)
|
wneuper@59601
|
73 |
structure Prog_Tac(**): PROGAM_TACTIC(**) =
|
wneuper@59601
|
74 |
struct
|
wneuper@59601
|
75 |
(**)
|
wneuper@59601
|
76 |
|
wenzelm@60309
|
77 |
fun dest_spec (Const (\<^const_name>\<open>Pair\<close>, _) $ d $ (Const (\<^const_name>\<open>Pair\<close>, _) $ p $ m)) =
|
walther@59618
|
78 |
(d |> HOLogic.dest_string,
|
walther@59618
|
79 |
p |> HOLogic.dest_list |> map HOLogic.dest_string,
|
walther@59985
|
80 |
m |> HOLogic.dest_list |> map HOLogic.dest_string) : References_Def.T
|
walther@59618
|
81 |
| dest_spec t = raise TERM ("dest_spec: called with ", [t])
|
walther@59618
|
82 |
|
walther@59845
|
83 |
(* get argument of first Prog_Tac in a progam for implicit_take *)
|
walther@59848
|
84 |
fun get_first_argument (_ $ body) =
|
wneuper@59601
|
85 |
let
|
walther@59637
|
86 |
(* entries occur twice, for form curried by #> or non-curried *)
|
walther@59848
|
87 |
fun get_t (Const ("Tactical.Chain",_) $ e1 $ e2) a =
|
walther@59848
|
88 |
(case get_t e1 a of NONE => get_t e2 a | la => la)
|
walther@59848
|
89 |
| get_t (Const ("Tactical.Chain",_) $ e1 $ e2 $ a) _ =
|
walther@59848
|
90 |
(case get_t e1 a of NONE => get_t e2 a | la => la)
|
walther@59848
|
91 |
| get_t (Const ("Tactical.Try",_) $ e) a = get_t e a
|
walther@59848
|
92 |
| get_t (Const ("Tactical.Try",_) $ e $ a) _ = get_t e a
|
walther@60335
|
93 |
| get_t (Const ("Tactical.Repeat", _) $ e) a = get_t e a
|
walther@59848
|
94 |
| get_t (Const ("Tactical.Repeat",_) $ e $ a) _ = get_t e a
|
walther@59848
|
95 |
| get_t (Const ("Tactical.Or",_) $e1 $ e2) a =
|
walther@59848
|
96 |
(case get_t e1 a of NONE => get_t e2 a | la => la)
|
walther@59848
|
97 |
| get_t (Const ("Tactical.Or",_) $e1 $ e2 $ a) _ =
|
walther@59848
|
98 |
(case get_t e1 a of NONE => get_t e2 a | la => la)
|
walther@59848
|
99 |
| get_t (Const ("Tactical.While",_) $ _ $ e) a = get_t e a
|
walther@60335
|
100 |
| get_t (Const ("Tactical.While", _) $ _ $ e $ a) _ = get_t e a
|
walther@60335
|
101 |
| get_t (Const ("Tactical.Letpar", _) $ e1 $ Abs (_, _, e2)) a =
|
walther@59848
|
102 |
(case get_t e1 a of NONE => get_t e2 a | la => la)
|
walther@60335
|
103 |
| get_t (Const (\<^const_name>\<open>Let\<close>, _) $ e1 $ Abs (_, _, _)) a =
|
walther@59848
|
104 |
get_t e1 a (* don't go deeper without evaluation *)
|
walther@59848
|
105 |
| get_t (Const ("If", _) $ _ $ _ $ _) _ = NONE
|
wneuper@59601
|
106 |
|
walther@60335
|
107 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Rewrite\<close>,_) $ _ $ a) _ = SOME a
|
walther@60335
|
108 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Rewrite\<close>,_) $ _ ) a = SOME a
|
walther@60335
|
109 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Rewrite_Inst\<close>,_) $ _ $ _ $ a) _ = SOME a
|
walther@60335
|
110 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Rewrite_Inst\<close>,_) $ _ $ _ ) a = SOME a
|
walther@60335
|
111 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Rewrite_Set\<close>,_) $ _ $ a) _ = SOME a
|
walther@60335
|
112 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Rewrite_Set\<close>,_) $ _ ) a = SOME a
|
walther@60335
|
113 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Rewrite_Set_Inst\<close>,_) $ _ $ _ $a)_ =SOME a
|
walther@60335
|
114 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Rewrite_Set_Inst\<close>,_) $ _ $ _ ) a =SOME a
|
walther@60335
|
115 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Calculate\<close>,_) $ _ $ a) _ = SOME a
|
walther@60335
|
116 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Calculate\<close>,_) $ _ ) a = SOME a
|
walther@60335
|
117 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Substitute\<close>,_) $ _ $ a) _ = SOME a
|
walther@60335
|
118 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.Substitute\<close>,_) $ _ ) a = SOME a
|
wneuper@59601
|
119 |
|
walther@60335
|
120 |
| get_t (Const (\<^const_name>\<open>Prog_Tac.SubProblem\<close>,_) $ _ $ _) _ = NONE
|
wneuper@59601
|
121 |
|
walther@59848
|
122 |
| get_t _ _ = ((*tracing ("### get_t yac: list-expr "^(term2str x));*) NONE)
|
walther@59861
|
123 |
in get_t body TermC.empty end
|
walther@59962
|
124 |
| get_first_argument t = raise ERROR ("get_first_argument: no fun-def. for " ^ UnparseC.term t);
|
wneuper@59601
|
125 |
|
walther@59635
|
126 |
(* substitute the Istate.T's environment to a leaf of the program
|
wneuper@59601
|
127 |
and attach the curried argument of a tactic, if any.
|
walther@59637
|
128 |
CAUTION: (1) currying with #> requires 2 patterns for each tactic
|
wneuper@59601
|
129 |
(2) the non-curried version must return NONE for a
|
walther@59800
|
130 |
(3) non-matching patterns become a Prog_Expr by fall-through.
|
wneuper@59601
|
131 |
WN060906 quick and dirty fix: due to (2) a is returned, too *)
|
walther@59718
|
132 |
fun eval_leaf E _ _ (t as (Const ("Prog_Tac.Rewrite"(*1*), _) $ _ $ _)) =
|
walther@59729
|
133 |
(Program.Tac (subst_atomic E t), NONE)
|
walther@59718
|
134 |
| eval_leaf E a v (t as (Const ("Prog_Tac.Rewrite"(*2*), _) $ _)) =
|
walther@59729
|
135 |
(Program.Tac (
|
walther@59800
|
136 |
case a of SOME a' => (subst_atomic E (t $ a'))
|
walther@59729
|
137 |
| NONE => ((subst_atomic E t) $ v)),
|
walther@59729
|
138 |
a)
|
walther@60278
|
139 |
| eval_leaf E _ _ (t as (Const ("Prog_Tac.Rewrite_Inst"(*1*), _) $ _ $ _ $ _)) =
|
walther@59729
|
140 |
(Program.Tac (subst_atomic E t), NONE)
|
walther@60278
|
141 |
| eval_leaf E a v (t as (Const ("Prog_Tac.Rewrite_Inst"(*2*), _) $ _ $ _)) =
|
walther@59729
|
142 |
(Program.Tac (
|
walther@59717
|
143 |
case a of SOME a' => subst_atomic E (t $ a')
|
walther@59729
|
144 |
| NONE => ((subst_atomic E t) $ v)),
|
walther@59729
|
145 |
a)
|
walther@60278
|
146 |
| eval_leaf E _ _ (t as (Const ("Prog_Tac.Rewrite_Set"(*1*), _) $ _ $ _)) =
|
walther@59729
|
147 |
(Program.Tac (subst_atomic E t), NONE)
|
walther@60278
|
148 |
| eval_leaf E a v (t as (Const ("Prog_Tac.Rewrite_Set"(*2*), _) $ _)) =
|
walther@59729
|
149 |
(Program.Tac (
|
walther@59717
|
150 |
case a of SOME a' => subst_atomic E (t $ a')
|
walther@59729
|
151 |
| NONE => ((subst_atomic E t) $ v)),
|
walther@59729
|
152 |
a)
|
walther@60278
|
153 |
| eval_leaf E _ _ (t as (Const ("Prog_Tac.Rewrite_Set_Inst"(*1*), _) $ _ $ _ $ _)) =
|
walther@59729
|
154 |
(Program.Tac (subst_atomic E t), NONE)
|
walther@60278
|
155 |
| eval_leaf E a v (t as (Const ("Prog_Tac.Rewrite_Set_Inst"(*2*), _) $ _ $ _)) =
|
walther@59729
|
156 |
(Program.Tac (
|
walther@59717
|
157 |
case a of SOME a' => subst_atomic E (t $ a')
|
walther@59729
|
158 |
| NONE => ((subst_atomic E t) $ v)),
|
walther@59729
|
159 |
a)
|
walther@59718
|
160 |
| eval_leaf E _ _ (t as (Const ("Prog_Tac.Calculate"(*1*), _) $ _ $ _)) =
|
walther@59729
|
161 |
(Program.Tac (subst_atomic E t), NONE)
|
walther@59718
|
162 |
| eval_leaf E a v (t as (Const ("Prog_Tac.Calculate"(*2*), _) $ _)) =
|
walther@59729
|
163 |
(Program.Tac (
|
walther@59717
|
164 |
case a of SOME a' => subst_atomic E (t $ a')
|
walther@59729
|
165 |
| NONE => ((subst_atomic E t) $ v)),
|
walther@59729
|
166 |
a)
|
walther@60278
|
167 |
| eval_leaf E _ _ (t as (Const ("Prog_Tac.Check_elementwise"(*1*),_) $ _ $ _)) =
|
walther@59729
|
168 |
(Program.Tac (subst_atomic E t), NONE)
|
walther@60278
|
169 |
| eval_leaf E a v (t as (Const ("Prog_Tac.Check_elementwise"(*2*), _) $ _)) =
|
walther@59729
|
170 |
(Program.Tac (
|
walther@59717
|
171 |
case a of SOME a' => subst_atomic E (t $ a')
|
walther@59729
|
172 |
| NONE => ((subst_atomic E t) $ v)),
|
walther@59729
|
173 |
a)
|
walther@60278
|
174 |
| eval_leaf E _ _ (t as (Const ("Prog_Tac.Or_to_List"(*1*), _) $ _)) =
|
walther@59729
|
175 |
(Program.Tac (subst_atomic E t), NONE)
|
walther@60278
|
176 |
| eval_leaf E a v (t as (Const ("Prog_Tac.Or_to_List"(*2*), _))) = (*t $ v*)
|
walther@59729
|
177 |
(Program.Tac (
|
walther@59717
|
178 |
case a of SOME a' => subst_atomic E (t $ a')
|
walther@59729
|
179 |
| NONE => ((subst_atomic E t) $ v)),
|
walther@59729
|
180 |
a)
|
walther@60335
|
181 |
| eval_leaf E _ _ (t as (Const (\<^const_name>\<open>Prog_Tac.SubProblem\<close>, _) $ _ $ _)) =
|
walther@59729
|
182 |
(Program.Tac (subst_atomic E t), NONE)
|
walther@60335
|
183 |
| eval_leaf E _ _ (t as (Const (\<^const_name>\<open>Prog_Tac.Take\<close>, _) $ _)) =
|
walther@59729
|
184 |
(Program.Tac (subst_atomic E t), NONE)
|
walther@59718
|
185 |
| eval_leaf E _ _ (t as (Const ("Prog_Tac.Substitute"(*1*), _) $ _ $ _)) =
|
walther@59729
|
186 |
(Program.Tac (subst_atomic E t), NONE)
|
walther@59718
|
187 |
| eval_leaf E a v (t as (Const ("Prog_Tac.Substitute"(*2*), _) $ _)) =
|
walther@59729
|
188 |
(Program.Tac (
|
walther@59717
|
189 |
case a of SOME a' => subst_atomic E (t $ a')
|
walther@59729
|
190 |
| NONE => ((subst_atomic E t) $ v)),
|
walther@59729
|
191 |
a)
|
wneuper@59601
|
192 |
(*now all tactics are matched out and this leaf must be without a tactic*)
|
walther@59718
|
193 |
| eval_leaf E a v t =
|
walther@59729
|
194 |
(Program.Expr (subst_atomic (case a of SOME a => Env.update E (a,v) | NONE => E) t), a);
|
wneuper@59601
|
195 |
|
walther@59716
|
196 |
|
walther@59716
|
197 |
(* check if a term is a Prog_Tac *)
|
walther@59716
|
198 |
|
walther@59716
|
199 |
val SOME Calculate = TermC.parseNEW @{context} "Calculate";
|
walther@59716
|
200 |
val SOME Rewrite = TermC.parseNEW @{context} "Rewrite";
|
walther@59716
|
201 |
val SOME Rewrite_Inst = TermC.parseNEW @{context} "Rewrite'_Inst";
|
walther@59716
|
202 |
val SOME Rewrite_Set = TermC.parseNEW @{context} "Rewrite'_Set";
|
walther@59716
|
203 |
val SOME Rewrite_Set_Inst = TermC.parseNEW @{context} "Rewrite'_Set'_Inst";
|
walther@59716
|
204 |
val SOME Or_to_List = TermC.parseNEW @{context} "Or'_to'_List";
|
walther@59716
|
205 |
val SOME SubProblem = TermC.parseNEW @{context} "SubProblem";
|
walther@59716
|
206 |
val SOME Substitute = TermC.parseNEW @{context} "Substitute";
|
walther@59716
|
207 |
val SOME Take = TermC.parseNEW @{context} "Take";
|
walther@59716
|
208 |
val SOME Check_elementwise = TermC.parseNEW @{context} "Check'_elementwise";
|
walther@59716
|
209 |
val SOME Assumptions = TermC.parseNEW @{context} "Assumptions";
|
walther@59716
|
210 |
|
walther@59716
|
211 |
val all_Consts = [Calculate, Rewrite, Rewrite_Inst, Rewrite_Set, Rewrite_Set_Inst, Or_to_List,
|
walther@59716
|
212 |
SubProblem, Substitute, Take, Check_elementwise, Assumptions]
|
walther@59716
|
213 |
|
walther@59716
|
214 |
fun is t = TermC.contains_Const_typeless all_Consts t
|
Walther@60567
|
215 |
|
Walther@60567
|
216 |
|
Walther@60567
|
217 |
(** adapt_to_type arguments of specific tactics **)
|
Walther@60567
|
218 |
(*
|
Walther@60567
|
219 |
Programs are stored as terms typed by the theory they are defined in.
|
Walther@60567
|
220 |
Specific Prog_Tac take substitutions as arguments; these substitutions have
|
Walther@60567
|
221 |
the variables to be substituted typed with the program;
|
Walther@60567
|
222 |
these variables need to be adapt_to_type from the user-context in order to conform
|
Walther@60567
|
223 |
with the terms input by the user.
|
Walther@60567
|
224 |
*)
|
Walther@60567
|
225 |
fun Substitute_adapt_to_type thy isasub =
|
Walther@60567
|
226 |
isasub
|
Walther@60567
|
227 |
|> Model_Pattern.adapt_term_to_type (Proof_Context.init_global thy)
|
Walther@60567
|
228 |
|> TermC.isalist2list
|
Walther@60567
|
229 |
|> Subst.eqs_to_input;
|
Walther@60567
|
230 |
|
Walther@60567
|
231 |
fun Rewrite_Inst_adapt_to_type thy sub =
|
Walther@60567
|
232 |
sub
|
Walther@60567
|
233 |
(*|> Model_Pattern.adapt_term_to_type (Proof_Context.init_global thy)*)
|
Walther@60567
|
234 |
|> Subst.program_to_input
|
Walther@60567
|
235 |
|
Walther@60567
|
236 |
(*eliminated ERROR: c_2 = (0 :: 'a)*)
|
Walther@60567
|
237 |
fun Take_adapt_to_type ctxt arg = arg
|
Walther@60567
|
238 |
|> TermC.parse ctxt
|
Walther@60567
|
239 |
|> Model_Pattern.adapt_term_to_type ctxt
|
Walther@60567
|
240 |
|
Walther@60567
|
241 |
(**)end(*struct*)
|
wneuper@59601
|
242 |
\<close> ML \<open>
|
wneuper@59601
|
243 |
\<close>
|
Walther@60567
|
244 |
|
wneuper@59601
|
245 |
subsection \<open>TODO\<close>
|
wneuper@59601
|
246 |
ML \<open>
|
wneuper@59601
|
247 |
\<close> ML \<open>
|
wneuper@59601
|
248 |
\<close> ML \<open>
|
wneuper@59601
|
249 |
\<close>
|
wneuper@59601
|
250 |
end
|