1 (* Handle user-input during the specify- and the solve-phase.
4 (c) due to copyright terms
7 signature ERROR_PATTERN =
9 val find_fillpatterns : Calc.T -> Rule.errpatID -> (Celem.fillpatID * term * thm * Selem.subs option) list
10 val is_exactly_equal : Calc.T -> string -> string * Tactic.input
11 val concat_deriv : 'a * ((term * term) list -> term * term -> bool) ->
12 Rule_Set.T -> Rule.rule list -> term -> term -> bool * (term * Rule.rule * (term * term list)) list
13 val mk_tacis: Rule_Def.rew_ord' * 'a -> Rule_Set.T -> term * Rule.rule * (term * term list) -> Tactic.input * Tactic.T * (Pos.pos' * (Istate.T * Proof.context))
14 val fetchErrorpatterns : Tactic.input -> Rule.errpatID list
17 term * (term * term) list -> (Rule.errpatID * term list * 'a list) list * Rule_Set.T -> Rule.errpatID option
18 val rule2thm'' : Rule.rule -> Celem.thm''
19 val rule2rls' : Rule.rule -> string
20 (* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
22 (*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
23 val dropwhile' : ('a -> 'b -> bool) -> 'a list -> 'b list -> 'a list * 'b list
24 val rev_deriv' : 'a * Rule.rule * ('b * 'c) -> 'b * Rule.rule * ('a * 'c)
25 val check_err_patt : term * term -> Rule.subst -> Rule.errpatID * term -> Rule_Set.T -> Rule.errpatID option
27 'a * (term * term) list -> 'b * term -> Rule.errpatID -> Celem.fillpat -> (Celem.fillpatID * term * 'b * 'a) option
29 'a * (term * term) list -> term -> Rule.errpatID -> thm -> (Celem.fillpatID * term * thm * 'a) list
30 ( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
34 structure Error_Pattern(**): ERROR_PATTERN(**) =
38 fun rule2thm'' (Rule.Thm (id, thm)) = (id, thm)
39 | rule2thm'' r = error ("rule2thm': not defined for " ^ Rule_Set.rule2str r);
40 fun rule2rls' (Rule.Rls_ rls) = Rule_Set.id_rls rls
41 | rule2rls' r = error ("rule2rls': not defined for " ^ Rule_Set.rule2str r);
43 (*the lists contain eq-al elem-pairs at the beginning;
44 return first list reverted (again) - ie. in order as required subsequently*)
45 fun dropwhile' equal (f1::f2::fs) (i1::i2::is) =
47 if equal f2 i2 then dropwhile' equal (f2 :: fs) (i2 :: is)
48 else (rev (f1 :: f2 :: fs), i1 :: i2 :: is)
49 else error "dropwhile': did not start with equal elements"
50 | dropwhile' equal (f::fs) [i] =
53 else error "dropwhile': did not start with equal elements"
54 | dropwhile' equal [f] (i::is) =
57 else error "dropwhile': did not start with equal elements"
58 | dropwhile' _ _ _ = error "dropwhile': uncovered case"
60 (* 040214: version for concat_deriv *)
61 fun rev_deriv' (t, r, (t', a)) = (t', Rtools.sym_rule r, (t, a));
63 fun mk_tacis ro erls (t, r as Rule.Thm (id, thm), (t', a)) =
64 (Tactic.Rewrite (id, thm),
65 Tactic.Rewrite' ("Isac_Knowledge", fst ro, erls, false, rule2thm'' r, t, (t', a)),
66 (Pos.e_pos'(*to be updated before generate tacis!!!*), (Istate.Uistate, ContextC.empty)))
67 | mk_tacis _ _ (t, r as Rule.Rls_ rls, (t', a)) =
68 (Tactic.Rewrite_Set (rule2rls' r),
69 Tactic.Rewrite_Set' ("Isac_Knowledge", false, rls, t, (t', a)),
70 (Pos.e_pos'(*to be updated before generate tacis!!!*), (Istate.Uistate, ContextC.empty)))
71 | mk_tacis _ _ (t, r, _) = error ("mk_tacis: not impl. for " ^ Rule_Set.rule2str r ^ " at " ^ Rule.term2str t)
73 (* fo = ifo excluded already in inform *)
74 fun concat_deriv rew_ord erls rules fo ifo =
76 fun derivat ([]:(term * Rule.rule * (term * term list)) list) = Rule.e_term
77 | derivat dt = (#1 o #3 o last_elem) dt
78 fun equal (_,_,(t1, _)) (_,_,(t2, _)) = t1=t2
79 val fod = Rtools.make_deriv (ThyC.Isac()) erls rules (snd rew_ord) NONE fo
80 val ifod = Rtools.make_deriv (ThyC.Isac()) erls rules (snd rew_ord) NONE ifo
83 ([], []) => if fo = ifo then (true, []) else (false, [])
84 | (fod, []) => if derivat fod = ifo then (true, fod) (*ifo is normal form*) else (false, [])
85 | ([], ifod) => if fo = derivat ifod then (true, ((map rev_deriv') o rev) ifod) else (false, [])
87 if derivat fod = derivat ifod (*common normal form found*) then
89 val (fod', rifod') = dropwhile' equal (rev fod) (rev ifod)
90 in (true, fod' @ (map rev_deriv' rifod')) end
94 (*** handle an error pattern ***)
96 (* check if (agreed result, input formula) matches the error pattern "pat" modulo simplifier rls *)
97 fun check_err_patt (res, inf) subst (errpatID, pat) rls =
99 val (res', _, _, rewritten) =
100 Rewrite.rew_sub (ThyC.Isac()) 1 subst Rule.e_rew_ord Rule_Set.empty false [] (HOLogic.Trueprop $ pat) res;
104 val norm_res = case Rewrite.rewrite_set_inst_ (ThyC.Isac()) false subst rls res' of
106 | SOME (norm_res, _) => norm_res
107 val norm_inf = case Rewrite.rewrite_set_inst_ (ThyC.Isac()) false subst rls inf of
109 | SOME (norm_inf, _) => norm_inf
110 in if norm_res = norm_inf then SOME errpatID else NONE
115 (* check if (agreed result, input formula) matches SOME error pattern modulo simplifier rls;
116 (prog, env) for retrieval of casual substitution for bdv in the pattern. *)
117 fun check_for (res, inf) (prog, env) (errpats, rls) =
119 val (_, subst) = Rtools.get_bdv_subst prog env
120 fun scan (_, [], _) = NONE
121 | scan (errpatID, errpat :: errpats, _) =
122 case check_err_patt (res, inf) subst (errpatID, errpat) rls of
123 NONE => scan (errpatID, errpats, [])
124 | SOME errpatID => SOME errpatID
126 | scans (group :: groups) =
129 | SOME errpatID => SOME errpatID
130 in scans errpats end;
132 (* fill-in patterns an forms.
133 returns thm required by "fun in_fillform *)
134 fun get_fillform (subs_opt, subst) (thm, form) errpatID (fillpatID, pat, erpaID) =
136 val (form', _, _, rewritten) =
137 Rewrite.rew_sub (ThyC.Isac()) 1 subst Rule.e_rew_ord Rule_Set.empty false [] (HOLogic.Trueprop $ pat) form;
138 in (*the fillpat of the thm must be dedicated to errpatID*)
139 if errpatID = erpaID andalso rewritten then
140 SOME (fillpatID, HOLogic.mk_eq (form, form'), thm, subs_opt)
144 fun get_fillpats subst form errpatID thm =
146 val thmDeriv = Thm.get_name_hint thm
147 val (part, thyID) = Rtools.thy_containing_thm thmDeriv
148 val theID = [part, thyID, "Theorems", Celem.thmID_of_derivation_name thmDeriv]
149 val fillpats = case Specify.get_the theID of
150 Celem.Hthm {fillpats, ...} => fillpats
151 | _ => error "get_fillpats: uncovered case of get_the"
152 val some = map (get_fillform subst (thm, form) errpatID) fillpats
153 in some |> filter is_some |> map the end
155 fun find_fillpatterns (pt, pos as (p, _): Pos.pos') errpatID =
157 val f_curr = Ctree.get_curr_formula (pt, pos);
158 val pp = Ctree.par_pblobj pt p
159 val (errpats, prog) = case Specify.get_met (Ctree.get_obj Ctree.g_metID pt pp) of
160 {errpats, scr = Rule.Prog prog, ...} => (errpats, prog)
161 | _ => error "find_fillpatterns: uncovered case of get_met"
162 val {env, ...} = Ctree.get_istate_LI pt pos |> Istate.the_pstate
163 val subst = Rtools.get_bdv_subst prog env
164 val errpatthms = errpats
165 |> filter ((curry op = errpatID) o (#1: Rule.errpat -> Rule.errpatID))
166 |> map (#3: Rule.errpat -> thm list)
168 in map (get_fillpats subst f_curr errpatID) errpatthms |> flat end
170 (* check if an input formula is exactly equal the rewrite from a rule
171 which is stored at the pos where the input is stored of "ok". *)
172 fun is_exactly_equal (pt, pos as (p, _)) istr =
173 case TermC.parseNEW (Celem.assoc_thy "Isac_Knowledge" |> ThyC.thy2ctxt) istr of
174 NONE => ("syntax error in '" ^ istr ^ "'", Tactic.Tac "")
177 val p' = Pos.lev_on p;
178 val tac = Ctree.get_obj Ctree.g_tac pt p';
180 case Applicable.applicable_in pos pt tac of
181 Applicable.Notappl msg => (msg, Tactic.Tac "")
182 | Applicable.Appl rew =>
184 val res = case rew of
185 Tactic.Rewrite_Inst' (_, _, _, _, _, _, _, (res, _)) => res
186 |Tactic.Rewrite' (_, _, _, _, _, _, (res, _)) => res
187 | t => error ("is_exactly_equal: uncovered case for " ^ Tactic.string_of t)
189 if not (ifo = res) then
190 ("input does not exactly fill the gaps", Tactic.Tac "")
195 (* fetch errpatIDs from an arbitrary tactic *)
196 fun fetchErrorpatterns tac =
200 Tactic.Rewrite_Set rlsID => rlsID
201 |Tactic.Rewrite_Set_Inst (_, rlsID) => rlsID
203 val (part, thyID) = Rtools.thy_containing_rls "Isac_Knowledge" rlsID;
204 val rls = case Specify.get_the [part, thyID, "Rulesets", rlsID] of
205 Celem.Hrls {thy_rls = (_, rls), ...} => rls
206 | _ => error "fetchErrorpatterns: uncovered case of get_the"
208 Rule_Def.Repeat {errpatts, ...} => errpatts
209 | Rule_Set.Seqence {errpatts, ...} => errpatts
210 | Rule_Set.Rrls {errpatts, ...} => errpatts
211 | Rule_Set.Empty => []