Theory TRS.Term_Rewriting

(*
Author:  Christian Sternagel <c.sternagel@gmail.com>
Author:  René Thiemann <rene.thiemann@uibk.ac.at>
License: LGPL (see file COPYING.LESSER)
*)
chapter ‹Term Rewriting›

theory Term_Rewriting
  imports
    First_Order_Terms.Subterm_and_Context
    Relation_Closure
begin


text ‹
  A rewrite rule is a pair of terms. A term rewrite system (TRS) is a set of rewrite rules.
›
type_synonym ('f, 'v) rule = "('f, 'v) term × ('f, 'v) term"
type_synonym ('f, 'v) trs  = "('f, 'v) rule set"

inductive_set rstep :: "_  ('f, 'v) term rel" for R :: "('f, 'v) trs"
  where
    rstep: "C σ l r. (l, r)  R  s = Cl  σ  t = Cr  σ  (s, t)  rstep R"

lemma rstep_induct_rule [case_names IH, induct set: rstep]:
  assumes "(s, t)  rstep R"
    and "C σ l r. (l, r)  R  P (Cl  σ) (Cr  σ)"
  shows "P s t"
  using assms by (induct) simp

text ‹
  An alternative induction scheme that treats the rule-case, the
  substition-case, and the context-case separately.
›
lemma rstep_induct [consumes 1, case_names rule subst ctxt]:
  assumes "(s, t)  rstep R"
    and rule: "l r. (l, r)  R  P l r"
    and subst: "s t σ. P s t  P (s  σ) (t  σ)"
    and ctxt: "s t C. P s t  P (Cs) (Ct)"
  shows "P s t"
  using assms by (induct) auto


lemmas rstepI = rstep.intros [intro]

lemmas rstepE = rstep.cases [elim]

lemma rstep_ctxt [intro]: "(s, t)  rstep R  (Cs, Ct)  rstep R"
  by (force simp flip: ctxt_ctxt_compose)

lemma rstep_rule [intro]: "(l, r)  R  (l, r)  rstep R"
  using rstep.rstep [where C =  and σ = Var and R = R] by simp

lemma rstep_subst [intro]: "(s, t)  rstep R  (s  σ, t  σ)  rstep R"
  by (force simp flip: subst_subst_compose)

lemma rstep_empty [simp]: "rstep {} = {}"
  by auto

lemma rstep_mono: "R  S  rstep R  rstep S"
  by force

lemma rstep_union: "rstep (R  S) = rstep R  rstep S"
  by auto

lemma rstep_converse [simp]: "rstep (R¯) = (rstep R)¯"
  by auto

interpretation subst: rel_closure "λσ t. t  σ" Var "λx y. y s x" by (standard) auto
declare subst.closure.induct [consumes 1, case_names subst, induct pred: subst.closure]
declare subst.closure.cases [consumes 1, case_names subst, cases pred: subst.closure]

interpretation ctxt: rel_closure "ctxt_apply_term"  "(∘c)" by (standard) auto
declare ctxt.closure.induct [consumes 1, case_names ctxt, induct pred: ctxt.closure]
declare ctxt.closure.cases [consumes 1, case_names ctxt, cases pred: ctxt.closure]

lemma rstep_eq_closure: "rstep R = ctxt.closure (subst.closure R)"
  by (force elim: ctxt.closure.cases subst.closure.cases)

lemma ctxt_closed_rstep [intro]: "ctxt.closed (rstep R)"
  by (simp add: rstep_eq_closure ctxt.closed_closure)

lemma ctxt_closed_one:
  "ctxt.closed r  (s, t)  r  (Fun f (ss @ s # ts), Fun f (ss @ t # ts))  r"
  using ctxt.closedD [of r s t "More f ss  ts"] by auto

lemma args_steps_imp_steps:
  assumes "ctxt.closed r"
    and len: "length ts = length us"
    and "i < length us. (ts ! i, us ! i)  r*"
  shows "(Fun f ts, Fun f us)  r*"
proof -
  have "(Fun f ts, Fun f (take i us @ drop i ts))  r*" if "i  length us" for i
    using that
  proof (induct i)
    case (Suc i)
    then have "(Fun f ts, Fun f (take i us @ drop i ts))  r*" by simp
    moreover have "take i us @ drop i ts = take i us @ ts ! length (take i us) # drop (Suc i) ts"
      using Suc and len by (auto simp: Cons_nth_drop_Suc min_def)
    moreover have "take (Suc i) us @ drop (Suc i) ts = take i us @ us ! length (take i us) # drop (Suc i) ts"
      using Suc and len by (auto simp: min_def take_Suc_conv_app_nth)
    moreover have "(Fun f (take i us @ ts ! length (take i us) # drop (Suc i) ts),
    Fun f (take i us @ us ! length (take i us) # drop (Suc i) ts))  r*"
      using assms and Suc by (intro ctxt_closed_one) auto
    ultimately show ?case by simp
  qed simp
  note this [of "length us"] and len
  then show ?thesis by simp
qed

end