separate Solve_Step.add, rearrange code, prep. Specify_Step
1 (* Title: Interpret/derive.sml
2 Author: Walther Neuper 2019
3 (c) due to copyright terms
5 Derive makes (term * rule * result) steps (= derivation) for term transformations,
6 which cannot be done by rewriting, e.g cancellation of polynomials.
11 (*TODO cleanup signature*)
16 val do_one : theory -> Rule_Set.T -> Rule.rule list -> Rule_Def.rew_ord_ ->
17 term option -> term -> derivation
18 (*val reverse_deriv *)
19 val steps_reverse : theory -> Rule_Set.T -> Rule.rule list -> Rule_Def.rew_ord_ ->
20 term option -> term -> deri list
22 val steps : Rule_Def.rew_ord -> Rule_Set.T -> Rule.rule list -> term -> term ->
24 val embed: State_Steps.T -> Calc.T -> Pos.pos' list * Calc.T
25 (* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
27 (*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
28 val trtas2str : (term * Rule.rule * (term * term list)) list -> string
29 val deriv2str : (term * Rule.rule * (term * term list)) list -> string
30 val rev_deriv' : 'a * Rule.rule * ('b * 'c) -> 'b * Rule.rule * ('a * 'c)
31 ( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
35 structure Derive(**): DERIVE(**) =
39 (** the triple for a step **)
41 type der = (* derivation for inserting one level of nodes into the Ctree *)
42 ( term * (* where the rule is applied to *)
43 Rule.rule * (* rule to be applied *)
44 ( term * (* resulting from rule application *)
45 term list));(* assumptions resulting from rule application *)
46 type deri = Rule.rule * (term * term list)
47 type derivation = der list
49 fun trta2str (t, r, (t', a)) =
50 "\n(" ^ UnparseC.term t ^ ", " ^ Rule.to_string_short r ^ ", (" ^ UnparseC.term t' ^ ", " ^ UnparseC.terms a ^ "))"
51 fun trtas2str trtas = (strs2str o (map trta2str)) trtas
52 val deriv2str = trtas2str
54 (** make one triple towards the goal term **)
57 (tracing ("do_one exceeds " ^ int2str (! Rewrite.lim_deriv) ^ "with derivation =\n");
58 tracing (deriv2str rts));
60 if not (! Rewrite.trace_on) then () else tracing ("### trying thm \"" ^ thmid ^ "\"");
62 if ! Rewrite.trace_on then tracing ("=== rewrites to: " ^ UnparseC.term t') else ();
64 if not (! Rewrite.trace_on) then () else tracing ("### trying calc. \"" ^ op_^"\"");
66 if not (! Rewrite.trace_on) then () else tracing("=== calc. to: " ^ UnparseC.term t')
68 fun do_one thy erls rs ro goal tt =
70 datatype switch = Appl | Noap (* TODO: unify with version in Rewrite *)
71 fun rew_once _ rts t Noap [] =
72 (case goal of NONE => rts | SOME _ =>
73 raise ERROR ("do_one: no derivation for " ^ UnparseC.term t))
74 | rew_once lim rts t Appl [] = rew_once lim rts t Noap rs
75 (*| Seq _ => rts) FIXXXXXME 14.3.03*)
76 | rew_once lim rts t apno rs' =
78 NONE => rew_or_calc lim rts t apno rs'
79 | SOME g => if g = t then rts else rew_or_calc lim rts t apno rs')
80 and rew_or_calc lim rts t apno (rrs' as (r :: rs')) =
85 Rule.Thm (thmid, tm) =>
87 case Rewrite.rewrite_ thy ro erls true tm t of
88 NONE => rew_once lim rts t apno rs'
90 (msg_3 t'; rew_once (lim - 1) (rts @ [(t, r, (t', a'))]) t' Appl rrs'))
91 | Rule.Eval (c as (op_, _)) =>
93 case Eval.adhoc_thm thy c (TermC.uminus_to_string t) of
94 NONE => rew_once lim rts t apno rs'
97 val (t', a') = case Rewrite.rewrite_ thy ro erls true tm t of
99 | NONE => raise ERROR "adhoc_thm: NONE"
101 val r' = Rule.Thm (thmid, tm)
102 in rew_once (lim - 1) (rts @ [(t, r', (t', a'))]) t' Appl rrs' end)
103 handle _ => raise ERROR "derive_norm, Eval: no rewrite")
105 (case Rewrite.rewrite_set_ thy true rls t of
106 NONE => rew_once lim rts t apno rs'
107 | SOME (t', a') => rew_once (lim - 1) (rts @ [(t, r, (t', a'))]) t' Appl rrs')
108 | rule => raise ERROR ("rew_once: uncovered case " ^ Rule.to_string rule))
109 | rew_or_calc _ _ _ _ [] = raise ERROR "rew_or_calc: called with []"
110 in rew_once (! Rewrite.lim_deriv) [] tt Noap rs end
113 (** concatenate several steps in revers order **)
115 fun rev_deriv (t, r, (_, a)) = (ThmC.make_sym_rule r, (t, a));
116 fun steps_reverse thy erls rs ro goal t =
117 (rev o (map rev_deriv)) (do_one thy erls rs ro goal t)
120 (** concatenate several steps **)
122 fun rev_deriv' (t, r, (t', a)) = (t', ThmC.make_sym_rule r, (t, a));
124 (* fo = ifo excluded already in inform *)
125 fun steps rew_ord erls rules fo ifo =
127 fun derivat ([]:(term * Rule.rule * (term * term list)) list) = TermC.empty
128 | derivat dt = (#1 o #3 o last_elem) dt
129 fun equal (_, _, (t1, _)) (_, _, (t2, _)) = t1 = t2
130 val fod = do_one (ThyC.Isac()) erls rules (snd rew_ord) NONE fo
131 val ifod = do_one (ThyC.Isac()) erls rules (snd rew_ord) NONE ifo
134 ([], []) => if fo = ifo then (true, []) else (false, [])
135 | (fod, []) => if derivat fod = ifo then (true, fod) (*ifo is normal form*) else (false, [])
136 | ([], ifod) => if fo = derivat ifod then (true, ((map rev_deriv') o rev) ifod) else (false, [])
138 if derivat fod = derivat ifod (*common normal form found*) then
140 val (fod', rifod') = dropwhile' equal (rev fod) (rev ifod)
141 in (true, fod' @ (map rev_deriv' rifod')) end
145 (* embed the tacis created by a '_deriv'ation; sys.form <> input.form
146 tacis are in order, thus are reverted for generate *)
147 fun embed tacis (pt, pos as (p, Pos.Frm)) =
148 (*inform at Frm: replace the whole PrfObj by a Transitive-ProfObj FIXME?0402
149 and transfer the istate (from _after_ compare_deriv) from Frm to Res*)
151 val (res, asm) = (State_Steps.result o last_elem) tacis
152 val (ist, ctxt) = case Ctree.get_obj Ctree.g_loc pt p of
153 (SOME (ist, ctxt), _) => (ist, ctxt)
154 | (NONE, _) => error "Derive.embed Frm: uncovered case get_obj"
155 val form = Ctree.get_obj Ctree.g_form pt p
156 (*val p = lev_on p; ---------------only difference to (..,Res) below*)
157 val tacis = (Tactic.Begin_Trans, Tactic.Begin_Trans' form, (pos, (Istate_Def.Uistate, ctxt))) ::
158 (State_Steps.insert_pos ((Pos.lev_on o Pos.lev_dn) p) tacis) @ [(Tactic.End_Trans, Tactic.End_Trans' (res, asm),
159 (Pos.pos_plus (length tacis) (Pos.lev_dn p, Pos.Res), (Ctree.new_val res ist, ctxt)))]
160 val {nrls, ...} = Specify.get_met (Ctree.get_obj Ctree.g_metID pt (Ctree.par_pblobj pt p))
161 val (pt, c, pos as (p, _)) = Solve_Step.s_add_general (rev tacis) (pt, [], (p, Pos.Res))
162 val pt = Ctree.update_tac pt p (Tactic.Derive (Rule_Set.id nrls))
163 val pt = Ctree.update_branch pt p Ctree.TransitiveB
164 in (c, (pt, pos)) end
165 | embed tacis (pt, (p, Pos.Res)) =
166 (*inform at Res: append a Transitive-PrfObj FIXME?0402 other branch-types ?
167 and transfer the istate (from _after_ compare_deriv) from Res to new Res*)
169 val (res, asm) = (State_Steps.result o last_elem) tacis
170 val (ist, ctxt) = case Ctree.get_obj Ctree.g_loc pt p of
171 (_, SOME (ist, ctxt)) => (ist, ctxt)
172 | (_, NONE) => error "Derive.embed Frm: uncovered case get_obj"
173 val (f, _) = Ctree.get_obj Ctree.g_result pt p
174 val p = Pos.lev_on p(*---------------only difference to (..,Frm) above*);
175 val tacis = (Tactic.Begin_Trans, Tactic.Begin_Trans' f, ((p, Pos.Frm), (Istate_Def.Uistate, ctxt))) ::
176 (State_Steps.insert_pos ((Pos.lev_on o Pos.lev_dn) p) tacis) @ [(Tactic.End_Trans, Tactic.End_Trans' (res, asm),
177 (Pos.pos_plus (length tacis) (Pos.lev_dn p, Pos.Res), (Ctree.new_val res ist, ctxt)))];
178 val {nrls, ...} = Specify.get_met (Ctree.get_obj Ctree.g_metID pt (Ctree.par_pblobj pt p))
179 val (pt, c, pos as (p, _)) = Solve_Step.s_add_general (rev tacis) (pt, [], (p, Pos.Res))
180 val pt = Ctree.update_tac pt p (Tactic.Derive (Rule_Set.id nrls))
181 val pt = Ctree.update_branch pt p Ctree.TransitiveB
182 in (c, (pt, pos)) end
183 | embed _ _ = error "Derive.embed: uncovered definition"