src/Tools/isac/Interpret/derive.sml
author wneuper <Walther.Neuper@jku.at>
Thu, 04 Aug 2022 12:48:37 +0200
changeset 60509 2e0b7ca391dc
parent 60501 3be00036a653
child 60519 70b30d910fd5
permissions -rw-r--r--
polish naming in Rewrite_Order
     1 (* Title:  Interpret/derive.sml
     2    Author: Walther Neuper
     3    (c) due to copyright terms
     4 
     5 Try to make (term * rule * result) steps (= derivation) by use of a Rule_Set.T.
     6 Two purposes:
     7 (1) derive steps from a given term towards another give term
     8 (2) term transformations, which cannot be done by rewriting, e.g cancellation of polynomials.
     9 *)
    10 
    11 signature DERIVE =
    12 sig
    13   type rule_result
    14   type step
    15   type derivation
    16 
    17   val do_one : Proof.context -> Rule_Set.T -> Rule.rule list -> Rewrite_Ord.function ->
    18     term option -> term -> derivation
    19   val steps_reverse : Proof.context -> Rule_Set.T -> Rule.rule list -> Rewrite_Ord.function ->
    20     term option -> term -> rule_result list
    21   val steps : Rewrite_Ord.T -> Rule_Set.T -> Rule.rule list -> term -> term ->
    22     bool * derivation
    23   val embed: State_Steps.T -> Calc.T -> Pos.pos' list * Calc.T
    24 \<^isac_test>\<open>
    25   val trtas2str : (term * Rule.rule * (term * term list)) list -> string
    26   val deriv2str : (term * Rule.rule * (term * term list)) list -> string
    27   val rev_deriv' : 'a * Rule.rule * ('b * 'c) -> 'b * Rule.rule * ('a * 'c)
    28 \<close>
    29 end
    30 
    31 (**)
    32 structure Derive(**): DERIVE(**) =
    33 struct
    34 (**)
    35 
    36 (** the triple for a step **)
    37 
    38 type rule_result = Rule.rule * Calc.result;
    39 type step = term * Rule.rule * Calc.result;
    40 type derivation = step list;
    41 
    42 fun trta2str (t, r, (t', a)) =
    43   "\n(" ^ UnparseC.term t ^ ", " ^ Rule.to_string_short r ^ ", (" ^ UnparseC.term t' ^ ", " ^ UnparseC.terms a ^ "))"
    44 fun trtas2str trtas = (strs2str o (map trta2str)) trtas
    45 val deriv2str = trtas2str
    46 
    47 
    48 (** make one triple towards the goal term **)
    49 
    50 fun msg_1 ctxt rts =
    51   (tracing ("do_one exceeds " ^ int2str (Config.get ctxt rewrite_limit) ^ "with derivation =\n");
    52    tracing (deriv2str rts));
    53 fun msg_2 ctxt thmid =
    54   if not (Config.get ctxt rewrite_trace) then () else tracing ("### trying thm \"" ^ thmid ^ "\"");
    55 fun msg_3 ctxt t' =
    56   if Config.get ctxt rewrite_trace then tracing ("=== rewrites to: " ^ UnparseC.term t') else ();
    57 fun msg_4 ctxt op_ =
    58   if not (Config.get ctxt rewrite_trace) then () else tracing ("### trying calc. \"" ^ op_^"\"");
    59 fun msg_5 ctxt t' =
    60   if not (Config.get ctxt rewrite_trace) then () else tracing("=== calc. to: " ^ UnparseC.term t')
    61 
    62 
    63 fun do_one ctxt erls rs ro goal tt = 
    64   let 
    65     datatype switch = Appl | Noap (* TODO: unify with version in Rewrite *)
    66     fun rew_once _ rts t Noap [] = 
    67         (case goal of NONE => rts | SOME _ =>
    68           raise ERROR ("Derive.do_one: no derivation for " ^ UnparseC.term t))
    69       | rew_once lim rts t Appl [] = rew_once lim rts t Noap rs
    70       | rew_once lim rts t apno rs' =
    71         (case goal of 
    72           NONE => rew_or_calc lim rts t apno rs'
    73         | SOME g => if g = t then rts else rew_or_calc lim rts t apno rs')
    74     and rew_or_calc lim rts t apno (rrs' as (r :: rs')) =
    75       if lim < 0 
    76       then (msg_1 ctxt rts; rts)
    77       else
    78         (case r of
    79           Rule.Thm (thmid, tm) => 
    80             (msg_2 ctxt thmid;
    81             case Rewrite.rewrite_ ctxt ro erls true tm t of
    82               NONE => rew_once lim rts t apno rs'
    83             | SOME (t', a') =>
    84               (msg_3 ctxt t'; rew_once (lim - 1) (rts @ [(t, r, (t', a'))]) t' Appl rrs'))
    85         | Rule.Eval (c as (op_, _)) => 
    86             (msg_4 ctxt op_;
    87             case Eval.adhoc_thm (Proof_Context.theory_of ctxt) c t of
    88               NONE => rew_once lim rts t apno rs'
    89             | SOME (thmid, tm) => 
    90               (let
    91                 val (t', a') = case Rewrite.rewrite_ ctxt ro erls true tm t of
    92                   SOME ta => ta
    93                 | NONE => raise ERROR "adhoc_thm: NONE"
    94                 val _ = msg_5 ctxt t'
    95                 val r' = Rule.Thm (thmid, tm)
    96               in rew_once (lim - 1) (rts @ [(t, r', (t', a'))]) t' Appl rrs' end) 
    97                 handle Rewrite.NO_REWRITE => raise ERROR "derive_norm, Eval: no rewrite")
    98         | Rule.Rls_ rls =>
    99           (case Rewrite.rewrite_set_ ctxt true rls t of
   100             NONE => rew_once lim rts t apno rs'
   101           | SOME (t', a') => rew_once (lim - 1) (rts @ [(t, r, (t', a'))]) t' Appl rrs')
   102         | rule => raise ERROR ("rew_once: uncovered case " ^ Rule.to_string rule))
   103     | rew_or_calc _ _ _ _ [] = raise ERROR "rew_or_calc: called with []"
   104   in rew_once (Config.get ctxt rewrite_limit) [] tt Noap rs end
   105 
   106 
   107 (** concatenate several steps in revers order **)
   108 
   109 fun rev_deriv (t, r, (_, a)) = (ThmC.make_sym_rule r, (t, a));
   110 fun steps_reverse thy erls rs ro goal t =
   111     (rev o (map rev_deriv)) (do_one thy erls rs ro goal t)
   112 
   113 
   114 (** concatenate several steps **)
   115 
   116 fun rev_deriv' (t, r, (t', a)) = (t', ThmC.make_sym_rule r, (t, a));
   117 
   118 (* fo = ifo excluded already in inform *)
   119 fun steps rew_ord erls rules fo ifo =
   120   let 
   121     fun derivat ([]:(term * Rule.rule * (term * term list)) list) = TermC.empty
   122       | derivat dt = (#1 o #3 o last_elem) dt
   123     fun equal (_, _, (t1, _)) (_, _, (t2, _)) = t1 = t2
   124     val  fod = do_one (Proof_Context.init_global (ThyC.Isac())) erls rules (snd rew_ord) NONE  fo
   125     val ifod = do_one (Proof_Context.init_global (ThyC.Isac())) erls rules (snd rew_ord) NONE ifo
   126   in 
   127     case (fod, ifod) of
   128       ([], []) => if fo = ifo then (true, []) else (false, [])
   129     | (fod, []) => if derivat fod = ifo then (true, fod) (*ifo is normal form*) else (false, [])
   130     | ([], ifod) => if fo = derivat ifod then (true, ((map rev_deriv') o rev) ifod) else (false, [])
   131     | (fod, ifod) =>
   132       if derivat fod = derivat ifod (*common normal form found*) then
   133         let 
   134           val (fod', rifod') = dropwhile' equal (rev fod) (rev ifod)
   135         in (true, fod' @ (map rev_deriv' rifod')) end
   136       else (false, [])
   137   end
   138 
   139 (** embed a derivation into the Ctree **)
   140 
   141 fun embed tacis (pt, pos as (p, Pos.Frm)) =
   142   (*inform at Frm: replace the whole PrfObj by a Transitive-ProfObj FIXME?0402
   143     and transfer the istate (from _after_ compare_deriv) from Frm to Res*)
   144     let
   145       val (res, asm) = (State_Steps.result o last_elem) tacis
   146     	val (ist, ctxt) = case Ctree.get_obj Ctree.g_loc pt p of
   147     	  (SOME (ist, ctxt), _) => (ist, ctxt)
   148       | (NONE, _) => raise ERROR "Derive.embed Frm: uncovered case get_obj"
   149     	val form =  Ctree.get_obj  Ctree.g_form pt p
   150       (*val p = lev_on p; ---------------only difference to (..,Res) below*)
   151     	val tacis = (Tactic.Begin_Trans, Tactic.Begin_Trans' form, (pos, (Istate_Def.Uistate, ctxt))) ::
   152     		(State_Steps.insert_pos ((Pos.lev_on o Pos.lev_dn) p) tacis) @ [(Tactic.End_Trans, Tactic.End_Trans' (res, asm),
   153     			(Pos.pos_plus (length tacis) (Pos.lev_dn p, Pos.Res), (Ctree.new_val res ist, ctxt)))]
   154     	val {nrls, ...} = MethodC.from_store (Ctree.get_obj Ctree.g_metID pt (Ctree.par_pblobj pt p))
   155     	val (pt, c, pos as (p, _)) = Solve_Step.s_add_general (rev tacis) (pt, [], (p, Pos.Res))
   156     	val pt = Ctree.update_tac pt p (Tactic.Derive (Rule_Set.id nrls))
   157     	val pt = Ctree.update_branch pt p Ctree.TransitiveB
   158     in (c, (pt, pos)) end
   159   | embed tacis (pt, (p, Pos.Res)) =
   160     (*inform at Res: append a Transitive-PrfObj FIXME?0402 other branch-types ?
   161       and transfer the istate (from _after_ compare_deriv) from Res to new Res*)
   162     let
   163       val (res, asm) = (State_Steps.result o last_elem) tacis
   164     	val (ist, ctxt) = case Ctree.get_obj Ctree.g_loc pt p of
   165     	  (_, SOME (ist, ctxt)) => (ist, ctxt)
   166       | (_, NONE) => raise ERROR "Derive.embed Frm: uncovered case get_obj"
   167     	val (f, _) = Ctree.get_obj Ctree.g_result pt p
   168     	val p = Pos.lev_on p(*---------------only difference to (..,Frm) above*);
   169     	val tacis = (Tactic.Begin_Trans, Tactic.Begin_Trans' f, ((p, Pos.Frm), (Istate_Def.Uistate, ctxt))) ::
   170     		(State_Steps.insert_pos ((Pos.lev_on o Pos.lev_dn) p) tacis) @ [(Tactic.End_Trans, Tactic.End_Trans' (res, asm), 
   171     			(Pos.pos_plus (length tacis) (Pos.lev_dn p, Pos.Res), (Ctree.new_val res ist, ctxt)))];
   172     	val {nrls, ...} = MethodC.from_store (Ctree.get_obj Ctree.g_metID pt (Ctree.par_pblobj pt p))
   173     	val (pt, c, pos as (p, _)) = Solve_Step.s_add_general (rev tacis) (pt, [], (p, Pos.Res))
   174     	val pt = Ctree.update_tac pt p (Tactic.Derive (Rule_Set.id nrls))
   175     	val pt = Ctree.update_branch pt p Ctree.TransitiveB
   176     in (c, (pt, pos)) end
   177   | embed _ _ = raise ERROR "Derive.embed: uncovered definition"
   178 
   179 (**)end(**)