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