src/Tools/isac/Interpret/rewtools.sml
author Walther Neuper <walther.neuper@jku.at>
Mon, 13 Apr 2020 18:32:01 +0200
changeset 59872 cea2815f65ed
parent 59868 d77aa0992e0f
child 59874 820bf0840029
permissions -rw-r--r--
reorganise struct. ThmC, part 2
walther@59848
     1
(* 
neuper@37906
     2
   authors: Walther Neuper 2002, 2006
neuper@37906
     3
  (c) due to copyright terms
walther@59848
     4
walther@59848
     5
tools for rewriting, reverse rewriting, context to thy concerning rewriting
neuper@37906
     6
*)
neuper@37906
     7
wneuper@59263
     8
signature REWRITE_TOOLS =
wneuper@59263
     9
sig
wneuper@59263
    10
  type deriv
walther@59851
    11
  val contains_rule : Rule.rule -> Rule_Set.T -> bool
walther@59851
    12
  val atomic_appl_tacs : theory -> string -> Rule_Set.T -> term -> Tactic.input -> Tactic.input list
walther@59867
    13
  val thy_containing_rls : ThyC.theory' -> Rule_Set.id -> string * ThyC.theory'
walther@59854
    14
  val thy_containing_cal : ThyC.theory' -> Exec_Def.prog_calcID -> string * string
wneuper@59263
    15
  datatype contthy
walther@59854
    16
  = ContNOrew of {applto: term, thm_rls: Celem.guh, thyID: ThyC.thyID}
walther@59863
    17
     | ContNOrewInst of {applto: term, bdvs: UnparseC.subst, thm_rls: Celem.guh, thminst: term, thyID: ThyC.thyID}
walther@59854
    18
     | ContRls of {applto: term, asms: term list, result: term, rls: Celem.guh, thyID: ThyC.thyID}
walther@59863
    19
     | ContRlsInst of {applto: term, asms: term list, bdvs: UnparseC.subst, result: term, rls: Celem.guh, thyID: ThyC.thyID}
walther@59867
    20
     | ContThm of {applat: term, applto: term, asmrls: Rule_Set.id, asms: (term * term) list,
walther@59857
    21
       lhs: term * term, resasms: term list, result: term, reword: Rewrite_Ord.rew_ord', rhs: term * term,
walther@59854
    22
       thm: Celem.guh, thyID: ThyC.thyID}
walther@59867
    23
     | ContThmInst of {applat: term, applto: term, asmrls: Rule_Set.id, asms: (term * term) list,
walther@59863
    24
       bdvs: UnparseC.subst, lhs: term * term, resasms: term list, result: term, reword: Rewrite_Ord.rew_ord',
walther@59854
    25
       rhs: term * term, thm: Celem.guh, thminst: term, thyID: ThyC.thyID}
wneuper@59263
    26
     | EContThy
wneuper@59405
    27
  val guh2filename : Celem.guh -> Celem.filename
walther@59851
    28
  val thms_of_rls : Rule_Set.T -> Rule.rule list
wneuper@59405
    29
  val theID2filename : Celem.theID -> Celem.filename
wneuper@59405
    30
  val no_thycontext : Celem.guh -> bool
wneuper@59572
    31
  val subs_from : Istate.T -> 'a -> Celem.guh -> Selem.subs
wneuper@59571
    32
  val guh2rewtac : Celem.guh -> Selem.subs -> Tactic.input
walther@59846
    33
  val get_tac_checked : Ctree.ctree -> Pos.pos' -> Tactic.input
walther@59775
    34
  val context_thy : Calc.T -> Tactic.input -> contthy
wneuper@59416
    35
  val distinct_Thm : Rule.rule list -> Rule.rule list
wneuper@59416
    36
  val eq_Thms : string list -> Rule.rule -> bool
walther@59851
    37
  val make_deriv : theory -> Rule_Set.T -> Rule.rule list -> ((term * term) list -> term * term -> bool) ->
wneuper@59263
    38
    term option -> term -> deriv
walther@59851
    39
  val reverse_deriv : theory -> Rule_Set.T -> Rule.rule list -> ((term * term) list -> term * term -> bool) ->
wneuper@59416
    40
    term option -> term -> (Rule.rule * (term * term list)) list
walther@59863
    41
  val get_bdv_subst : term -> (term * term) list -> Selem.subs option * UnparseC.subst
wneuper@59313
    42
  val thy_containing_thm : string -> string * string
wneuper@59405
    43
  val guh2theID : Celem.guh -> Celem.theID
wneuper@59310
    44
(* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
wneuper@59310
    45
  (*  NONE *)
walther@59785
    46
(*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
wneuper@59416
    47
  val trtas2str : (term * Rule.rule * (term * term list)) list -> string
wneuper@59416
    48
  val eq_Thm : Rule.rule * Rule.rule -> bool
wneuper@59416
    49
  val deriv2str : (term * Rule.rule * (term * term list)) list -> string
walther@59865
    50
  val deriv_of_thm'' : ThmC_Def.thm'' -> string
walther@59785
    51
( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
wneuper@59310
    52
wneuper@59310
    53
(*----- unused code, kept as hints to design ideas ---------------------------------------------*)
wneuper@59416
    54
  val deri2str : (Rule.rule * (term * term list)) list -> string
wneuper@59313
    55
  val sym_trm : term -> term
wneuper@59263
    56
end 
walther@59848
    57
(**)
wneuper@59263
    58
structure Rtools(**): REWRITE_TOOLS(**) =
wneuper@59263
    59
struct
walther@59848
    60
(**)
wneuper@59313
    61
wneuper@59263
    62
(*** reverse rewriting ***)
wneuper@59266
    63
(*. a '_deriv'ation is constructed during 'reverse rewring' by an Rrls       *
wneuper@59266
    64
 *  of for connecting a user-input formula with the current calc-state.	     *
wneuper@59266
    65
 *# It is somewhat incompatible with the rest of the math-engine:	     *
wneuper@59266
    66
 *  (1) it is not created by a script					     *
wneuper@59266
    67
 *  (2) thus there cannot be another user-input within a derivation	     *
wneuper@59266
    68
 *# It suffers particularily from the not-well-foundedness of the math-engine*
wneuper@59266
    69
 *  (1) FIXME other branchtyptes than Transitive will change 'embed_deriv'   *
wneuper@59266
    70
 *  (2) FIXME and eventually 'compare_step' (ie. the script interpreter)     *
wneuper@59266
    71
 *  (3) FIXME and eventually 'lev_back'                                      *
wneuper@59266
    72
 *# SOME improvements are evident FIXME.040215 '_deriv'ation:	             *
wneuper@59266
    73
 *  (1) FIXME nest Rls_ in 'make_deriv'					     *
wneuper@59266
    74
 *  (2) FIXME do the not-reversed part in 'make_deriv' by scripts -- thus    *
wneuper@59266
    75
 *	user-input will become possible in this part of a derivation	     *
wneuper@59266
    76
 *  (3) FIXME do (2) only if a derivation has been found -- for efficiency,  *
wneuper@59266
    77
 *	while a non-derivable inform requires to step until End_Proof'	     *
wneuper@59266
    78
 *  (4) FIXME find criteria on when _not_ to step until End_Proof'           *
wneuper@59266
    79
 *  (5) FIXME 
wneuper@59266
    80
.*)
walther@59848
    81
type deriv =      (* derivation for insertin one level of nodes into the Ctree *) 
walther@59848
    82
  ( term *        (* where the rule is applied to                              *)
walther@59848
    83
    Rule.rule *   (* rule to be applied                                        *)
walther@59848
    84
    ( term *      (* resulting from rule application                           *)
walther@59848
    85
      term list)) (* assumptions resulting from rule application               *)
walther@59848
    86
  list
neuper@37906
    87
wneuper@59263
    88
fun trta2str (t, r, (t', a)) =
walther@59868
    89
  "\n(" ^ UnparseC.term t ^ ", " ^ Rule.to_string_short r ^ ", (" ^ UnparseC.term t' ^ ", " ^ UnparseC.terms a ^ "))"
wneuper@59263
    90
fun trtas2str trtas = (strs2str o (map trta2str)) trtas
wneuper@59263
    91
val deriv2str = trtas2str
wneuper@59263
    92
fun rta2str (r, (t, a)) =
walther@59868
    93
  "\n(" ^ Rule.to_string_short r ^ ", (" ^ UnparseC.term t ^ ", " ^ UnparseC.terms a ^ "))"
wneuper@59263
    94
fun rtas2str rtas = (strs2str o (map rta2str)) rtas
wneuper@59263
    95
val deri2str = rtas2str
neuper@37906
    96
wneuper@59263
    97
(* WN100910 weaker than fun sym_thm for Theory.axioms_of in isa02 *)
neuper@38002
    98
fun sym_trm trm =
wneuper@59263
    99
  let
wneuper@59390
   100
    val (lhs, rhs) = (TermC.dest_equals o TermC.strip_trueprop o Logic.strip_imp_concl) trm
wneuper@59389
   101
    val trm' = case TermC.strip_imp_prems' trm of
wneuper@59389
   102
	      NONE => TermC.mk_equality (rhs, lhs)
wneuper@59389
   103
	    | SOME cs => TermC.ins_concl cs (TermC.mk_equality (rhs, lhs))
wneuper@59263
   104
  in trm' end
neuper@37906
   105
neuper@55487
   106
(* derive normalform of a rls, or derive until SOME goal,
neuper@37906
   107
   and record rules applied and rewrites.
neuper@37906
   108
val it = fn
neuper@37906
   109
  : theory
neuper@37906
   110
    -> rls
neuper@37906
   111
    -> rule list
neuper@37906
   112
    -> rew_ord       : the order of this rls, which 1 theorem of is used 
neuper@37906
   113
                       for rewriting 1 single step (?14.4.03)
neuper@55487
   114
    -> term option   : 040214 ??? use for "derive until SOME goal" ??? 
neuper@37906
   115
    -> term 
neuper@37906
   116
    -> (term *       : to this term ...
neuper@37906
   117
        rule * 	     : ... this rule is applied yielding ...
neuper@37906
   118
        (term *      : ... this term ...
neuper@37906
   119
         term list)) : ... under these assumptions.
neuper@37906
   120
       list          :
neuper@37906
   121
returns empty list for a normal form
neuper@37906
   122
FIXME.WN040214: treats rules as in Rls, _not_ as in Seq
neuper@37906
   123
neuper@37906
   124
WN060825 too complicated for the intended use by cancel_, common_nominator_
neuper@55487
   125
and unreflectedly adapted to extension of rules by Rls_: returns Rls_("sym_simpl..
neuper@55487
   126
 -- replaced below *)
wneuper@59405
   127
fun make_deriv thy erls rs ro goal tt = 
neuper@55487
   128
  let 
wneuper@59263
   129
    datatype switch = Appl | Noap (* unify with version in rewrite.sml *)
wneuper@59263
   130
    fun rew_once _ rts t Noap [] = 
walther@59868
   131
        (case goal of NONE => rts | SOME _ => error ("make_deriv: no derivation for " ^ UnparseC.term t))
neuper@55487
   132
      | rew_once lim rts t Appl [] = rew_once lim rts t Noap rs
neuper@55487
   133
        (*| Seq _ => rts) FIXXXXXME 14.3.03*)
neuper@55487
   134
      | rew_once lim rts t apno rs' =
neuper@55487
   135
        (case goal of 
neuper@55487
   136
          NONE => rew_or_calc lim rts t apno rs'
neuper@55487
   137
        | SOME g => if g = t then rts else rew_or_calc lim rts t apno rs')
neuper@55487
   138
    and rew_or_calc lim rts t apno (rrs' as (r :: rs')) =
neuper@55487
   139
      if lim < 0 
wneuper@59405
   140
      then (tracing ("make_deriv exceeds " ^ int2str (! Celem.lim_deriv) ^ "with deriv =\n");
wneuper@59263
   141
        tracing (deriv2str rts); rts)
neuper@55487
   142
      else
wneuper@59263
   143
        (case r of
wneuper@59416
   144
          Rule.Thm (thmid, tm) => 
wneuper@59405
   145
            (if not (! Celem.trace_rewrite) then () else tracing ("### trying thm \"" ^ thmid ^ "\"");
wneuper@59380
   146
            case Rewrite.rewrite_ thy ro erls true tm t of
neuper@55487
   147
              NONE => rew_once lim rts t apno rs'
neuper@55487
   148
            | SOME (t', a') =>
walther@59868
   149
              (if ! Celem.trace_rewrite then tracing ("=== rewrites to: " ^ UnparseC.term t') else ();
neuper@55487
   150
              rew_once (lim - 1) (rts @ [(t, r, (t', a'))]) t' Appl rrs'))
walther@59773
   151
        | Rule.Num_Calc (c as (op_, _)) => 
neuper@55487
   152
          let 
wneuper@59405
   153
            val _ = if not (! Celem.trace_rewrite) then () else tracing ("### trying calc. \"" ^ op_^"\"")
wneuper@59389
   154
            val t = TermC.uminus_to_string t
neuper@55487
   155
          in 
walther@59773
   156
            case Num_Calc.adhoc_thm thy c t of
neuper@55487
   157
              NONE => rew_once lim rts t apno rs'
neuper@55487
   158
            | SOME (thmid, tm) => 
neuper@55487
   159
              (let
wneuper@59380
   160
                val (t', a') = case Rewrite.rewrite_ thy ro erls true tm t of
wneuper@59263
   161
                  SOME ta => ta
wneuper@59263
   162
                | NONE => error "adhoc_thm: NONE"
walther@59868
   163
                val _ = if not (! Celem.trace_rewrite) then () else tracing("=== calc. to: " ^ UnparseC.term t')
wneuper@59416
   164
                val r' = Rule.Thm (thmid, tm)
neuper@55487
   165
              in rew_once (lim - 1) (rts @ [(t, r', (t', a'))]) t' Appl rrs' end) 
walther@59773
   166
                handle _ => error "derive_norm, Num_Calc: no rewrite"
neuper@55487
   167
          end
neuper@55487
   168
      (*| Cal1 (cc as (op_,_)) => ... WN080222 see rewrite__set_: see 7df94616c1bd and earlier*)
wneuper@59416
   169
        | Rule.Rls_ rls =>           (* WN060829: CREATES "sym_rlsID", see 7df94616c1bd and earlier*)
wneuper@59380
   170
          (case Rewrite.rewrite_set_ thy true rls t of
wneuper@59263
   171
            NONE => rew_once lim rts t apno rs'
wneuper@59263
   172
          | SOME (t', a') => rew_once (lim - 1) (rts @ [(t, r, (t', a'))]) t' Appl rrs')
walther@59867
   173
        | rule => error ("rew_once: uncovered case " ^ Rule.to_string rule))
wneuper@59263
   174
    | rew_or_calc _ _ _ _ [] = error "rew_or_calc: called with []"
wneuper@59405
   175
  in rew_once (! Celem.lim_deriv) [] tt Noap rs end
neuper@37906
   176
neuper@37906
   177
(*version for reverse rewrite used before 040214*)
walther@59872
   178
fun rev_deriv (t, r, (_, a)) = (ThmC.sym_rule r, (t, a));
wneuper@59405
   179
fun reverse_deriv thy erls rs ro goal t =
wneuper@59405
   180
    (rev o (map rev_deriv)) (make_deriv thy erls rs ro goal t)
neuper@37906
   181
wneuper@59416
   182
fun eq_Thm (Rule.Thm (id1, _), Rule.Thm (id2,_)) = id1 = id2
wneuper@59416
   183
  | eq_Thm (Rule.Thm (_, _), _) = false
walther@59867
   184
  | eq_Thm (Rule.Rls_ r1, Rule.Rls_ r2) = Rule_Set.id r1 = Rule_Set.id r2
wneuper@59416
   185
  | eq_Thm (Rule.Rls_ _, _) = false
walther@59867
   186
  | eq_Thm (r1, r2) = error ("eq_Thm: called with '" ^ Rule.to_string r1 ^ "' '" ^ Rule.to_string r2 ^ "'")
wneuper@59263
   187
fun distinct_Thm r = gen_distinct eq_Thm r
neuper@37906
   188
walther@59865
   189
fun eq_Thms thmIDs thm = (member op = thmIDs (ThmC_Def.id_of_thm thm))
wneuper@59263
   190
  handle ERROR _ => false
neuper@37906
   191
neuper@42400
   192
fun thy_containing_thm thmDeriv =
neuper@42400
   193
  let
wneuper@59405
   194
    val isabthys' = map Context.theory_name (Celem.isabthys ());
neuper@42400
   195
  in
walther@59862
   196
    if member op= isabthys' (ThyC.thyID_of_derivation_name thmDeriv)
walther@59862
   197
    then ("Isabelle", ThyC.thyID_of_derivation_name thmDeriv)
walther@59862
   198
    else ("IsacKnowledge", ThyC.thyID_of_derivation_name thmDeriv)
wneuper@59263
   199
  end
neuper@37906
   200
neuper@55457
   201
(* which theory in ancestors of thy' contains a ruleset *)
wneuper@59405
   202
fun thy_containing_rls thy' rls' =
neuper@55457
   203
  let
walther@59854
   204
    val thy = ThyC.Thy_Info_get_theory thy'
neuper@55457
   205
  in
neuper@55457
   206
    case AList.lookup op= (KEStore_Elems.get_rlss thy) rls' of
wneuper@59405
   207
      SOME (thy'', _) => (Celem.partID' thy'', thy'')
neuper@55457
   208
    | _ => error ("thy_containing_rls : rls '" ^ rls' ^ "' not in ancestors of thy '" ^ thy' ^ "'")
neuper@55457
   209
  end
neuper@37906
   210
neuper@55457
   211
(* this function cannot work as long as the datastructure does not contain thy' *)
wneuper@59405
   212
fun thy_containing_cal thy' sop =
neuper@42407
   213
  let
walther@59854
   214
    val thy = ThyC.Thy_Info_get_theory thy'
neuper@55457
   215
  in
neuper@55457
   216
    case AList.lookup op= (KEStore_Elems.get_calcs thy) sop of
walther@59603
   217
      SOME (_(*"Groups.plus_class.plus"*), _) => ("IsacKnowledge", "Base_Tools")
neuper@55457
   218
    | _ => error ("thy_containing_cal : rls '" ^ sop ^ "' not in ancestors of thy '" ^ thy' ^ "'")
neuper@42407
   219
  end
neuper@37906
   220
wneuper@59263
   221
(* packing return-values to matchTheory, contextToThy for xml-generation *)
walther@59850
   222
datatype contthy =  (*also an item from KEStore on Browser ...........#*)
wneuper@59263
   223
	EContThy   (* not from KEStore ..............................*)
wneuper@59263
   224
  | ContThm of (* a theorem in contex ===========================*)
walther@59854
   225
    {thyID   : ThyC.thyID,      (* for *2guh in sub-elems here        .*)
wneuper@59405
   226
     thm     : Celem.guh,       (* theorem in the context             .*)
wneuper@59405
   227
     applto  : term,	          (* applied to formula ...             .*)
wneuper@59405
   228
     applat  : term,	          (* ...  with lhs inserted             .*)
walther@59857
   229
     reword  : Rewrite_Ord.rew_ord',   (* order used for rewrite             .*)
wneuper@59405
   230
     asms    : (term            (* asumption instantiated             .*)
wneuper@59405
   231
   	   * term) list,            (* asumption evaluated                .*)
wneuper@59405
   232
     lhs     : term             (* lhs of the theorem ...             #*)
wneuper@59405
   233
   	   * term,                  (* ... instantiated                   .*)
wneuper@59405
   234
     rhs     : term             (* rhs of the theorem ...             #*)
wneuper@59405
   235
   	   * term,                  (* ... instantiated                   .*)
wneuper@59405
   236
     result  : term,	          (* resulting from the rewrite         .*)
wneuper@59405
   237
     resasms : term list,       (* ... with asms stored               .*)
walther@59867
   238
     asmrls  : Rule_Set.id        (* ruleset for evaluating asms        .*)
wneuper@59263
   239
   	}						 
wneuper@59263
   240
  | ContThmInst of (* a theorem with bdvs in contex ============ *)
walther@59854
   241
    {thyID   : ThyC.thyID,      (*for *2guh in sub-elems here         .*)
wneuper@59405
   242
     thm     : Celem.guh,       (*theorem in the context              .*)
walther@59863
   243
     bdvs    : UnparseC.subst,      (*bound variables to modify...        .*)
wneuper@59405
   244
     thminst : term,            (*... theorem instantiated            .*)
wneuper@59405
   245
     applto  : term,	          (*applied to formula ...              .*)
wneuper@59405
   246
     applat  : term,	          (*...  with lhs inserted              .*)
walther@59857
   247
     reword  : Rewrite_Ord.rew_ord',   (*order used for rewrite              .*)
wneuper@59405
   248
     asms    : (term            (*asumption instantiated              .*)
wneuper@59405
   249
   	   * term) list,            (*asumption evaluated                 .*)
wneuper@59405
   250
     lhs     : term             (*lhs of the theorem ...              #*)
wneuper@59405
   251
   	   * term,                  (*... instantiated                    .*)
wneuper@59405
   252
     rhs     : term             (*rhs of the theorem ...              #*)
wneuper@59405
   253
   	   * term,                  (*... instantiated                    .*)
wneuper@59405
   254
     result  : term,	          (*resulting from the rewrite          .*)
wneuper@59405
   255
     resasms : term list,       (*... with asms stored                .*)
walther@59867
   256
     asmrls  : Rule_Set.id        (*ruleset for evaluating asms         .*)
wneuper@59263
   257
    }						 
wneuper@59263
   258
  | ContRls of (* a rule set in contex ========================= *)
walther@59854
   259
    {thyID   : ThyC.thyID,      (*for *2guh in sub-elems here         .*)
wneuper@59405
   260
     rls     : Celem.guh,       (*rule set in the context             .*)
wneuper@59405
   261
     applto  : term,	          (*rewrite this formula                .*)
wneuper@59405
   262
     result  : term,	          (*resulting from the rewrite          .*)
wneuper@59405
   263
     asms    : term list        (*... with asms stored                .*)
wneuper@59263
   264
   	}						 
wneuper@59263
   265
  | ContRlsInst of (* a rule set with bdvs in contex =========== *)
walther@59854
   266
	{thyID   : ThyC.thyID,        (*for *2guh in sub-elems here         .*)
wneuper@59405
   267
	 rls     : Celem.guh,         (*rule set in the context             .*)
walther@59863
   268
	 bdvs    : UnparseC.subst,        (*for bound variables in thms         .*)
wneuper@59405
   269
	 applto  : term,	            (*rewrite this formula                .*)
wneuper@59405
   270
	 result  : term,	            (*resulting from the rewrite          .*)
wneuper@59405
   271
	 asms    : term list          (*... with asms stored                .*)
wneuper@59263
   272
   	}						 
wneuper@59263
   273
  | ContNOrew of (* no rewrite for thm or rls ================== *)
walther@59854
   274
    {thyID   : ThyC.thyID,      (*for *2guh in sub-elems here         .*)
wneuper@59405
   275
     thm_rls : Celem.guh,       (*thm or rls in the context           .*)
wneuper@59405
   276
     applto  : term	            (*rewrite this formula                .*)
wneuper@59263
   277
   	}						 
wneuper@59263
   278
  | ContNOrewInst of (* no rewrite for some instantiation ====== *)
walther@59854
   279
    {thyID   : ThyC.thyID,      (*for *2guh in sub-elems here         .*)
wneuper@59405
   280
     thm_rls : Celem.guh,       (*thm or rls in the context           .*)
walther@59863
   281
     bdvs    : UnparseC.subst,      (*for bound variables in thms         .*)
wneuper@59405
   282
     thminst : term,            (*... theorem instantiated            .*)
walther@59850
   283
     applto  : term	            (*rewrite this formula                .*)
wneuper@59263
   284
   	}						 
neuper@37906
   285
neuper@37906
   286
(*.check a rewrite-tac for bdv (RL always used *_Inst !) TODO.WN060718
neuper@37906
   287
   pass other tacs unchanged.*)
walther@59846
   288
fun get_tac_checked pt ((p, _) : Pos.pos') = Ctree.get_obj Ctree.g_tac pt p;
neuper@37906
   289
wneuper@59252
   290
(* create a derivation-name, eg. ("refl", _) --> "HOL.refl"*)
wneuper@59405
   291
fun deriv_of_thm'' (thmID, _) =
walther@59854
   292
  thmID |> Global_Theory.get_thm (ThyC.Isac ()) |> Thm.get_name_hint
neuper@37906
   293
wneuper@59252
   294
(* get the formula f at ptp rewritten by the Rewrite_* already applied to f *)
wneuper@59571
   295
fun context_thy (pt, pos as (p,p_)) (tac as Tactic.Rewrite thm'') =
wneuper@59263
   296
    let val thm_deriv = deriv_of_thm'' thm''
wneuper@59263
   297
    in
wneuper@59272
   298
    (case Applicable.applicable_in pos pt tac of
walther@59735
   299
      Applicable.Appl (Tactic.Rewrite' (thy', ord', erls, _, _, f, (res,asm))) =>
wneuper@59263
   300
        ContThm
walther@59854
   301
         {thyID = ThyC.theory'2thyID thy',
walther@59865
   302
          thm = Celem.thm2guh (thy_containing_thm thm_deriv) (ThmC_Def.thmID_of_derivation_name thm_deriv),
walther@59861
   303
          applto = f, applat  = TermC.empty, reword  = ord',
walther@59861
   304
          asms = [](*asms ~~ asms'*), lhs = (TermC.empty, TermC.empty)(*(lhs, lhs')*), rhs = (TermC.empty, TermC.empty)(*(rhs, rhs')*),
walther@59867
   305
          result = res, resasms = asm, asmrls  = Rule_Set.id erls}
walther@59735
   306
     | Applicable.Notappl _ =>
wneuper@59263
   307
         let
wneuper@59276
   308
           val pp = Ctree.par_pblobj pt p
wneuper@59276
   309
           val thy' = Ctree.get_obj Ctree.g_domID pt pp
wneuper@59263
   310
           val f = case p_ of
walther@59694
   311
             Pos.Frm => Ctree.get_obj Ctree.g_form pt p
walther@59694
   312
           | Pos.Res => (fst o (Ctree.get_obj Ctree.g_result pt)) p 
wneuper@59313
   313
           | _ => error "context_thy: uncovered position"
wneuper@59263
   314
         in
wneuper@59263
   315
           ContNOrew
walther@59854
   316
            {thyID   = ThyC.theory'2thyID thy',
wneuper@59263
   317
             thm_rls = 
walther@59865
   318
               Celem.thm2guh (thy_containing_thm thm_deriv) (ThmC_Def.thmID_of_derivation_name thm_deriv),
wneuper@59263
   319
             applto  = f}
wneuper@59263
   320
		     end
wneuper@59263
   321
     | _ => error "context_thy..Rewrite: uncovered case 2")
wneuper@59263
   322
    end
wneuper@59571
   323
  | context_thy (pt, pos as (p, p_)) (tac as Tactic.Rewrite_Inst (subs, (thmID, _))) =
walther@59854
   324
    let val thm = Global_Theory.get_thm (ThyC.Isac ()) thmID
wneuper@59263
   325
    in
wneuper@59272
   326
	  (case Applicable.applicable_in pos pt tac of
walther@59735
   327
	     Applicable.Appl (Tactic.Rewrite_Inst' (thy', ord', erls, _, subst, _, f, (res, asm))) =>
wneuper@59263
   328
	       let
wneuper@59263
   329
           val thm_deriv = Thm.get_name_hint thm
walther@59773
   330
           val thminst = TermC.inst_bdv subst ((Num_Calc.norm o #prop o Thm.rep_thm) thm)
wneuper@59263
   331
	       in
wneuper@59263
   332
	         ContThmInst
walther@59854
   333
	          {thyID = ThyC.theory'2thyID thy',
wneuper@59263
   334
	           thm = 
walther@59865
   335
	             Celem.thm2guh (thy_containing_thm thm_deriv) (ThmC_Def.thmID_of_derivation_name thm_deriv),
walther@59861
   336
	           bdvs = subst, thminst = thminst, applto  = f, applat  = TermC.empty, reword  = ord',
walther@59861
   337
	           asms = [](*asms ~~ asms'*), lhs = (TermC.empty, TermC.empty)(*(lhs, lhs')*), rhs = (TermC.empty, TermC.empty)(*(rhs, rhs')*),
walther@59867
   338
	           result = res, resasms = asm, asmrls  = Rule_Set.id erls}
wneuper@59263
   339
	       end
walther@59735
   340
     | Applicable.Notappl _ =>
wneuper@59263
   341
         let
walther@59854
   342
           val thm = Global_Theory.get_thm (ThyC.Isac ()(*WN141021 assoc_thy thy' ERROR*)) thmID
wneuper@59263
   343
           val thm_deriv = Thm.get_name_hint thm
wneuper@59276
   344
           val pp = Ctree.par_pblobj pt p
wneuper@59276
   345
           val thy' = Ctree.get_obj Ctree.g_domID pt pp
wneuper@59405
   346
           val subst = Selem.subs2subst (Celem.assoc_thy thy') subs
walther@59773
   347
           val thminst = TermC.inst_bdv subst ((Num_Calc.norm o #prop o Thm.rep_thm) thm)
wneuper@59263
   348
           val f = case p_ of
walther@59694
   349
               Pos.Frm => Ctree.get_obj Ctree.g_form pt p
walther@59694
   350
             | Pos.Res => (fst o (Ctree.get_obj Ctree.g_result pt)) p 
wneuper@59313
   351
             | _ => error "context_thy: uncovered case 3"
wneuper@59263
   352
         in
wneuper@59263
   353
           ContNOrewInst
walther@59854
   354
            {thyID = ThyC.theory'2thyID thy',
walther@59865
   355
             thm_rls = Celem.thm2guh (thy_containing_thm thm_deriv) (ThmC_Def.thmID_of_derivation_name thm_deriv),
wneuper@59263
   356
             bdvs = subst, thminst = thminst, applto = f}
wneuper@59263
   357
         end
wneuper@59263
   358
      | _ => error "context_thy..Rewrite_Inst: uncovered case 4")
wneuper@59263
   359
    end
wneuper@59571
   360
  | context_thy (pt, p) (tac as Tactic.Rewrite_Set rls') =
wneuper@59272
   361
    (case Applicable.applicable_in p pt tac of
walther@59735
   362
       Applicable.Appl (Tactic.Rewrite_Set' (thy', _, _(*rls*), f, (res,asm))) =>
wneuper@59263
   363
         ContRls
walther@59854
   364
          {thyID = ThyC.theory'2thyID thy',
wneuper@59405
   365
           rls = Celem.rls2guh (thy_containing_rls thy' rls') rls',
wneuper@59263
   366
           applto = f, result = res, asms = asm}
walther@59735
   367
     | _ => error ("context_thy Rewrite_Set: not for Applicable.Notappl"))
wneuper@59571
   368
  | context_thy (pt,p) (tac as Tactic.Rewrite_Set_Inst (_(*subs*), rls')) = 
wneuper@59272
   369
    (case Applicable.applicable_in p pt tac of
walther@59735
   370
       Applicable.Appl (Tactic.Rewrite_Set_Inst' (thy', _, subst, _, f, (res,asm))) =>
wneuper@59263
   371
         ContRlsInst
walther@59854
   372
          {thyID = ThyC.theory'2thyID thy',
wneuper@59405
   373
           rls = Celem.rls2guh (thy_containing_rls thy' rls') rls',
wneuper@59263
   374
           bdvs = subst, applto = f, result = res, asms = asm}
walther@59735
   375
     | _ => error ("context_thy Rewrite_Set_Inst: not for Applicable.Notappl"))
wneuper@59263
   376
  | context_thy (_, p) tac =
walther@59846
   377
      error ("context_thy: not for tac " ^ Tactic.input_to_string tac ^ " at " ^ Pos.pos'2str p)
neuper@37906
   378
neuper@42372
   379
(* get all theorems in a rule set (recursivley containing rule sets) *)
wneuper@59416
   380
fun thm_of_rule Rule.Erule = []
wneuper@59416
   381
  | thm_of_rule (thm as Rule.Thm _) = [thm]
walther@59773
   382
  | thm_of_rule (Rule.Num_Calc _) = []
wneuper@59416
   383
  | thm_of_rule (Rule.Cal1 _) = []
wneuper@59416
   384
  | thm_of_rule (Rule.Rls_ rls) = thms_of_rls rls
walther@59851
   385
and thms_of_rls Rule_Set.Empty = []
walther@59851
   386
  | thms_of_rls (Rule_Def.Repeat {rules,...}) = (flat o (map  thm_of_rule)) rules
walther@59851
   387
  | thms_of_rls (Rule_Set.Seqence {rules,...}) = (flat o (map  thm_of_rule)) rules
walther@59850
   388
  | thms_of_rls (Rule_Set.Rrls _) = []
neuper@37906
   389
wneuper@59263
   390
(* check if a rule is contained in a rule-set (recursivley down in Rls_);
wneuper@59263
   391
   this rule can even be a rule-set itself                             *)
neuper@37906
   392
fun contains_rule r rls = 
wneuper@59263
   393
  let 
wneuper@59263
   394
    fun (*find (_, Rls_ rls) = finds (get_rules rls)
walther@59867
   395
      | find r12 = equal r12
wneuper@59263
   396
    and*) finds [] = false
walther@59867
   397
    | finds (r1 :: rs) = if Rule.equal (r, r1) then true else finds rs
wneuper@59263
   398
  in 
walther@59850
   399
    finds (Rule_Set.get_rules rls) 
wneuper@59263
   400
  end
neuper@37906
   401
wneuper@59263
   402
(* try if a rewrite-rule is applicable to a given formula; 
wneuper@59263
   403
   in case of rule-sets (recursivley) collect all _atomic_ rewrites *) 
walther@59863
   404
fun try_rew thy ((_, ro) : Rewrite_Ord.rew_ord) erls (subst : UnparseC.subst) f (thm' as Rule.Thm (_, thm)) =
walther@59618
   405
    if Auto_Prog.contains_bdv thm
wneuper@59380
   406
    then case Rewrite.rewrite_inst_ thy ro erls false subst thm f of
wneuper@59571
   407
	    SOME _ => [Tactic.rule2tac thy subst thm']
wneuper@59263
   408
	  | NONE => []
wneuper@59380
   409
    else (case Rewrite.rewrite_ thy ro erls false thm f of
wneuper@59571
   410
	    SOME _ => [Tactic.rule2tac thy [] thm']
wneuper@59263
   411
	  | NONE => [])
walther@59773
   412
  | try_rew thy _ _ _ f (cal as Rule.Num_Calc c) = 
walther@59773
   413
    (case Num_Calc.adhoc_thm thy c f of
wneuper@59571
   414
	    SOME _ => [Tactic.rule2tac thy [] cal]
wneuper@59263
   415
    | NONE => [])
wneuper@59416
   416
  | try_rew thy _ _ _ f (cal as Rule.Cal1 c) = 
walther@59773
   417
    (case Num_Calc.adhoc_thm thy c f of
wneuper@59571
   418
	      SOME _ => [Tactic.rule2tac thy [] cal]
neuper@37926
   419
      | NONE => [])
wneuper@59416
   420
  | try_rew thy _ _ subst f (Rule.Rls_ rls) = filter_appl_rews thy subst f rls
wneuper@59263
   421
  | try_rew _ _ _ _ _ _ = error "try_rew: uncovered case"
walther@59851
   422
and filter_appl_rews thy subst f (Rule_Def.Repeat {rew_ord = ro, erls, rules, ...}) = 
wneuper@59571
   423
    gen_distinct Tactic.eq_tac (flat (map (try_rew thy ro erls subst f) rules))
walther@59851
   424
  | filter_appl_rews thy subst f (Rule_Set.Seqence {rew_ord = ro, erls, rules,...}) = 
wneuper@59571
   425
    gen_distinct Tactic.eq_tac (flat (map (try_rew thy ro erls subst f) rules))
walther@59850
   426
  | filter_appl_rews _ _ _ (Rule_Set.Rrls _) = []
wneuper@59263
   427
  | filter_appl_rews _ _ _ _ = error "filter_appl_rews: uncovered case"
neuper@37906
   428
wneuper@59263
   429
(* decide if a tactic is applicable to a given formula; 
wneuper@59263
   430
   in case of Rewrite_Set* go down to _atomic_ rewrite-tactics *)
wneuper@59571
   431
fun atomic_appl_tacs thy _ _ f (Tactic.Calculate scrID) =
walther@59857
   432
    try_rew thy Rewrite_Ord.e_rew_ordX Rule_Set.empty [] f (Rule.Num_Calc (assoc_calc' thy scrID |> snd))
wneuper@59571
   433
  | atomic_appl_tacs thy ro erls f (Tactic.Rewrite thm'') =
walther@59857
   434
    try_rew thy (ro, Rewrite_Ord.assoc_rew_ord ro) erls [] f (Rule.Thm thm'')
wneuper@59571
   435
  | atomic_appl_tacs thy ro erls f (Tactic.Rewrite_Inst (subs, thm'')) =
walther@59857
   436
    try_rew thy (ro, Rewrite_Ord.assoc_rew_ord ro) erls (Selem.subs2subst thy subs) f (Rule.Thm thm'')
neuper@37906
   437
wneuper@59571
   438
  | atomic_appl_tacs thy _ _ f (Tactic.Rewrite_Set rls') =
neuper@37906
   439
    filter_appl_rews thy [] f (assoc_rls rls')
wneuper@59571
   440
  | atomic_appl_tacs thy _ _ f (Tactic.Rewrite_Set_Inst (subs, rls')) =
wneuper@59301
   441
    filter_appl_rews thy (Selem.subs2subst thy subs) f (assoc_rls rls')
neuper@37906
   442
  | atomic_appl_tacs _ _ _ _ tac = 
walther@59846
   443
    (tracing ("### atomic_appl_tacs: not impl. for tac = '" ^ Tactic.input_to_string tac ^ "'"); []);
neuper@37906
   444
wneuper@59263
   445
(* filenames not only for thydata, but also for thy's etc *)
wneuper@59405
   446
fun theID2filename theID = Celem.theID2guh theID ^ ".xml"
neuper@37906
   447
wneuper@59405
   448
fun guh2theID guh =
wneuper@59263
   449
  let
wneuper@59263
   450
    val guh' = Symbol.explode guh
wneuper@59263
   451
    val part = implode (take_fromto 1 4 guh')
wneuper@59263
   452
    val isa = implode (take_fromto 5 9 guh')
wneuper@59263
   453
  in
wneuper@59263
   454
    if not (member op = ["exp_", "thy_", "pbl_", "met_"] part)
wneuper@59263
   455
    then raise ERROR ("guh '" ^ guh ^ "' does not begin with exp_ | thy_ | pbl_ | met_")
wneuper@59263
   456
    else
wneuper@59263
   457
      let
wneuper@59263
   458
  	    val chap = case isa of
wneuper@59263
   459
  		  "isab_" => "Isabelle"
wneuper@59263
   460
  		| "scri_" => "IsacScripts"
wneuper@59263
   461
  		| "isac_" => "IsacKnowledge"
wneuper@59263
   462
  		| _ =>
wneuper@59263
   463
  		  raise ERROR ("guh2theID: '" ^ guh ^ "' does not have isab_ | scri_ | isac_ at position 5..9")
wneuper@59263
   464
        val rest = takerest (9, guh') 
wneuper@59263
   465
        val thyID = takewhile [] (not o (curry op= "-")) rest
wneuper@59263
   466
        val rest' = dropuntil (curry op = "-") rest
neuper@37906
   467
	    in case implode rest' of
wneuper@59405
   468
		    "-part" => [chap] : Celem.theID
wneuper@59263
   469
      | "" => [chap, implode thyID]
wneuper@59263
   470
      | "-Theorems" => [chap, implode thyID, "Theorems"]
wneuper@59263
   471
      | "-Rulesets" => [chap, implode thyID, "Rulesets"]
wneuper@59263
   472
      | "-Operations" => [chap, implode thyID, "Operations"]
wneuper@59263
   473
      | "-Orders" => [chap, implode thyID, "Orders"]
wneuper@59263
   474
      | _ => 
wneuper@59263
   475
		    let val sect = implode (take_fromto 1 5 rest')
wneuper@59263
   476
		       val sect' = case sect of
neuper@37906
   477
			       "-thm-" => "Theorems"
neuper@37906
   478
			     | "-rls-" => "Rulesets"
neuper@37906
   479
			     | "-cal-" => "Operations"
neuper@37906
   480
			     | "-ord-" => "Orders"
wneuper@59263
   481
			     | _ =>
wneuper@59263
   482
			     raise ERROR ("guh2theID: '" ^ guh ^ "' has '" ^ sect ^ "' instead -thm- | -rls- | -cal- | -ord-")
wneuper@59263
   483
		    in
wneuper@59263
   484
		      [chap, implode thyID, sect', implode (takerest (5, rest'))]
wneuper@59263
   485
		    end
neuper@37906
   486
	    end	
wneuper@59263
   487
    end
neuper@37906
   488
wneuper@59405
   489
fun guh2filename guh = guh ^ ".xml";
neuper@37906
   490
wneuper@59301
   491
fun guh2rewtac guh [] =
wneuper@59263
   492
    let
wneuper@59263
   493
      val (_, thy, sect, xstr) = case guh2theID guh of
wneuper@59263
   494
        [isa, thy, sect, xstr] => (isa, thy, sect, xstr)
wneuper@59263
   495
      | _ => error "guh2rewtac: uncovered case"
wneuper@59263
   496
    in case sect of
walther@59872
   497
      "Theorems" => Tactic.Rewrite (xstr, ThmC.assoc_thm'' (Celem.assoc_thy thy) xstr)
wneuper@59571
   498
    | "Rulesets" => Tactic.Rewrite_Set xstr
wneuper@59263
   499
    | _ => error ("guh2rewtac: not impl. for '"^xstr^"'") 
wneuper@59263
   500
    end
wneuper@59263
   501
  | guh2rewtac guh subs =
wneuper@59263
   502
    let
wneuper@59263
   503
      val (_, thy, sect, xstr) = case guh2theID guh of
wneuper@59263
   504
        [isa, thy, sect, xstr] => (isa, thy, sect, xstr)
wneuper@59263
   505
      | _ => error "guh2rewtac: uncovered case"
wneuper@59263
   506
    in case sect of
wneuper@59263
   507
      "Theorems" => 
walther@59872
   508
        Tactic.Rewrite_Inst (subs, (xstr, ThmC.assoc_thm'' (Celem.assoc_thy thy) xstr))
wneuper@59571
   509
    | "Rulesets" => Tactic.Rewrite_Set_Inst (subs,  xstr)
wneuper@59263
   510
    | str => error ("guh2rewtac: not impl. for '" ^ str ^ "'") 
wneuper@59263
   511
    end
neuper@37906
   512
wneuper@59263
   513
(* the front-end may request a context for any element of the hierarchy *)
wneuper@59405
   514
fun no_thycontext guh = (guh2theID guh; false)
wneuper@59263
   515
  handle ERROR _ => true;
neuper@37906
   516
wneuper@59263
   517
(* get the substitution of bound variables for matchTheory:
neuper@37906
   518
   # lookup the thm|rls' in the script
neuper@37906
   519
   # take the [(bdv, v_),..] from the respective Rewrite_(Set_)Inst
neuper@37906
   520
   # instantiate this subs with the istates env to [(bdv, x),..]
wneuper@59263
   521
   # otherwise []
wneuper@59263
   522
   WN060617 hack assuming that all scripts use only one bound variable
wneuper@59263
   523
   and use 'v_' as the formal argument for this bound variable*)
walther@59685
   524
fun subs_from (Istate.Pstate (pst as {env, ...})) _ guh =
wneuper@59263
   525
    let
wneuper@59263
   526
      val (_, _, thyID, sect, xstr) = case guh2theID guh of
wneuper@59263
   527
        theID as [isa, thyID, sect, xstr] => (theID, isa, thyID, sect, xstr)
wneuper@59263
   528
      | _ => error "subs_from: uncovered case"
wneuper@59263
   529
    in
wneuper@59263
   530
      case sect of
wneuper@59263
   531
        "Theorems" => 
walther@59854
   532
          let val thm = Global_Theory.get_thm (Celem.assoc_thy (ThyC.thyID2theory' thyID)) xstr
wneuper@59263
   533
          in
walther@59618
   534
            if Auto_Prog.contains_bdv thm
wneuper@59263
   535
            then
wneuper@59263
   536
              let
walther@59676
   537
                val formal_arg = TermC.str2term "v_"      
walther@59685
   538
                val value = subst_atomic env formal_arg
walther@59868
   539
              in ["(''bdv''," ^ UnparseC.term value ^ ")"] : Selem.subs end
wneuper@59263
   540
            else []
wneuper@59263
   541
	        end
wneuper@59263
   542
  	  | "Rulesets" => 
wneuper@59263
   543
        let
walther@59850
   544
          val rules = (Rule_Set.get_rules o assoc_rls) xstr
wneuper@59263
   545
        in
walther@59618
   546
          if Auto_Prog.contain_bdv rules
wneuper@59263
   547
          then
wneuper@59263
   548
            let
wneuper@59389
   549
              val formal_arg = TermC.str2term "v_"
walther@59685
   550
              val value = subst_atomic env formal_arg
walther@59868
   551
            in ["(''bdv''," ^ UnparseC.term value ^ ")"] : Selem.subs end
wneuper@59263
   552
          else []
wneuper@59263
   553
        end
wneuper@59263
   554
      | str => error ("subs_from: uncovered case with " ^ str)
wneuper@59263
   555
    end
wneuper@59405
   556
  | subs_from _ _  guh = error ("subs_from: uncovered case with " ^ guh)
neuper@37906
   557
neuper@42433
   558
(* get a substitution for "bdv*" from the current program and environment.
wneuper@59494
   559
    returns a substitution: sube for tac, subst for tac_, i.e. for rewriting *)
neuper@42433
   560
fun get_bdv_subst prog env =
neuper@42433
   561
  let
neuper@42433
   562
    fun scan (Const _) = NONE
neuper@42433
   563
      | scan (Free _) = NONE
neuper@42433
   564
      | scan (Var _) = NONE
neuper@42433
   565
      | scan (Bound _) = NONE
wneuper@59494
   566
      | scan (t as Const ("List.list.Cons", _) $ (Const ("Product_Type.Pair", _) $ _ $ _) $ _) =
wneuper@59389
   567
        if TermC.is_bdv_subst t then SOME t else NONE
neuper@42433
   568
      | scan (Abs (_, _, body)) = scan body
wneuper@59263
   569
      | scan (t1 $ t2) = case scan t1 of NONE => scan t2 | SOME subst => SOME subst
neuper@42433
   570
  in
neuper@42433
   571
    case scan prog of
walther@59863
   572
      NONE => (NONE: Selem.subs option, []: UnparseC.subst)
neuper@42433
   573
    | SOME tm =>
wneuper@59494
   574
        let val subst = subst_atomic env tm
wneuper@59494
   575
        in (SOME (Selem.subst'_to_sube subst), Selem.subst'_to_subst subst) end
wneuper@59263
   576
  end
neuper@42433
   577
wneuper@59263
   578
end