src/Tools/isac/Interpret/rewtools.sml
author Walther Neuper <wneuper@ist.tugraz.at>
Wed, 21 Dec 2016 08:57:47 +0100
changeset 59272 1d3ef477d9c8
parent 59266 56762e8a672e
child 59276 56dc790071cb
permissions -rw-r--r--
added structure Applicable INTERMEDIATELY

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